From 4841858862df4b8ac4ac68922086f03c8bbd3dc2 Mon Sep 17 00:00:00 2001 From: Alexander Yermolovich <43973793+ayermolo@users.noreply.github.com> Date: Mon, 18 Mar 2024 15:28:01 -0700 Subject: [PATCH 001/307] [BOLT][DWARF] Add support to debug_names for DW_AT_abstract_origin/DW_AT_specification (#85485) According to the DWARF spec a DIE that has DW_AT_specification or DW_AT_abstract_origin can be part of .debug_name if a DIE those attribute points to has DW_AT_name or DW_AT_linkage_name. --- bolt/lib/Core/DebugNames.cpp | 49 +- .../dwarf5-debug-names-dw-at-specification.s | 694 ++++++++++++++++++ ...arf5-debug-names-generate-debug-names.test | 273 ++++--- bolt/test/X86/dwarf5-debug-names.test | 9 +- bolt/test/X86/dwarf5-one-cu-debug-names.test | 8 +- 5 files changed, 897 insertions(+), 136 deletions(-) create mode 100644 bolt/test/X86/dwarf5-debug-names-dw-at-specification.s diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp index 4bcedbea8d22..23a29f52513c 100644 --- a/bolt/lib/Core/DebugNames.cpp +++ b/bolt/lib/Core/DebugNames.cpp @@ -234,8 +234,7 @@ DWARF5AcceleratorTable::addAccelTableEntry( addUnit(Unit, DWOID); } - auto addEntry = - [&](DIEValue ValName) -> std::optional { + auto getName = [&](DIEValue ValName) -> std::optional { if ((!ValName || ValName.getForm() == dwarf::DW_FORM_string) && NameToUse.empty()) return std::nullopt; @@ -268,7 +267,16 @@ DWARF5AcceleratorTable::addAccelTableEntry( // This the same hash function used in DWARF5AccelTableData. It.HashValue = caseFoldingDjbHash(Name); } + return Name; + }; + auto addEntry = + [&](DIEValue ValName) -> std::optional { + std::optional Name = getName(ValName); + if (!Name) + return std::nullopt; + + auto &It = Entries[*Name]; bool IsTU = false; uint32_t DieTag = 0; uint32_t UnitID = getUnitID(Unit, IsTU, DieTag); @@ -278,7 +286,7 @@ DWARF5AcceleratorTable::addAccelTableEntry( if (Iter == CUOffsetsToPatch.end()) BC.errs() << "BOLT-WARNING: [internal-dwarf-warning]: Could not find " "DWO ID in CU offsets for second Unit Index " - << Name << ". For DIE at offset: " + << *Name << ". For DIE at offset: " << Twine::utohexstr(CurrentUnitOffset + Die.getOffset()) << ".\n"; SecondIndex = Iter->second; @@ -295,11 +303,36 @@ DWARF5AcceleratorTable::addAccelTableEntry( return It.Values.back(); }; - std::optional NameEntry = - addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name)); - std::optional LinkageNameEntry = - addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name)); - return NameEntry ? NameEntry : LinkageNameEntry; + // Minor optimization not to add entry twice for DW_TAG_namespace if it has no + // DW_AT_name. + if (!(Die.getTag() == dwarf::DW_TAG_namespace && + !Die.findAttribute(dwarf::Attribute::DW_AT_name))) + addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name)); + // For the purposes of determining whether a debugging information entry has a + // particular attribute (such as DW_AT_name), if debugging information entry A + // has a DW_AT_specification or DW_AT_abstract_origin attribute pointing to + // another debugging information entry B, any attributes of B are considered + // to be part of A. + auto processReferencedDie = [&](const dwarf::Attribute &Attr) + -> std::optional { + const DIEValue Value = Die.findAttribute(Attr); + if (!Value) + return std::nullopt; + const DIEEntry &DIEENtry = Value.getDIEEntry(); + DIE &EntryDie = DIEENtry.getEntry(); + addEntry(EntryDie.findAttribute(dwarf::Attribute::DW_AT_linkage_name)); + return addEntry(EntryDie.findAttribute(dwarf::Attribute::DW_AT_name)); + }; + + if (std::optional Entry = + processReferencedDie(dwarf::Attribute::DW_AT_abstract_origin)) + return *Entry; + if (std::optional Entry = + processReferencedDie(dwarf::Attribute::DW_AT_specification)) + return *Entry; + + return addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name)); + ; } /// Algorithm from llvm implementation. diff --git a/bolt/test/X86/dwarf5-debug-names-dw-at-specification.s b/bolt/test/X86/dwarf5-debug-names-dw-at-specification.s new file mode 100644 index 000000000000..ec5b425625ce --- /dev/null +++ b/bolt/test/X86/dwarf5-debug-names-dw-at-specification.s @@ -0,0 +1,694 @@ +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %tmain.o +# RUN: %clang %cflags -gdwarf-5 %tmain.o -o %tmain.exe +# RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections +# RUN: llvm-dwarfdump --debug-info -r 0 --debug-names %tmain.exe.bolt > %tlog.txt +# RUN: cat %tlog.txt | FileCheck -check-prefix=BOLT %s + +## Tests that BOLT correctly generates entries in .debug_names with DW_AT_specification. + +# BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit +# BOLT: Name Index @ 0x0 +# BOLT-NEXT: Header { +# BOLT-NEXT: Length: 0x10F +# BOLT-NEXT: Format: DWARF32 +# BOLT-NEXT: Version: 5 +# BOLT-NEXT: CU count: 1 +# BOLT-NEXT: Local TU count: 0 +# BOLT-NEXT: Foreign TU count: 0 +# BOLT-NEXT: Bucket count: 9 +# BOLT-NEXT: Name count: 9 +# BOLT-NEXT: Abbreviations table size: 0x21 +# BOLT-NEXT: Augmentation: 'BOLT' +# BOLT-NEXT: } +# BOLT-NEXT: Compilation Unit offsets [ +# BOLT-NEXT: CU[0]: [[OFFSET1]] +# BOLT-NEXT: ] +# BOLT-NEXT: Abbreviations [ +# BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_variable +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_structure_type +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 0 [ +# BOLT-NEXT: Name 1 { +# BOLT-NEXT: Hash: 0x5D3CA9E0 +# BOLT-NEXT: String: {{.+}} "_ZN1A15fully_specifiedE" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_variable +# BOLT-NEXT: DW_IDX_die_offset: 0x00000024 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 2 { +# BOLT-NEXT: Hash: 0x7C9DFC37 +# BOLT-NEXT: String: {{.+}} "smem" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_variable +# BOLT-NEXT: DW_IDX_die_offset: 0x00000057 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 1 [ +# BOLT-NEXT: Name 3 { +# BOLT-NEXT: Hash: 0x2B606 +# BOLT-NEXT: String: {{.+}} "A" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV2]] +# BOLT-NEXT: Tag: DW_TAG_structure_type +# BOLT-NEXT: DW_IDX_die_offset: 0x0000002d +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 2 [ +# BOLT-NEXT: Name 4 { +# BOLT-NEXT: Hash: 0xB888030 +# BOLT-NEXT: String: {{.+}} "int" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV3]] +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: 0x00000044 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 3 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 4 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 5 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 6 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 7 [ +# BOLT-NEXT: Name 5 { +# BOLT-NEXT: Hash: 0x65788E1C +# BOLT-NEXT: String: {{.+}} "fully_specified" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_variable +# BOLT-NEXT: DW_IDX_die_offset: 0x00000024 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 6 { +# BOLT-NEXT: Hash: 0x7C9A7F6A +# BOLT-NEXT: String: {{.+}} "main" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV4]] +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: 0x00000070 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 8 [ +# BOLT-NEXT: Name 7 { +# BOLT-NEXT: Hash: 0xCEF4CFB +# BOLT-NEXT: String: {{.+}} "__ARRAY_SIZE_TYPE__" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV3]] +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: 0x00000053 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 8 { +# BOLT-NEXT: Hash: 0x48684B69 +# BOLT-NEXT: String: {{.+}} "_ZN1A4smemE" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_variable +# BOLT-NEXT: DW_IDX_die_offset: 0x00000057 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 9 { +# BOLT-NEXT: Hash: 0x7C952063 +# BOLT-NEXT: String: {{.+}} "char" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV3]] +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: 0x0000009e +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: } + +# clang++ main.cpp -O2 -g2 -gdwarf-5 -gpubnames -S +# struct A { +# static int fully_specified; +# static int smem[]; +# }; +# +# int A::fully_specified; +# int A::smem[] = { 0, 1, 2, 3 }; +# int main(int argc, char *argv[]) { +# return 0; +# } + .text + .file "main.cpp" + .file 0 "/specification" "main.cpp" md5 0x6c1b1c014d300f2e0efd26584acae1a9 + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .cfi_startproc +# %bb.0: # %entry + #DEBUG_VALUE: main:argc <- $edi + #DEBUG_VALUE: main:argv <- $rsi + .loc 0 9 3 prologue_end # main.cpp:9:3 + xorl %eax, %eax + retq +.Ltmp0: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .type _ZN1A15fully_specifiedE,@object # @_ZN1A15fully_specifiedE + .bss + .globl _ZN1A15fully_specifiedE + .p2align 2, 0x0 +_ZN1A15fully_specifiedE: + .long 0 # 0x0 + .size _ZN1A15fully_specifiedE, 4 + + .type _ZN1A4smemE,@object # @_ZN1A4smemE + .data + .globl _ZN1A4smemE + .p2align 4, 0x0 +_ZN1A4smemE: + .long 0 # 0x0 + .long 1 # 0x1 + .long 2 # 0x2 + .long 3 # 0x3 + .size _ZN1A4smemE, 16 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 71 # DW_AT_specification + .byte 19 # DW_FORM_ref4 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 1 # DW_CHILDREN_yes + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 1 # DW_TAG_array_type + .byte 1 # DW_CHILDREN_yes + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 33 # DW_TAG_subrange_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 9 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 71 # DW_AT_specification + .byte 19 # DW_FORM_ref4 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 33 # DW_TAG_subrange_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 55 # DW_AT_count + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 11 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 122 # DW_AT_call_all_calls + .byte 25 # DW_FORM_flag_present + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 12 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 13 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x96 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 2 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x9 DW_TAG_variable + .long 50 # DW_AT_specification + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 8 # DW_AT_linkage_name + .byte 3 # Abbrev [3] 0x2c:0x17 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 7 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 4 # Abbrev [4] 0x32:0x8 DW_TAG_variable + .byte 3 # DW_AT_name + .long 67 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + # DW_AT_external + # DW_AT_declaration + .byte 4 # Abbrev [4] 0x3a:0x8 DW_TAG_variable + .byte 5 # DW_AT_name + .long 71 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + # DW_AT_external + # DW_AT_declaration + .byte 0 # End Of Children Mark + .byte 5 # Abbrev [5] 0x43:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 6 # Abbrev [6] 0x47:0xb DW_TAG_array_type + .long 67 # DW_AT_type + .byte 7 # Abbrev [7] 0x4c:0x5 DW_TAG_subrange_type + .long 82 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 8 # Abbrev [8] 0x52:0x4 DW_TAG_base_type + .byte 6 # DW_AT_name + .byte 8 # DW_AT_byte_size + .byte 7 # DW_AT_encoding + .byte 9 # Abbrev [9] 0x56:0xd DW_TAG_variable + .long 58 # DW_AT_specification + .long 99 # DW_AT_type + .byte 2 # DW_AT_location + .byte 161 + .byte 1 + .byte 9 # DW_AT_linkage_name + .byte 6 # Abbrev [6] 0x63:0xc DW_TAG_array_type + .long 67 # DW_AT_type + .byte 10 # Abbrev [10] 0x68:0x6 DW_TAG_subrange_type + .long 82 # DW_AT_type + .byte 4 # DW_AT_count + .byte 0 # End Of Children Mark + .byte 11 # Abbrev [11] 0x6f:0x24 DW_TAG_subprogram + .byte 2 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 87 + # DW_AT_call_all_calls + .byte 10 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .long 67 # DW_AT_type + # DW_AT_external + .byte 12 # Abbrev [12] 0x7e:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 85 + .byte 11 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .long 67 # DW_AT_type + .byte 12 # Abbrev [12] 0x88:0xa DW_TAG_formal_parameter + .byte 1 # DW_AT_location + .byte 84 + .byte 12 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .long 147 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 13 # Abbrev [13] 0x93:0x5 DW_TAG_pointer_type + .long 152 # DW_AT_type + .byte 13 # Abbrev [13] 0x98:0x5 DW_TAG_pointer_type + .long 157 # DW_AT_type + .byte 5 # Abbrev [5] 0x9d:0x4 DW_TAG_base_type + .byte 13 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 60 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git ced1fac8a32e35b63733bda27c7f5b9a2b635403)" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=104 +.Linfo_string2: + .asciz "/specification" # string offset=113 +.Linfo_string3: + .asciz "A" # string offset=165 +.Linfo_string4: + .asciz "fully_specified" # string offset=167 +.Linfo_string5: + .asciz "int" # string offset=183 +.Linfo_string6: + .asciz "smem" # string offset=187 +.Linfo_string7: + .asciz "__ARRAY_SIZE_TYPE__" # string offset=192 +.Linfo_string8: + .asciz "_ZN1A15fully_specifiedE" # string offset=212 +.Linfo_string9: + .asciz "_ZN1A4smemE" # string offset=236 +.Linfo_string10: + .asciz "main" # string offset=248 +.Linfo_string11: + .asciz "argc" # string offset=253 +.Linfo_string12: + .asciz "argv" # string offset=258 +.Linfo_string13: + .asciz "char" # string offset=263 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string3 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .long .Linfo_string11 + .long .Linfo_string12 + .long .Linfo_string13 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad _ZN1A15fully_specifiedE + .quad _ZN1A4smemE + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 9 # Header: bucket count + .long 9 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 1 # Bucket 0 + .long 3 # Bucket 1 + .long 4 # Bucket 2 + .long 0 # Bucket 3 + .long 0 # Bucket 4 + .long 0 # Bucket 5 + .long 0 # Bucket 6 + .long 5 # Bucket 7 + .long 7 # Bucket 8 + .long 1564256736 # Hash in Bucket 0 + .long 2090728503 # Hash in Bucket 0 + .long 177670 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long 1702399516 # Hash in Bucket 7 + .long 2090499946 # Hash in Bucket 7 + .long 217009403 # Hash in Bucket 8 + .long 1214794601 # Hash in Bucket 8 + .long 2090147939 # Hash in Bucket 8 + .long .Linfo_string8 # String in Bucket 0: _ZN1A15fully_specifiedE + .long .Linfo_string6 # String in Bucket 0: smem + .long .Linfo_string3 # String in Bucket 1: A + .long .Linfo_string5 # String in Bucket 2: int + .long .Linfo_string4 # String in Bucket 7: fully_specified + .long .Linfo_string10 # String in Bucket 7: main + .long .Linfo_string7 # String in Bucket 8: __ARRAY_SIZE_TYPE__ + .long .Linfo_string9 # String in Bucket 8: _ZN1A4smemE + .long .Linfo_string13 # String in Bucket 8: char + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 7 + .long .Lnames7-.Lnames_entries0 # Offset in Bucket 7 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 8 + .long .Lnames6-.Lnames_entries0 # Offset in Bucket 8 + .long .Lnames8-.Lnames_entries0 # Offset in Bucket 8 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 52 # DW_TAG_variable + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames4: +.L3: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _ZN1A15fully_specifiedE +.Lnames5: +.L4: + .byte 1 # Abbreviation code + .long 86 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: smem +.Lnames0: +.L6: + .byte 2 # Abbreviation code + .long 44 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: A +.Lnames1: +.L5: + .byte 3 # Abbreviation code + .long 67 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames3: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: fully_specified +.Lnames7: +.L0: + .byte 4 # Abbreviation code + .long 111 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames2: +.L2: + .byte 3 # Abbreviation code + .long 82 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: __ARRAY_SIZE_TYPE__ +.Lnames6: + .byte 1 # Abbreviation code + .long 86 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _ZN1A4smemE +.Lnames8: +.L1: + .byte 3 # Abbreviation code + .long 157 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git ced1fac8a32e35b63733bda27c7f5b9a2b635403)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/dwarf5-debug-names-generate-debug-names.test b/bolt/test/X86/dwarf5-debug-names-generate-debug-names.test index ae921d1e8b93..b7d8fda63315 100644 --- a/bolt/test/X86/dwarf5-debug-names-generate-debug-names.test +++ b/bolt/test/X86/dwarf5-debug-names-generate-debug-names.test @@ -14,15 +14,15 @@ ; BOLT: [[OFFSET2:0x[0-9a-f]*]]: Compile Unit ; BOLT: Name Index @ 0x0 { ; BOLT-NEXT: Header { -; BOLT-NEXT: Length: 0x109 +; BOLT-NEXT: Length: 0x155 ; BOLT-NEXT: Format: DWARF32 ; BOLT-NEXT: Version: 5 ; BOLT-NEXT: CU count: 2 ; BOLT-NEXT: Local TU count: 0 ; BOLT-NEXT: Foreign TU count: 0 -; BOLT-NEXT: Bucket count: 8 -; BOLT-NEXT: Name count: 8 -; BOLT-NEXT: Abbreviations table size: 0x1F +; BOLT-NEXT: Bucket count: 10 +; BOLT-NEXT: Name count: 10 +; BOLT-NEXT: Abbreviations table size: 0x29 ; BOLT-NEXT: Augmentation: 'BOLT' ; BOLT-NEXT: } ; BOLT-NEXT: Compilation Unit offsets [ @@ -31,136 +31,183 @@ ; BOLT-NEXT: ] ; BOLT-NEXT: Abbreviations [ ; BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { -; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: Tag: DW_TAG_subprogram ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { -; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: Tag: DW_TAG_inlined_subroutine +; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 +; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +; BOLT-NEXT: DW_IDX_parent: DW_FORM_ref4 +; BOLT-NEXT: } +; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { +; BOLT-NEXT: Tag: DW_TAG_variable ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } -; BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { -; BOLT-NEXT: Tag: DW_TAG_variable +; BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { +; BOLT-NEXT: Tag: DW_TAG_base_type ; BOLT-NEXT: DW_IDX_compile_unit: DW_FORM_data1 ; BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 ; BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present ; BOLT-NEXT: } ; BOLT-NEXT: ] ; BOLT-NEXT: Bucket 0 [ -; BOLT-NEXT: Name 1 { -; BOLT-NEXT: Hash: 0xB888030 -; BOLT-NEXT: String: {{.+}} "int" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV1]] -; BOLT-NEXT: Tag: DW_TAG_base_type -; BOLT-NEXT: DW_IDX_compile_unit: 0x01 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000033 -; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: Name 1 { +; BOLT-NEXT: Hash: 0x2124BB36 +; BOLT-NEXT: String: {{.+}} "useFoo" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000037 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV2]] +; BOLT-NEXT: Tag: DW_TAG_inlined_subroutine +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000081 +; BOLT-NEXT: DW_IDX_parent: Entry @ 0x14b +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV1]] -; BOLT-NEXT: Tag: DW_TAG_base_type -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x0000007f -; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 1 [ +; BOLT-NEXT: EMPTY +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 2 [ +; BOLT-NEXT: Name 2 { +; BOLT-NEXT: Hash: 0xFDE4B5D2 +; BOLT-NEXT: String: {{.+}} "fooVar" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV3]] +; BOLT-NEXT: Tag: DW_TAG_variable +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 1 [ -; BOLT-NEXT: Name 2 { -; BOLT-NEXT: Hash: 0xB887389 -; BOLT-NEXT: String: {{.+}} "foo" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_subprogram -; BOLT-NEXT: DW_IDX_compile_unit: 0x01 -; BOLT-NEXT: DW_IDX_die_offset: 0x0000005e -; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 3 [ +; BOLT-NEXT: EMPTY +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 4 [ +; BOLT-NEXT: EMPTY +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 5 [ +; BOLT-NEXT: EMPTY +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 6 [ +; BOLT-NEXT: Name 3 { +; BOLT-NEXT: Hash: 0xB88B3D2 +; BOLT-NEXT: String: {{.+}} "use" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: Name 3 { -; BOLT-NEXT: Hash: 0x8C06E589 -; BOLT-NEXT: String: {{.+}} "_Z3usePiS_" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_subprogram -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 -; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: Name 4 { +; BOLT-NEXT: Hash: 0x69A7307E +; BOLT-NEXT: String: {{.+}} "_Z6useFooPi" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000037 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV2]] +; BOLT-NEXT: Tag: DW_TAG_inlined_subroutine +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000081 +; BOLT-NEXT: DW_IDX_parent: Entry @ 0x14b +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 2 [ -; BOLT-NEXT: Name 4 { -; BOLT-NEXT: Hash: 0xB88B3D2 -; BOLT-NEXT: String: {{.+}} "use" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_subprogram -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 -; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: Name 5 { +; BOLT-NEXT: Hash: 0x7C9A7F6A +; BOLT-NEXT: String: {{.+}} "main" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000049 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: Name 5 { -; BOLT-NEXT: Hash: 0x7C9A7F6A -; BOLT-NEXT: String: {{.+}} "main" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_subprogram -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000049 -; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: Name 6 { +; BOLT-NEXT: Hash: 0xB5063CFE +; BOLT-NEXT: String: {{.+}} "_Z3fooi" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x0000005e +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: Name 6 { -; BOLT-NEXT: Hash: 0xFDE4B5D2 -; BOLT-NEXT: String: {{.+}} "fooVar" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV3]] -; BOLT-NEXT: Tag: DW_TAG_variable -; BOLT-NEXT: DW_IDX_compile_unit: 0x01 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 -; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 7 [ +; BOLT-NEXT: Name 7 { +; BOLT-NEXT: Hash: 0x8C06E589 +; BOLT-NEXT: String: {{.+}} "_Z3usePiS_" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000028 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 3 [ -; BOLT-NEXT: Name 7 { -; BOLT-NEXT: Hash: 0x7C952063 -; BOLT-NEXT: String: {{.+}} "char" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV1]] -; BOLT-NEXT: Tag: DW_TAG_base_type -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000092 -; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 8 [ +; BOLT-NEXT: Name 8 { +; BOLT-NEXT: Hash: 0xB888030 +; BOLT-NEXT: String: {{.+}} "int" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV4]] +; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000033 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: Entry @ 0x{{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV4]] +; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x0000007f +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 4 [ -; BOLT-NEXT: EMPTY -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 5 [ -; BOLT-NEXT: EMPTY -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 6 [ -; BOLT-NEXT: Name 8 { -; BOLT-NEXT: Hash: 0xB5063CFE -; BOLT-NEXT: String: {{.+}} "_Z3fooi" -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_subprogram -; BOLT-NEXT: DW_IDX_compile_unit: 0x01 -; BOLT-NEXT: DW_IDX_die_offset: 0x0000005e -; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: ] +; BOLT-NEXT: Bucket 9 [ +; BOLT-NEXT: Name 9 { +; BOLT-NEXT: Hash: 0xB887389 +; BOLT-NEXT: String: {{.+}} "foo" +; BOLT-NEXT: Entry @ 0x14b { +; BOLT-NEXT: Abbrev: [[ABBREV1]] +; BOLT-NEXT: Tag: DW_TAG_subprogram +; BOLT-NEXT: DW_IDX_compile_unit: 0x01 +; BOLT-NEXT: DW_IDX_die_offset: 0x0000005e +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } ; BOLT-NEXT: } -; BOLT-NEXT: } -; BOLT-NEXT: ] -; BOLT-NEXT: Bucket 7 [ -; BOLT-NEXT: EMPTY -; BOLT-NEXT: ] -; BOLT-NEXT: } +; BOLT-NEXT: Name 10 { +; BOLT-NEXT: Hash: 0x7C952063 +; BOLT-NEXT: String: {{.+}} "char" +; BOLT-NEXT: Entry @ {{.+}} { +; BOLT-NEXT: Abbrev: [[ABBREV4]] +; BOLT-NEXT: Tag: DW_TAG_base_type +; BOLT-NEXT: DW_IDX_compile_unit: 0x00 +; BOLT-NEXT: DW_IDX_die_offset: 0x00000092 +; BOLT-NEXT: DW_IDX_parent: +; BOLT-NEXT: } +; BOLT-NEXT: } +; BOLT-NEXT: ] +; BOLT-NEXT: } diff --git a/bolt/test/X86/dwarf5-debug-names.test b/bolt/test/X86/dwarf5-debug-names.test index 8e45ef3a9481..ef11ee0c479b 100644 --- a/bolt/test/X86/dwarf5-debug-names.test +++ b/bolt/test/X86/dwarf5-debug-names.test @@ -11,7 +11,7 @@ ; BOLT: [[OFFSET2:0x[0-9a-f]*]]: Compile Unit ; BOLT: Name Index @ 0x0 { ; BOLT-NEXT: Header { -; BOLT-NEXT: Length: 0x1DA +; BOLT-NEXT: Length: 0x1D4 ; BOLT-NEXT: Format: DWARF32 ; BOLT-NEXT: Version: 5 ; BOLT-NEXT: CU count: 2 @@ -101,13 +101,6 @@ ; BOLT-NEXT: DW_IDX_die_offset: 0x00000061 ; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV2]] -; BOLT-NEXT: Tag: DW_TAG_namespace -; BOLT-NEXT: DW_IDX_compile_unit: 0x00 -; BOLT-NEXT: DW_IDX_die_offset: 0x00000061 -; BOLT-NEXT: DW_IDX_parent: -; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: Name 4 { ; BOLT-NEXT: Hash: 0xBA564846 diff --git a/bolt/test/X86/dwarf5-one-cu-debug-names.test b/bolt/test/X86/dwarf5-one-cu-debug-names.test index 2145d8160a42..74d6b3041c93 100644 --- a/bolt/test/X86/dwarf5-one-cu-debug-names.test +++ b/bolt/test/X86/dwarf5-one-cu-debug-names.test @@ -9,7 +9,7 @@ ; BOLT: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit ; BOLT: Name Index @ 0x0 { ; BOLT-NEXT: Header { -; BOLT-NEXT: Length: 0x154 +; BOLT-NEXT: Length: 0x14F ; BOLT-NEXT: Format: DWARF32 ; BOLT-NEXT: Version: 5 ; BOLT-NEXT: CU count: 1 @@ -183,12 +183,6 @@ ; BOLT-NEXT: DW_IDX_die_offset: 0x00000061 ; BOLT-NEXT: DW_IDX_parent: ; BOLT-NEXT: } -; BOLT-NEXT: Entry @ {{.+}} { -; BOLT-NEXT: Abbrev: [[ABBREV6]] -; BOLT-NEXT: Tag: DW_TAG_namespace -; BOLT-NEXT: DW_IDX_die_offset: 0x00000061 -; BOLT-NEXT: DW_IDX_parent: -; BOLT-NEXT: } ; BOLT-NEXT: } ; BOLT-NEXT: ] ; BOLT-NEXT: Bucket 9 [ -- GitLab From 7ef1a59ed1ca176cf3c38672fe1d3f49c1758e49 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Mon, 18 Mar 2024 15:20:48 -0700 Subject: [PATCH 002/307] remove incorrect DCHECK this DCHECK was not valid for hwasan_load1, and was not necessary for the. the function is written without any assumptions of alignment of the pointer. --- compiler-rt/lib/hwasan/hwasan_checks.h | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler-rt/lib/hwasan/hwasan_checks.h b/compiler-rt/lib/hwasan/hwasan_checks.h index 0911af30dcb8..735d21a5db77 100644 --- a/compiler-rt/lib/hwasan/hwasan_checks.h +++ b/compiler-rt/lib/hwasan/hwasan_checks.h @@ -140,7 +140,6 @@ __attribute__((always_inline, nodebug)) static inline uptr ShortTagSize( __attribute__((always_inline, nodebug)) static inline bool PossiblyShortTagMatches(tag_t mem_tag, uptr ptr, uptr sz) { - DCHECK(IsAligned(ptr, kShadowAlignment)); tag_t ptr_tag = GetTagFromPointer(ptr); if (ptr_tag == mem_tag) return true; -- GitLab From 715a931864eff4021463d40b73ef4b1b63959f3f Mon Sep 17 00:00:00 2001 From: Shourya Goel Date: Tue, 19 Mar 2024 04:18:47 +0530 Subject: [PATCH 003/307] [libc] Added tablegen definition for fileno (#85682) This was missed in the previous PR. Updating tablegen definition with this PR. --- libc/spec/posix.td | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libc/spec/posix.td b/libc/spec/posix.td index 26f41b61dc00..3b793ea90ffd 100644 --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -1169,6 +1169,11 @@ def POSIX : StandardSpec<"POSIX"> { RetValSpec, [ArgSpec] >, + FunctionSpec< + "fileno", + RetValSpec, + [ArgSpec] + >, ] >; -- GitLab From f4e90e3f3c02a94a17bd8fe6ad18dbb46f92d027 Mon Sep 17 00:00:00 2001 From: Slava Zakharin Date: Mon, 18 Mar 2024 16:29:58 -0700 Subject: [PATCH 004/307] [flang][runtime] Get rid of warnings in F18 runtime CUDA build. (#85488) --- flang/runtime/freestanding-tools.h | 23 +++++++++++++++++++++++ flang/runtime/numeric-templates.h | 7 +++++++ flang/runtime/tools.cpp | 2 +- flang/runtime/tools.h | 2 +- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/flang/runtime/freestanding-tools.h b/flang/runtime/freestanding-tools.h index bdc11ae93ac9..682b4c9b8929 100644 --- a/flang/runtime/freestanding-tools.h +++ b/flang/runtime/freestanding-tools.h @@ -42,6 +42,11 @@ #define STD_REALLOC_UNSUPPORTED 1 #endif +#if !defined(STD_MEMCHR_UNSUPPORTED) && \ + (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__) +#define STD_MEMCHR_UNSUPPORTED 1 +#endif + namespace Fortran::runtime { #if STD_FILL_N_UNSUPPORTED @@ -134,5 +139,23 @@ static inline RT_API_ATTRS void *realloc(void *ptr, std::size_t newByteSize) { using std::realloc; #endif // !STD_REALLOC_UNSUPPORTED +#if STD_MEMCHR_UNSUPPORTED +// Provides alternative implementation for std::memchr(), if +// it is not supported. +static inline RT_API_ATTRS const void *memchr( + const void *ptr, int ch, std::size_t count) { + auto buf{reinterpret_cast(ptr)}; + auto c{static_cast(ch)}; + for (; count--; ++buf) { + if (*buf == c) { + return buf; + } + } + return nullptr; +} +#else // !STD_MEMCMP_UNSUPPORTED +using std::memchr; +#endif // !STD_MEMCMP_UNSUPPORTED + } // namespace Fortran::runtime #endif // FORTRAN_RUNTIME_FREESTANDING_TOOLS_H_ diff --git a/flang/runtime/numeric-templates.h b/flang/runtime/numeric-templates.h index ecc3b2654d96..8ea3daaa57bc 100644 --- a/flang/runtime/numeric-templates.h +++ b/flang/runtime/numeric-templates.h @@ -122,12 +122,19 @@ template struct ABSTy { static constexpr RT_API_ATTRS T compute(T x) { return std::abs(x); } }; +// Suppress the warnings about calling __host__-only +// 'long double' std::frexp, from __device__ code. +RT_DIAG_PUSH +RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN + template struct FREXPTy { static constexpr RT_API_ATTRS T compute(T x, int *e) { return std::frexp(x, e); } }; +RT_DIAG_POP + template struct ILOGBTy { static constexpr RT_API_ATTRS int compute(T x) { return std::ilogb(x); } }; diff --git a/flang/runtime/tools.cpp b/flang/runtime/tools.cpp index e653323ed1de..71022c7a8c17 100644 --- a/flang/runtime/tools.cpp +++ b/flang/runtime/tools.cpp @@ -175,7 +175,7 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from) { RT_API_ATTRS char *EnsureNullTerminated( char *str, std::size_t length, Terminator &terminator) { - if (std::memchr(str, '\0', length) == nullptr) { + if (runtime::memchr(str, '\0', length) == nullptr) { char *newCmd{(char *)AllocateMemoryOrCrash(terminator, length + 1)}; std::memcpy(newCmd, str, length); newCmd[length] = '\0'; diff --git a/flang/runtime/tools.h b/flang/runtime/tools.h index 392e3fc6c891..df25eb888233 100644 --- a/flang/runtime/tools.h +++ b/flang/runtime/tools.h @@ -430,7 +430,7 @@ template <> inline RT_API_ATTRS const char *FindCharacter( const char *data, char ch, std::size_t chars) { return reinterpret_cast( - std::memchr(data, static_cast(ch), chars)); + runtime::memchr(data, static_cast(ch), chars)); } // Copy payload data from one allocated descriptor to another. -- GitLab From ba2dc2953cdaaad63968296e3cbb1f06c1784114 Mon Sep 17 00:00:00 2001 From: Alexander Richardson Date: Mon, 18 Mar 2024 16:48:37 -0700 Subject: [PATCH 005/307] [compiler-rt] Don't check COMPILER_RT_STANDALONE_BUILD for test deps With https://github.com/llvm/llvm-project/pull/83088, we now need the runtimes to be built before running test if COMPILER_RT_TEST_STANDALONE_BUILD_LIBS is true, since otherwise we get failures running `ninja check-all` such as the following: ``` /usr/bin/ld: cannot find .../compiler-rt/cmake-build-all-sanitizers/lib/linux/libclang_rt.fuzzer-x86_64.a: No such file or directory /usr/bin/ld: cannot find .../compiler-rt/cmake-build-all-sanitizers/lib/linux/libclang_rt.xray-x86_64.a: No such file or directory /usr/bin/ld: cannot find .../compiler-rt/cmake-build-all-sanitizers/lib/linux/libclang_rt.xray-basic-x86_64.a: No such file or directory /usr/bin/ld: cannot find .../compiler-rt/cmake-build-all-sanitizers/lib/linux/libclang_rt.xray-fdr-x86_64.a: No such file or directory ``` This is a follow-up to 058e9b03 which started removing these checks and it should make it easier to stop forcing COMPILER_RT_STANDALONE_BUILD for runtimes builds in the future. Reviewed By: vitalybuka Pull Request: https://github.com/llvm/llvm-project/pull/83651 --- .../cmake/Modules/CompilerRTCompile.cmake | 3 ++- compiler-rt/lib/msan/tests/CMakeLists.txt | 4 +--- compiler-rt/test/asan_abi/CMakeLists.txt | 5 +---- compiler-rt/test/fuzzer/CMakeLists.txt | 21 ++++++++++++------- compiler-rt/test/memprof/CMakeLists.txt | 9 +++----- compiler-rt/test/msan/CMakeLists.txt | 6 +----- compiler-rt/test/ubsan/CMakeLists.txt | 4 +--- compiler-rt/test/xray/CMakeLists.txt | 5 ++--- 8 files changed, 24 insertions(+), 33 deletions(-) diff --git a/compiler-rt/cmake/Modules/CompilerRTCompile.cmake b/compiler-rt/cmake/Modules/CompilerRTCompile.cmake index 2bf115973a49..d5b2e7970f11 100644 --- a/compiler-rt/cmake/Modules/CompilerRTCompile.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTCompile.cmake @@ -65,8 +65,9 @@ function(clang_compile object_file source) cmake_parse_arguments(SOURCE "" "" "CFLAGS;DEPS" ${ARGN}) get_filename_component(source_rpath ${source} REALPATH) if(NOT COMPILER_RT_STANDALONE_BUILD) - list(APPEND SOURCE_DEPS clang compiler-rt-headers) + list(APPEND SOURCE_DEPS clang) endif() + list(APPEND SOURCE_DEPS compiler-rt-headers) if (TARGET CompilerRTUnitTestCheckCxx) list(APPEND SOURCE_DEPS CompilerRTUnitTestCheckCxx) endif() diff --git a/compiler-rt/lib/msan/tests/CMakeLists.txt b/compiler-rt/lib/msan/tests/CMakeLists.txt index bc58c0b9fabf..4f09f1e6a691 100644 --- a/compiler-rt/lib/msan/tests/CMakeLists.txt +++ b/compiler-rt/lib/msan/tests/CMakeLists.txt @@ -120,9 +120,7 @@ macro(add_msan_tests_for_arch arch kind cflags) set(MSAN_TEST_DEPS ${MSAN_TEST_OBJECTS} libcxx_msan_${arch}-build ${MSAN_LOADABLE_SO} "${MSAN_LIBCXX_DIR}/libc++.a" "${MSAN_LIBCXX_DIR}/libc++abi.a") - if(NOT COMPILER_RT_STANDALONE_BUILD) - list(APPEND MSAN_TEST_DEPS msan) - endif() + list(APPEND MSAN_TEST_DEPS msan) get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS) add_compiler_rt_test(MsanUnitTests "Msan-${arch}${kind}-Test" ${arch} OBJECTS ${MSAN_TEST_OBJECTS} "${MSAN_LIBCXX_DIR}/libc++.a" "${MSAN_LIBCXX_DIR}/libc++abi.a" diff --git a/compiler-rt/test/asan_abi/CMakeLists.txt b/compiler-rt/test/asan_abi/CMakeLists.txt index f28cf6cd1da6..1114ed1b8279 100644 --- a/compiler-rt/test/asan_abi/CMakeLists.txt +++ b/compiler-rt/test/asan_abi/CMakeLists.txt @@ -9,10 +9,7 @@ macro(get_bits_for_arch arch bits) endif() endmacro() -set(ASAN_ABI_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) -if(NOT COMPILER_RT_STANDALONE_BUILD) - list(APPEND ASAN_ABI_TEST_DEPS asan_abi) -endif() +set(ASAN_ABI_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} asan_abi) set(ASAN_ABI_TEST_ARCH ${ASAN_ABI_SUPPORTED_ARCH}) if(APPLE) diff --git a/compiler-rt/test/fuzzer/CMakeLists.txt b/compiler-rt/test/fuzzer/CMakeLists.txt index f0ba087a1b32..5bcb44757bae 100644 --- a/compiler-rt/test/fuzzer/CMakeLists.txt +++ b/compiler-rt/test/fuzzer/CMakeLists.txt @@ -1,12 +1,17 @@ -set(LIBFUZZER_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) +set(LIBFUZZER_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} fuzzer) +if (COMPILER_RT_HAS_UBSAN) + list(APPEND LIBFUZZER_TEST_DEPS ubsan) +endif() +if (COMPILER_RT_HAS_ASAN) + list(APPEND LIBFUZZER_TEST_DEPS asan) +endif() +if (COMPILER_RT_HAS_MSAN) + list(APPEND LIBFUZZER_TEST_DEPS msan) +endif() +if (COMPILER_RT_HAS_DFSAN) + list(APPEND LIBFUZZER_TEST_DEPS dfsan) +endif() if (NOT COMPILER_RT_STANDALONE_BUILD) - list(APPEND LIBFUZZER_TEST_DEPS fuzzer asan ubsan) - if (COMPILER_RT_HAS_MSAN) - list(APPEND LIBFUZZER_TEST_DEPS msan) - endif() - if (COMPILER_RT_HAS_DFSAN) - list(APPEND LIBFUZZER_TEST_DEPS dfsan) - endif() if(NOT APPLE AND COMPILER_RT_HAS_LLD AND "lld" IN_LIST LLVM_ENABLE_PROJECTS) list(APPEND LIBFUZZER_TEST_DEPS lld) endif() diff --git a/compiler-rt/test/memprof/CMakeLists.txt b/compiler-rt/test/memprof/CMakeLists.txt index 8a29919b1770..3f0ba3812485 100644 --- a/compiler-rt/test/memprof/CMakeLists.txt +++ b/compiler-rt/test/memprof/CMakeLists.txt @@ -11,12 +11,9 @@ macro(get_bits_for_arch arch bits) endif() endmacro() -set(MEMPROF_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) -if(NOT COMPILER_RT_STANDALONE_BUILD) - list(APPEND MEMPROF_TEST_DEPS memprof) - if(COMPILER_RT_HAS_LLD AND TARGET lld) - list(APPEND MEMPROF_TEST_DEPS lld) - endif() +set(MEMPROF_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} memprof) +if(NOT COMPILER_RT_STANDALONE_BUILD AND COMPILER_RT_HAS_LLD AND TARGET lld) + list(APPEND MEMPROF_TEST_DEPS lld) endif() set(MEMPROF_DYNAMIC_TEST_DEPS ${MEMPROF_TEST_DEPS}) diff --git a/compiler-rt/test/msan/CMakeLists.txt b/compiler-rt/test/msan/CMakeLists.txt index 01b832b5ae3f..9f784507c4ee 100644 --- a/compiler-rt/test/msan/CMakeLists.txt +++ b/compiler-rt/test/msan/CMakeLists.txt @@ -1,7 +1,7 @@ set(MSAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(MSAN_TESTSUITES) -set(MSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) +set(MSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} msan) set(MSAN_TEST_ARCH ${MSAN_SUPPORTED_ARCH}) if(APPLE) @@ -41,10 +41,6 @@ foreach(arch ${MSAN_TEST_ARCH}) endif() endforeach() -if(NOT COMPILER_RT_STANDALONE_BUILD) - list(APPEND MSAN_TEST_DEPS msan) -endif() - if(COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_LIBCXX_PATH AND COMPILER_RT_LIBCXXABI_PATH) diff --git a/compiler-rt/test/ubsan/CMakeLists.txt b/compiler-rt/test/ubsan/CMakeLists.txt index b5040f79e607..52052c80960c 100644 --- a/compiler-rt/test/ubsan/CMakeLists.txt +++ b/compiler-rt/test/ubsan/CMakeLists.txt @@ -23,9 +23,7 @@ macro(add_ubsan_testsuite test_mode sanitizer arch lld thinlto) ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg.py) list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) - if(NOT COMPILER_RT_STANDALONE_BUILD) - list(APPEND UBSAN_TEST_DEPS ${sanitizer}) - endif() + list(APPEND UBSAN_TEST_DEPS ${sanitizer}) endmacro() macro(add_ubsan_testsuites test_mode sanitizer arch) diff --git a/compiler-rt/test/xray/CMakeLists.txt b/compiler-rt/test/xray/CMakeLists.txt index b97659ae08f9..0c008b6ea557 100644 --- a/compiler-rt/test/xray/CMakeLists.txt +++ b/compiler-rt/test/xray/CMakeLists.txt @@ -3,12 +3,11 @@ set(XRAY_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(XRAY_TESTSUITES) set(XRAY_FDR_TESTSUITES) -set(XRAY_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) -set(XRAY_FDR_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) +set(XRAY_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} xray) if(NOT COMPILER_RT_STANDALONE_BUILD AND COMPILER_RT_BUILD_XRAY AND COMPILER_RT_HAS_XRAY) - list(APPEND XRAY_TEST_DEPS xray llvm-xray) + list(APPEND XRAY_TEST_DEPS llvm-xray) endif() set(XRAY_TEST_ARCH ${XRAY_SUPPORTED_ARCH}) -- GitLab From 2e6b18b3f3924d150c8837175938e76c3402f83f Mon Sep 17 00:00:00 2001 From: Aart Bik Date: Mon, 18 Mar 2024 17:06:02 -0700 Subject: [PATCH 006/307] [mlir][sparse] add example to new operation doc, and roundtrip test (#85711) --- .../Dialect/SparseTensor/IR/SparseTensorOps.td | 16 +++++++++++++--- mlir/test/Dialect/SparseTensor/roundtrip.mlir | 10 ++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td index 1b2981ac751f..29cf8c32447e 100644 --- a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td +++ b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td @@ -1444,9 +1444,19 @@ def SparseTensor_HasRuntimeLibraryOp : SparseTensor_Op<"has_runtime_library", []>, Results<(outs I1:$result)> { string summary = "Indicates whether running in runtime/codegen mode"; string description = [{ - Returns a boolean value that indicates whether the sparse compiler runs in - runtime library mode or not. For testing only: This op is useful for writing - test cases that require different IR depending on runtime/codegen mode. + Returns a boolean value that indicates whether the sparsifier runs in + runtime library mode or not. For testing only! This operation is useful + for writing test cases that require different code depending on + runtime/codegen mode. + + Example: + + ```mlir + %has_runtime = sparse_tensor.has_runtime_library + scf.if %has_runtime { + ... + } + ``` }]; let assemblyFormat = "attr-dict"; } diff --git a/mlir/test/Dialect/SparseTensor/roundtrip.mlir b/mlir/test/Dialect/SparseTensor/roundtrip.mlir index e9e458e805ba..a47a3d5119f9 100644 --- a/mlir/test/Dialect/SparseTensor/roundtrip.mlir +++ b/mlir/test/Dialect/SparseTensor/roundtrip.mlir @@ -728,3 +728,13 @@ func.func @sparse_print(%arg0: tensor<10x10xf64, #CSR>) { sparse_tensor.print %arg0 : tensor<10x10xf64, #CSR> return } + +// ----- + +// CHECK-LABEL: func.func @sparse_has_runtime() -> i1 +// CHECK: %[[H:.*]] = sparse_tensor.has_runtime_library +// CHECK: return %[[H]] : i1 +func.func @sparse_has_runtime() -> i1 { + %has_runtime = sparse_tensor.has_runtime_library + return %has_runtime : i1 +} -- GitLab From 42c38b1cc5c1b216f4bd18c39b82fcd64ca20b90 Mon Sep 17 00:00:00 2001 From: Aart Bik Date: Mon, 18 Mar 2024 17:10:23 -0700 Subject: [PATCH 007/307] [mlir][sparse] deallocate temporary transposed tensor (#85720) Last resort resolution of cycles introduced a sparse conversion without explicit sparse deallocation (which is not inserted by any automatic means). This fixes 2 out of 5 remaining asan detected leaks in sparse integration tests. --- .../SparseTensor/Transforms/SparseReinterpretMap.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp index f93b59de29e5..14ea07f0b54b 100644 --- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp +++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp @@ -573,6 +573,12 @@ private: rewriter.modifyOpInPlace(linalgOp, [&]() { linalgOp->setOperand(t->getOperandNumber(), dst); }); + + // Release the transposed form afterwards. + // TODO: CSE when used in more than one following op? + rewriter.setInsertionPointAfter(linalgOp); + rewriter.create(dst.getLoc(), dst); + return success(); } // Cannot be resolved with a single conversion. -- GitLab From 8a6a0f1954937341abd501529f3d7454937110a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Clement=20=28=E3=83=90=E3=83=AC=E3=83=B3?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=B3=20=E3=82=AF=E3=83=AC=E3=83=A1?= =?UTF-8?q?=E3=83=B3=29?= Date: Mon, 18 Mar 2024 17:11:04 -0700 Subject: [PATCH 008/307] [flang][cuda] Add proper TODO for cuda fortran assignment (#85705) Data transfer between host and device can be done with assignment statements in CUDA Fortran. This is currently not lowered so adding a proper TODO. https://docs.nvidia.com/hpc-sdk/archive/24.3/compilers/cuda-fortran-prog-guide/index.html#cfref-data-trans-assgn-statemts --- flang/include/flang/Evaluate/tools.h | 14 ++++++++++++++ flang/lib/Lower/Bridge.cpp | 5 +++++ flang/test/Lower/CUDA/cuda-module-use.cuf | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index aba40025ca50..9a32062440ab 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -1218,6 +1218,20 @@ bool CheckForCoindexedObject(parser::ContextualMessages &, const std::optional &, const std::string &procName, const std::string &argName); +/// Check if any of the symbols part of the expression has a cuda data +/// attribute. +inline bool HasCUDAAttrs(const Expr &expr) { + for (const Symbol &sym : CollectSymbols(expr)) { + if (const auto *details = + sym.GetUltimate().detailsIf()) { + if (details->cudaDataAttr()) { + return true; + } + } + } + return false; +} + } // namespace Fortran::evaluate namespace Fortran::semantics { diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 650ec5db2d0c..6c32c537198c 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -3692,6 +3692,11 @@ private: const Fortran::evaluate::ProcedureRef *userDefinedAssignment) { mlir::Location loc = getCurrentLocation(); fir::FirOpBuilder &builder = getFirOpBuilder(); + + if (Fortran::evaluate::HasCUDAAttrs(assign.lhs) || + Fortran::evaluate::HasCUDAAttrs(assign.rhs)) + TODO(loc, "Assignement with CUDA Fortran variables"); + // Gather some information about the assignment that will impact how it is // lowered. const bool isWholeAllocatableAssignment = diff --git a/flang/test/Lower/CUDA/cuda-module-use.cuf b/flang/test/Lower/CUDA/cuda-module-use.cuf index f54083b026ee..47d3805065a5 100644 --- a/flang/test/Lower/CUDA/cuda-module-use.cuf +++ b/flang/test/Lower/CUDA/cuda-module-use.cuf @@ -5,7 +5,7 @@ subroutine sub1() use cuf_mod - md = 1.0 +! md = 1.0 ! currently a TODO end ! CHECK-LABEL: func.func @_QPsub1() -- GitLab From 6ae77eca6ceb17033eb58440038e620eba1c6f51 Mon Sep 17 00:00:00 2001 From: Kyungwoo Lee Date: Mon, 18 Mar 2024 17:15:40 -0700 Subject: [PATCH 009/307] Revert "[lld] Fix warnings" This reverts commit 6800f422c22ffd672b1e31f0d0a3fa29d19b7a13 as the part of revert https://github.com/llvm/llvm-project/pull/82928. buildbot failures: https://lab.llvm.org/buildbot/#/builders/168/builds/19302/steps/10/logs/stdio --- lld/MachO/ObjC.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp index 3e26ed5f2ebe..9b2446360e4f 100644 --- a/lld/MachO/ObjC.cpp +++ b/lld/MachO/ObjC.cpp @@ -636,7 +636,6 @@ void ObjcCategoryMerger::parseProtocolListInfo(const ConcatInputSection *isec, /*extra null value*/ target->wordSize; assert(expectedListSize == ptrListSym->isec->data.size() && "Protocol list does not match expected size"); - (void)expectedListSize; uint32_t off = protocolListHeaderLayout.totalSize; for (uint32_t inx = 0; inx < protocolCount; ++inx) { @@ -1034,7 +1033,6 @@ void ObjcCategoryMerger::mergeCategoriesIntoSingleCategory( Defined *newCatDef = emitCategory(extInfo); assert(newCatDef && "Failed to create a new category"); - (void)newCatDef; for (auto &catInfo : categories) catInfo.wasMerged = true; -- GitLab From 5373daad9492e157c0c1ad496334f5dfd78d7da0 Mon Sep 17 00:00:00 2001 From: Kyungwoo Lee Date: Mon, 18 Mar 2024 17:16:52 -0700 Subject: [PATCH 010/307] Revert "[lld-macho] Implement ObjC category merging (-objc_category_merging) (#82928)" This reverts commit ece2903ce730392e5236d27f1f387fa8067fcb1b, https://github.com/llvm/llvm-project/pull/82928. https://github.com/llvm/llvm-project/pull/82928 --- lld/MachO/Driver.cpp | 9 - lld/MachO/InputSection.h | 2 +- lld/MachO/ObjC.cpp | 920 +----------------- lld/MachO/ObjC.h | 12 - lld/MachO/Options.td | 10 +- .../objc-category-merging-complete-test.s | 762 --------------- ...jc-category-merging-extern-class-minimal.s | 155 --- 7 files changed, 8 insertions(+), 1862 deletions(-) delete mode 100644 lld/test/MachO/objc-category-merging-complete-test.s delete mode 100644 lld/test/MachO/objc-category-merging-extern-class-minimal.s diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 36248925d65a..9edb6b9c60a1 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1437,8 +1437,6 @@ bool link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, resetOutputSegments(); resetWriter(); InputFile::resetIdCount(); - - objc::doCleanup(); }; ctx->e.logName = args::getFilenameWithoutExe(argsArr[0]); @@ -1981,16 +1979,9 @@ bool link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, if (config->deadStrip) markLive(); - // Categories are not subject to dead-strip. The __objc_catlist section is - // marked as NO_DEAD_STRIP and that propagates into all category data. if (args.hasArg(OPT_check_category_conflicts)) objc::checkCategories(); - // Category merging uses "->live = false" to erase old category data, so - // it has to run after dead-stripping (markLive). - if (args.hasArg(OPT_objc_category_merging, OPT_no_objc_category_merging)) - objc::mergeCategories(); - // ICF assumes that all literals have been folded already, so we must run // foldIdenticalLiterals before foldIdenticalSections. foldIdenticalLiterals(); diff --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h index b25f0638f4c6..becb01017d63 100644 --- a/lld/MachO/InputSection.h +++ b/lld/MachO/InputSection.h @@ -93,9 +93,9 @@ public: // .subsections_via_symbols, there is typically only one element here. llvm::TinyPtrVector symbols; +protected: const Section §ion; -protected: const Defined *getContainingSymbol(uint64_t off) const; }; diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp index 9b2446360e4f..67254ec53a21 100644 --- a/lld/MachO/ObjC.cpp +++ b/lld/MachO/ObjC.cpp @@ -7,19 +7,16 @@ //===----------------------------------------------------------------------===// #include "ObjC.h" -#include "ConcatOutputSection.h" #include "InputFiles.h" #include "InputSection.h" #include "Layout.h" #include "OutputSegment.h" -#include "SyntheticSections.h" #include "Target.h" #include "lld/Common/ErrorHandler.h" #include "llvm/ADT/DenseMap.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/Bitcode/BitcodeReader.h" -#include "llvm/Support/TimeProfiler.h" using namespace llvm; using namespace llvm::MachO; @@ -81,8 +78,7 @@ namespace { DO(Ptr, classMethods) \ DO(Ptr, protocols) \ DO(Ptr, instanceProps) \ - DO(Ptr, classProps) \ - DO(uint32_t, size) + DO(Ptr, classProps) CREATE_LAYOUT_CLASS(Category, FOR_EACH_CATEGORY_FIELD); @@ -116,19 +112,13 @@ CREATE_LAYOUT_CLASS(ROClass, FOR_EACH_RO_CLASS_FIELD); #undef FOR_EACH_RO_CLASS_FIELD #define FOR_EACH_LIST_HEADER(DO) \ - DO(uint32_t, structSize) \ - DO(uint32_t, structCount) + DO(uint32_t, size) \ + DO(uint32_t, count) CREATE_LAYOUT_CLASS(ListHeader, FOR_EACH_LIST_HEADER); #undef FOR_EACH_LIST_HEADER -#define FOR_EACH_PROTOCOL_LIST_HEADER(DO) DO(Ptr, protocolCount) - -CREATE_LAYOUT_CLASS(ProtocolListHeader, FOR_EACH_PROTOCOL_LIST_HEADER); - -#undef FOR_EACH_PROTOCOL_LIST_HEADER - #define FOR_EACH_METHOD(DO) \ DO(Ptr, name) \ DO(Ptr, type) \ @@ -321,8 +311,6 @@ void ObjcCategoryChecker::parseClass(const Defined *classSym) { } void objc::checkCategories() { - TimeTraceScope timeScope("ObjcCategoryChecker"); - ObjcCategoryChecker checker; for (const InputSection *isec : inputSections) { if (isec->getName() == section_names::objcCatList) @@ -332,905 +320,3 @@ void objc::checkCategories() { } } } - -namespace { - -class ObjcCategoryMerger { - // Information about an input category - struct InfoInputCategory { - ConcatInputSection *catListIsec; - ConcatInputSection *catBodyIsec; - uint32_t offCatListIsec = 0; - - bool wasMerged = false; - }; - - // To write new (merged) categories or classes, we will try make limited - // assumptions about the alignment and the sections the various class/category - // info are stored in and . So we'll just reuse the same sections and - // alignment as already used in existing (input) categories. To do this we - // have InfoCategoryWriter which contains the various sections that the - // generated categories will be written to. - template struct InfoWriteSection { - bool valid = false; // Data has been successfully collected from input - uint32_t align = 0; - Section *inputSection; - Reloc relocTemplate; - T *outputSection; - }; - - struct InfoCategoryWriter { - InfoWriteSection catListInfo; - InfoWriteSection catBodyInfo; - InfoWriteSection catNameInfo; - InfoWriteSection catPtrListInfo; - }; - - // Information about a pointer list in the original categories (method lists, - // protocol lists, etc) - struct PointerListInfo { - PointerListInfo(const char *_categoryPrefix, uint32_t _categoryOffset, - uint32_t _pointersPerStruct) - : categoryPrefix(_categoryPrefix), categoryOffset(_categoryOffset), - pointersPerStruct(_pointersPerStruct) {} - const char *categoryPrefix; - uint32_t categoryOffset = 0; - - uint32_t pointersPerStruct = 0; - - uint32_t structSize = 0; - uint32_t structCount = 0; - - std::vector allPtrs; - }; - - // Full information about all the categories that extend a class. This will - // include all the additional methods, protocols, and properties that are - // contained in all the categories that extend a particular class. - struct ClassExtensionInfo { - ClassExtensionInfo(CategoryLayout &_catLayout) : catLayout(_catLayout){}; - - // Merged names of containers. Ex: base|firstCategory|secondCategory|... - std::string mergedContainerName; - std::string baseClassName; - Symbol *baseClass = nullptr; - CategoryLayout &catLayout; - - // In case we generate new data, mark the new data as belonging to this file - ObjFile *objFileForMergeData = nullptr; - - PointerListInfo instanceMethods = { - objc::symbol_names::categoryInstanceMethods, - /*_categoryOffset=*/catLayout.instanceMethodsOffset, - /*pointersPerStruct=*/3}; - PointerListInfo classMethods = { - objc::symbol_names::categoryClassMethods, - /*_categoryOffset=*/catLayout.classMethodsOffset, - /*pointersPerStruct=*/3}; - PointerListInfo protocols = {objc::symbol_names::categoryProtocols, - /*_categoryOffset=*/catLayout.protocolsOffset, - /*pointersPerStruct=*/0}; - PointerListInfo instanceProps = { - objc::symbol_names::listProprieties, - /*_categoryOffset=*/catLayout.instancePropsOffset, - /*pointersPerStruct=*/2}; - PointerListInfo classProps = { - objc::symbol_names::klassPropList, - /*_categoryOffset=*/catLayout.classPropsOffset, - /*pointersPerStruct=*/2}; - }; - -public: - ObjcCategoryMerger(std::vector &_allInputSections); - void doMerge(); - static void doCleanup(); - -private: - void collectAndValidateCategoriesData(); - void - mergeCategoriesIntoSingleCategory(std::vector &categories); - - void eraseISec(ConcatInputSection *isec); - void eraseMergedCategories(); - - void generateCatListForNonErasedCategories( - std::map> - catListToErasedOffsets); - template - void collectSectionWriteInfoFromIsec(const InputSection *isec, - InfoWriteSection &catWriteInfo); - void collectCategoryWriterInfoFromCategory(const InfoInputCategory &catInfo); - void parseCatInfoToExtInfo(const InfoInputCategory &catInfo, - ClassExtensionInfo &extInfo); - - void parseProtocolListInfo(const ConcatInputSection *isec, uint32_t secOffset, - PointerListInfo &ptrList); - - void parsePointerListInfo(const ConcatInputSection *isec, uint32_t secOffset, - PointerListInfo &ptrList); - - void emitAndLinkPointerList(Defined *parentSym, uint32_t linkAtOffset, - const ClassExtensionInfo &extInfo, - const PointerListInfo &ptrList); - - void emitAndLinkProtocolList(Defined *parentSym, uint32_t linkAtOffset, - const ClassExtensionInfo &extInfo, - const PointerListInfo &ptrList); - - Defined *emitCategory(const ClassExtensionInfo &extInfo); - Defined *emitCatListEntrySec(const std::string &forCateogryName, - const std::string &forBaseClassName, - ObjFile *objFile); - Defined *emitCategoryBody(const std::string &name, const Defined *nameSym, - const Symbol *baseClassSym, - const std::string &baseClassName, ObjFile *objFile); - Defined *emitCategoryName(const std::string &name, ObjFile *objFile); - void createSymbolReference(Defined *refFrom, const Symbol *refTo, - uint32_t offset, const Reloc &relocTemplate); - Symbol *tryGetSymbolAtIsecOffset(const ConcatInputSection *isec, - uint32_t offset); - Defined *tryGetDefinedAtIsecOffset(const ConcatInputSection *isec, - uint32_t offset); - void tryEraseDefinedAtIsecOffset(const ConcatInputSection *isec, - uint32_t offset); - - // Allocate a null-terminated StringRef backed by generatedSectionData - StringRef newStringData(const char *str); - // Allocate section data, backed by generatedSectionData - SmallVector &newSectionData(uint32_t size); - - CategoryLayout catLayout; - ClassLayout classLayout; - ROClassLayout roClassLayout; - ListHeaderLayout listHeaderLayout; - MethodLayout methodLayout; - ProtocolListHeaderLayout protocolListHeaderLayout; - - InfoCategoryWriter infoCategoryWriter; - std::vector &allInputSections; - // Map of base class Symbol to list of InfoInputCategory's for it - DenseMap> categoryMap; - - // Normally, the binary data comes from the input files, but since we're - // generating binary data ourselves, we use the below array to store it in. - // Need this to be 'static' so the data survives past the ObjcCategoryMerger - // object, as the data will be read by the Writer when the final binary is - // generated. - static SmallVector> generatedSectionData; -}; - -SmallVector> ObjcCategoryMerger::generatedSectionData; - -ObjcCategoryMerger::ObjcCategoryMerger( - std::vector &_allInputSections) - : catLayout(target->wordSize), classLayout(target->wordSize), - roClassLayout(target->wordSize), listHeaderLayout(target->wordSize), - methodLayout(target->wordSize), - protocolListHeaderLayout(target->wordSize), - allInputSections(_allInputSections) {} - -// This is a template so that it can be used both for CStringSection and -// ConcatOutputSection -template -void ObjcCategoryMerger::collectSectionWriteInfoFromIsec( - const InputSection *isec, InfoWriteSection &catWriteInfo) { - - catWriteInfo.inputSection = const_cast
(&isec->section); - catWriteInfo.align = isec->align; - catWriteInfo.outputSection = dyn_cast_or_null(isec->parent); - - assert(catWriteInfo.outputSection && - "outputSection may not be null in collectSectionWriteInfoFromIsec."); - - if (isec->relocs.size()) - catWriteInfo.relocTemplate = isec->relocs[0]; - - catWriteInfo.valid = true; -} - -Symbol * -ObjcCategoryMerger::tryGetSymbolAtIsecOffset(const ConcatInputSection *isec, - uint32_t offset) { - const Reloc *reloc = isec->getRelocAt(offset); - - if (!reloc) - return nullptr; - - return reloc->referent.get(); -} - -Defined * -ObjcCategoryMerger::tryGetDefinedAtIsecOffset(const ConcatInputSection *isec, - uint32_t offset) { - Symbol *sym = tryGetSymbolAtIsecOffset(isec, offset); - return dyn_cast_or_null(sym); -} - -// Given an ConcatInputSection or CStringInputSection and an offset, if there is -// a symbol(Defined) at that offset, then erase the symbol (mark it not live) -void ObjcCategoryMerger::tryEraseDefinedAtIsecOffset( - const ConcatInputSection *isec, uint32_t offset) { - const Reloc *reloc = isec->getRelocAt(offset); - - if (!reloc) - return; - - Defined *sym = dyn_cast_or_null(reloc->referent.get()); - if (!sym) - return; - - if (auto *cisec = dyn_cast_or_null(sym->isec)) - eraseISec(cisec); - else if (auto *csisec = dyn_cast_or_null(sym->isec)) { - uint32_t totalOffset = sym->value + reloc->addend; - StringPiece &piece = csisec->getStringPiece(totalOffset); - piece.live = false; - } else { - llvm_unreachable("erased symbol has to be Defined or CStringInputSection"); - } -} - -void ObjcCategoryMerger::collectCategoryWriterInfoFromCategory( - const InfoInputCategory &catInfo) { - - if (!infoCategoryWriter.catListInfo.valid) - collectSectionWriteInfoFromIsec( - catInfo.catListIsec, infoCategoryWriter.catListInfo); - if (!infoCategoryWriter.catBodyInfo.valid) - collectSectionWriteInfoFromIsec( - catInfo.catBodyIsec, infoCategoryWriter.catBodyInfo); - - if (!infoCategoryWriter.catNameInfo.valid) { - lld::macho::Defined *catNameSym = - tryGetDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset); - assert(catNameSym && "Category does not have a valid name Symbol"); - - collectSectionWriteInfoFromIsec( - catNameSym->isec, infoCategoryWriter.catNameInfo); - } - - // Collect writer info from all the category lists (we're assuming they all - // would provide the same info) - if (!infoCategoryWriter.catPtrListInfo.valid) { - for (uint32_t off = catLayout.instanceMethodsOffset; - off <= catLayout.classPropsOffset; off += target->wordSize) { - if (Defined *ptrList = - tryGetDefinedAtIsecOffset(catInfo.catBodyIsec, off)) { - collectSectionWriteInfoFromIsec( - ptrList->isec, infoCategoryWriter.catPtrListInfo); - // we've successfully collected data, so we can break - break; - } - } - } -} - -// Parse a protocol list that might be linked to ConcatInputSection at a given -// offset. The format of the protocol list is different than other lists (prop -// lists, method lists) so we need to parse it differently -void ObjcCategoryMerger::parseProtocolListInfo(const ConcatInputSection *isec, - uint32_t secOffset, - PointerListInfo &ptrList) { - if (!isec || (secOffset + target->wordSize > isec->data.size())) - assert("Tried to read pointer list beyond protocol section end"); - - const Reloc *reloc = isec->getRelocAt(secOffset); - if (!reloc) - return; - - auto *ptrListSym = dyn_cast_or_null(reloc->referent.get()); - assert(ptrListSym && "Protocol list reloc does not have a valid Defined"); - - // Theoretically protocol count can be either 32b or 64b, depending on - // platform pointer size, but to simplify implementation we always just read - // the lower 32b which should be good enough. - uint32_t protocolCount = *reinterpret_cast( - ptrListSym->isec->data.data() + listHeaderLayout.structSizeOffset); - - ptrList.structCount += protocolCount; - ptrList.structSize = target->wordSize; - - uint32_t expectedListSize = - (protocolCount * target->wordSize) + - /*header(count)*/ protocolListHeaderLayout.totalSize + - /*extra null value*/ target->wordSize; - assert(expectedListSize == ptrListSym->isec->data.size() && - "Protocol list does not match expected size"); - - uint32_t off = protocolListHeaderLayout.totalSize; - for (uint32_t inx = 0; inx < protocolCount; ++inx) { - const Reloc *reloc = ptrListSym->isec->getRelocAt(off); - assert(reloc && "No reloc found at protocol list offset"); - - auto *listSym = dyn_cast_or_null(reloc->referent.get()); - assert(listSym && "Protocol list reloc does not have a valid Defined"); - - ptrList.allPtrs.push_back(listSym); - off += target->wordSize; - } - assert((ptrListSym->isec->getRelocAt(off) == nullptr) && - "expected null terminating protocol"); - assert(off + /*extra null value*/ target->wordSize == expectedListSize && - "Protocol list end offset does not match expected size"); -} - -// Parse a pointer list that might be linked to ConcatInputSection at a given -// offset. This can be used for instance methods, class methods, instance props -// and class props since they have the same format. -void ObjcCategoryMerger::parsePointerListInfo(const ConcatInputSection *isec, - uint32_t secOffset, - PointerListInfo &ptrList) { - assert(ptrList.pointersPerStruct == 2 || ptrList.pointersPerStruct == 3); - assert(isec && "Trying to parse pointer list from null isec"); - assert(secOffset + target->wordSize <= isec->data.size() && - "Trying to read pointer list beyond section end"); - - const Reloc *reloc = isec->getRelocAt(secOffset); - if (!reloc) - return; - - auto *ptrListSym = dyn_cast_or_null(reloc->referent.get()); - assert(ptrListSym && "Reloc does not have a valid Defined"); - - uint32_t thisStructSize = *reinterpret_cast( - ptrListSym->isec->data.data() + listHeaderLayout.structSizeOffset); - uint32_t thisStructCount = *reinterpret_cast( - ptrListSym->isec->data.data() + listHeaderLayout.structCountOffset); - assert(thisStructSize == ptrList.pointersPerStruct * target->wordSize); - - assert(!ptrList.structSize || (thisStructSize == ptrList.structSize)); - - ptrList.structCount += thisStructCount; - ptrList.structSize = thisStructSize; - - uint32_t expectedListSize = - listHeaderLayout.totalSize + (thisStructSize * thisStructCount); - assert(expectedListSize == ptrListSym->isec->data.size() && - "Pointer list does not match expected size"); - - for (uint32_t off = listHeaderLayout.totalSize; off < expectedListSize; - off += target->wordSize) { - const Reloc *reloc = ptrListSym->isec->getRelocAt(off); - assert(reloc && "No reloc found at pointer list offset"); - - auto *listSym = dyn_cast_or_null(reloc->referent.get()); - assert(listSym && "Reloc does not have a valid Defined"); - - ptrList.allPtrs.push_back(listSym); - } -} - -// Here we parse all the information of an input category (catInfo) and -// append the parsed info into the structure which will contain all the -// information about how a class is extended (extInfo) -void ObjcCategoryMerger::parseCatInfoToExtInfo(const InfoInputCategory &catInfo, - ClassExtensionInfo &extInfo) { - const Reloc *catNameReloc = - catInfo.catBodyIsec->getRelocAt(catLayout.nameOffset); - - // Parse name - assert(catNameReloc && "Category does not have a reloc at 'nameOffset'"); - - // is this the first category we are parsing? - if (extInfo.mergedContainerName.empty()) - extInfo.objFileForMergeData = - dyn_cast_or_null(catInfo.catBodyIsec->getFile()); - else - extInfo.mergedContainerName += "|"; - - assert(extInfo.objFileForMergeData && - "Expected to already have valid objextInfo.objFileForMergeData"); - - StringRef catName = getReferentString(*catNameReloc); - extInfo.mergedContainerName += catName.str(); - - // Parse base class - if (!extInfo.baseClass) { - Symbol *classSym = - tryGetSymbolAtIsecOffset(catInfo.catBodyIsec, catLayout.klassOffset); - assert(extInfo.baseClassName.empty()); - extInfo.baseClass = classSym; - llvm::StringRef classPrefix(objc::symbol_names::klass); - assert(classSym->getName().starts_with(classPrefix) && - "Base class symbol does not start with expected prefix"); - extInfo.baseClassName = classSym->getName().substr(classPrefix.size()); - } else { - assert((extInfo.baseClass == - tryGetSymbolAtIsecOffset(catInfo.catBodyIsec, - catLayout.klassOffset)) && - "Trying to parse category info into container with different base " - "class"); - } - - parsePointerListInfo(catInfo.catBodyIsec, catLayout.instanceMethodsOffset, - extInfo.instanceMethods); - - parsePointerListInfo(catInfo.catBodyIsec, catLayout.classMethodsOffset, - extInfo.classMethods); - - parseProtocolListInfo(catInfo.catBodyIsec, catLayout.protocolsOffset, - extInfo.protocols); - - parsePointerListInfo(catInfo.catBodyIsec, catLayout.instancePropsOffset, - extInfo.instanceProps); - - parsePointerListInfo(catInfo.catBodyIsec, catLayout.classPropsOffset, - extInfo.classProps); -} - -// Generate a protocol list (including header) and link it into the parent at -// the specified offset. -void ObjcCategoryMerger::emitAndLinkProtocolList( - Defined *parentSym, uint32_t linkAtOffset, - const ClassExtensionInfo &extInfo, const PointerListInfo &ptrList) { - if (ptrList.allPtrs.empty()) - return; - - assert(ptrList.allPtrs.size() == ptrList.structCount); - - uint32_t bodySize = (ptrList.structCount * target->wordSize) + - /*header(count)*/ protocolListHeaderLayout.totalSize + - /*extra null value*/ target->wordSize; - llvm::ArrayRef bodyData = newSectionData(bodySize); - - // This theoretically can be either 32b or 64b, but writing just the first 32b - // is good enough - const uint32_t *ptrProtoCount = reinterpret_cast( - bodyData.data() + protocolListHeaderLayout.protocolCountOffset); - - *const_cast(ptrProtoCount) = ptrList.allPtrs.size(); - - ConcatInputSection *listSec = make( - *infoCategoryWriter.catPtrListInfo.inputSection, bodyData, - infoCategoryWriter.catPtrListInfo.align); - listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection; - listSec->live = true; - allInputSections.push_back(listSec); - - listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection; - - std::string symName = ptrList.categoryPrefix; - symName += extInfo.baseClassName + "_$_(" + extInfo.mergedContainerName + ")"; - - Defined *ptrListSym = make( - newStringData(symName.c_str()), /*file=*/parentSym->getObjectFile(), - listSec, /*value=*/0, bodyData.size(), /*isWeakDef=*/false, - /*isExternal=*/false, /*isPrivateExtern=*/false, /*includeInSymtab=*/true, - /*isReferencedDynamically=*/false, /*noDeadStrip=*/false, - /*isWeakDefCanBeHidden=*/false); - - ptrListSym->used = true; - parentSym->getObjectFile()->symbols.push_back(ptrListSym); - - createSymbolReference(parentSym, ptrListSym, linkAtOffset, - infoCategoryWriter.catBodyInfo.relocTemplate); - - uint32_t offset = protocolListHeaderLayout.totalSize; - for (Symbol *symbol : ptrList.allPtrs) { - createSymbolReference(ptrListSym, symbol, offset, - infoCategoryWriter.catPtrListInfo.relocTemplate); - offset += target->wordSize; - } -} - -// Generate a pointer list (including header) and link it into the parent at the -// specified offset. This is used for instance and class methods and -// proprieties. -void ObjcCategoryMerger::emitAndLinkPointerList( - Defined *parentSym, uint32_t linkAtOffset, - const ClassExtensionInfo &extInfo, const PointerListInfo &ptrList) { - if (ptrList.allPtrs.empty()) - return; - - assert(ptrList.allPtrs.size() * target->wordSize == - ptrList.structCount * ptrList.structSize); - - // Generate body - uint32_t bodySize = - listHeaderLayout.totalSize + (ptrList.structSize * ptrList.structCount); - llvm::ArrayRef bodyData = newSectionData(bodySize); - - const uint32_t *ptrStructSize = reinterpret_cast( - bodyData.data() + listHeaderLayout.structSizeOffset); - const uint32_t *ptrStructCount = reinterpret_cast( - bodyData.data() + listHeaderLayout.structCountOffset); - - *const_cast(ptrStructSize) = ptrList.structSize; - *const_cast(ptrStructCount) = ptrList.structCount; - - ConcatInputSection *listSec = make( - *infoCategoryWriter.catPtrListInfo.inputSection, bodyData, - infoCategoryWriter.catPtrListInfo.align); - listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection; - listSec->live = true; - allInputSections.push_back(listSec); - - listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection; - - std::string symName = ptrList.categoryPrefix; - symName += extInfo.baseClassName + "_$_" + extInfo.mergedContainerName; - - Defined *ptrListSym = make( - newStringData(symName.c_str()), /*file=*/parentSym->getObjectFile(), - listSec, /*value=*/0, bodyData.size(), /*isWeakDef=*/false, - /*isExternal=*/false, /*isPrivateExtern=*/false, /*includeInSymtab=*/true, - /*isReferencedDynamically=*/false, /*noDeadStrip=*/false, - /*isWeakDefCanBeHidden=*/false); - - ptrListSym->used = true; - parentSym->getObjectFile()->symbols.push_back(ptrListSym); - - createSymbolReference(parentSym, ptrListSym, linkAtOffset, - infoCategoryWriter.catBodyInfo.relocTemplate); - - uint32_t offset = listHeaderLayout.totalSize; - for (Symbol *symbol : ptrList.allPtrs) { - createSymbolReference(ptrListSym, symbol, offset, - infoCategoryWriter.catPtrListInfo.relocTemplate); - offset += target->wordSize; - } -} - -// This method creates an __objc_catlist ConcatInputSection with a single slot -Defined * -ObjcCategoryMerger::emitCatListEntrySec(const std::string &forCateogryName, - const std::string &forBaseClassName, - ObjFile *objFile) { - uint32_t sectionSize = target->wordSize; - llvm::ArrayRef bodyData = newSectionData(sectionSize); - - ConcatInputSection *newCatList = - make(*infoCategoryWriter.catListInfo.inputSection, - bodyData, infoCategoryWriter.catListInfo.align); - newCatList->parent = infoCategoryWriter.catListInfo.outputSection; - newCatList->live = true; - allInputSections.push_back(newCatList); - - newCatList->parent = infoCategoryWriter.catListInfo.outputSection; - - std::string catSymName = "<__objc_catlist slot for merged category "; - catSymName += forBaseClassName + "(" + forCateogryName + ")>"; - - Defined *catListSym = make( - newStringData(catSymName.c_str()), /*file=*/objFile, newCatList, - /*value=*/0, bodyData.size(), /*isWeakDef=*/false, /*isExternal=*/false, - /*isPrivateExtern=*/false, /*includeInSymtab=*/false, - /*isReferencedDynamically=*/false, /*noDeadStrip=*/false, - /*isWeakDefCanBeHidden=*/false); - - catListSym->used = true; - objFile->symbols.push_back(catListSym); - return catListSym; -} - -// Here we generate the main category body and link the name and base class into -// it. We don't link any other info yet like the protocol and class/instance -// methods/props. -Defined *ObjcCategoryMerger::emitCategoryBody(const std::string &name, - const Defined *nameSym, - const Symbol *baseClassSym, - const std::string &baseClassName, - ObjFile *objFile) { - llvm::ArrayRef bodyData = newSectionData(catLayout.totalSize); - - uint32_t *ptrSize = (uint32_t *)(const_cast(bodyData.data()) + - catLayout.sizeOffset); - *ptrSize = catLayout.totalSize; - - ConcatInputSection *newBodySec = - make(*infoCategoryWriter.catBodyInfo.inputSection, - bodyData, infoCategoryWriter.catBodyInfo.align); - newBodySec->parent = infoCategoryWriter.catBodyInfo.outputSection; - newBodySec->live = true; - allInputSections.push_back(newBodySec); - - std::string symName = - objc::symbol_names::category + baseClassName + "_$_(" + name + ")"; - Defined *catBodySym = make( - newStringData(symName.c_str()), /*file=*/objFile, newBodySec, - /*value=*/0, bodyData.size(), /*isWeakDef=*/false, /*isExternal=*/false, - /*isPrivateExtern=*/false, /*includeInSymtab=*/true, - /*isReferencedDynamically=*/false, /*noDeadStrip=*/false, - /*isWeakDefCanBeHidden=*/false); - - catBodySym->used = true; - objFile->symbols.push_back(catBodySym); - - createSymbolReference(catBodySym, nameSym, catLayout.nameOffset, - infoCategoryWriter.catBodyInfo.relocTemplate); - - // Create a reloc to the base class (either external or internal) - createSymbolReference(catBodySym, baseClassSym, catLayout.klassOffset, - infoCategoryWriter.catBodyInfo.relocTemplate); - - return catBodySym; -} - -// This writes the new category name (for the merged category) into the binary -// and returns the sybmol for it. -Defined *ObjcCategoryMerger::emitCategoryName(const std::string &name, - ObjFile *objFile) { - StringRef nameStrData = newStringData(name.c_str()); - // We use +1 below to include the null terminator - llvm::ArrayRef nameData( - reinterpret_cast(nameStrData.data()), - nameStrData.size() + 1); - - auto *parentSection = infoCategoryWriter.catNameInfo.inputSection; - CStringInputSection *newStringSec = make( - *infoCategoryWriter.catNameInfo.inputSection, nameData, - infoCategoryWriter.catNameInfo.align, /*dedupLiterals=*/true); - - parentSection->subsections.push_back({0, newStringSec}); - - newStringSec->splitIntoPieces(); - newStringSec->pieces[0].live = true; - newStringSec->parent = infoCategoryWriter.catNameInfo.outputSection; - in.cStringSection->addInput(newStringSec); - assert(newStringSec->pieces.size() == 1); - - Defined *catNameSym = make( - "", /*file=*/objFile, newStringSec, - /*value=*/0, nameData.size(), - /*isWeakDef=*/false, /*isExternal=*/false, /*isPrivateExtern=*/false, - /*includeInSymtab=*/false, /*isReferencedDynamically=*/false, - /*noDeadStrip=*/false, /*isWeakDefCanBeHidden=*/false); - - catNameSym->used = true; - objFile->symbols.push_back(catNameSym); - return catNameSym; -} - -// This method fully creates a new category from the given ClassExtensionInfo. -// It creates the category name, body and method/protocol/prop lists and links -// them all together. Then it creates a new __objc_catlist entry and adds the -// category to it. Calling this method will fully generate a category which will -// be available in the final binary. -Defined *ObjcCategoryMerger::emitCategory(const ClassExtensionInfo &extInfo) { - Defined *catNameSym = emitCategoryName(extInfo.mergedContainerName, - extInfo.objFileForMergeData); - - Defined *catBodySym = emitCategoryBody( - extInfo.mergedContainerName, catNameSym, extInfo.baseClass, - extInfo.baseClassName, extInfo.objFileForMergeData); - - Defined *catListSym = - emitCatListEntrySec(extInfo.mergedContainerName, extInfo.baseClassName, - extInfo.objFileForMergeData); - - // Add the single category body to the category list at the offset 0. - createSymbolReference(catListSym, catBodySym, /*offset=*/0, - infoCategoryWriter.catListInfo.relocTemplate); - - emitAndLinkPointerList(catBodySym, catLayout.instanceMethodsOffset, extInfo, - extInfo.instanceMethods); - - emitAndLinkPointerList(catBodySym, catLayout.classMethodsOffset, extInfo, - extInfo.classMethods); - - emitAndLinkProtocolList(catBodySym, catLayout.protocolsOffset, extInfo, - extInfo.protocols); - - emitAndLinkPointerList(catBodySym, catLayout.instancePropsOffset, extInfo, - extInfo.instanceProps); - - emitAndLinkPointerList(catBodySym, catLayout.classPropsOffset, extInfo, - extInfo.classProps); - - return catBodySym; -} - -// This method merges all the categories (sharing a base class) into a single -// category. -void ObjcCategoryMerger::mergeCategoriesIntoSingleCategory( - std::vector &categories) { - assert(categories.size() > 1 && "Expected at least 2 categories"); - - ClassExtensionInfo extInfo(catLayout); - - for (auto &catInfo : categories) - parseCatInfoToExtInfo(catInfo, extInfo); - - Defined *newCatDef = emitCategory(extInfo); - assert(newCatDef && "Failed to create a new category"); - - for (auto &catInfo : categories) - catInfo.wasMerged = true; -} - -void ObjcCategoryMerger::createSymbolReference(Defined *refFrom, - const Symbol *refTo, - uint32_t offset, - const Reloc &relocTemplate) { - Reloc r = relocTemplate; - r.offset = offset; - r.addend = 0; - r.referent = const_cast(refTo); - refFrom->isec->relocs.push_back(r); -} - -void ObjcCategoryMerger::collectAndValidateCategoriesData() { - for (InputSection *sec : allInputSections) { - if (sec->getName() != section_names::objcCatList) - continue; - ConcatInputSection *catListCisec = dyn_cast(sec); - assert(catListCisec && - "__objc_catList InputSection is not a ConcatInputSection"); - - for (uint32_t off = 0; off < catListCisec->getSize(); - off += target->wordSize) { - Defined *categorySym = tryGetDefinedAtIsecOffset(catListCisec, off); - assert(categorySym && - "Failed to get a valid cateogry at __objc_catlit offset"); - - // We only support ObjC categories (no swift + @objc) - // TODO: Support swift + @objc categories also - if (!categorySym->getName().starts_with(objc::symbol_names::category)) - continue; - - auto *catBodyIsec = dyn_cast(categorySym->isec); - assert(catBodyIsec && - "Category data section is not an ConcatInputSection"); - - // Check that the category has a reloc at 'klassOffset' (which is - // a pointer to the class symbol) - - Symbol *classSym = - tryGetSymbolAtIsecOffset(catBodyIsec, catLayout.klassOffset); - assert(classSym && "Category does not have a valid base class"); - - InfoInputCategory catInputInfo{catListCisec, catBodyIsec, off}; - categoryMap[classSym].push_back(catInputInfo); - - collectCategoryWriterInfoFromCategory(catInputInfo); - } - } -} - -// In the input we have multiple __objc_catlist InputSection, each of which may -// contain links to multiple categories. Of these categories, we will merge (and -// erase) only some. There will be some categories that will remain untouched -// (not erased). For these not erased categories, we generate new __objc_catlist -// entries since the parent __objc_catlist entry will be erased -void ObjcCategoryMerger::generateCatListForNonErasedCategories( - const std::map> - catListToErasedOffsets) { - - // Go through all offsets of all __objc_catlist's that we process and if there - // are categories that we didn't process - generate a new __objc_catlist for - // each. - for (auto &mapEntry : catListToErasedOffsets) { - ConcatInputSection *catListIsec = mapEntry.first; - for (uint32_t catListIsecOffset = 0; - catListIsecOffset < catListIsec->data.size(); - catListIsecOffset += target->wordSize) { - // This slot was erased, we can just skip it - if (mapEntry.second.count(catListIsecOffset)) - continue; - - Defined *nonErasedCatBody = - tryGetDefinedAtIsecOffset(catListIsec, catListIsecOffset); - assert(nonErasedCatBody && "Failed to relocate non-deleted category"); - - // Allocate data for the new __objc_catlist slot - auto bodyData = newSectionData(target->wordSize); - - // We mark the __objc_catlist slot as belonging to the same file as the - // category - ObjFile *objFile = dyn_cast(nonErasedCatBody->getFile()); - - ConcatInputSection *listSec = make( - *infoCategoryWriter.catListInfo.inputSection, bodyData, - infoCategoryWriter.catListInfo.align); - listSec->parent = infoCategoryWriter.catListInfo.outputSection; - listSec->live = true; - allInputSections.push_back(listSec); - - std::string slotSymName = "<__objc_catlist slot for category "; - slotSymName += nonErasedCatBody->getName(); - slotSymName += ">"; - - Defined *catListSlotSym = make( - newStringData(slotSymName.c_str()), /*file=*/objFile, listSec, - /*value=*/0, bodyData.size(), - /*isWeakDef=*/false, /*isExternal=*/false, /*isPrivateExtern=*/false, - /*includeInSymtab=*/false, /*isReferencedDynamically=*/false, - /*noDeadStrip=*/false, /*isWeakDefCanBeHidden=*/false); - - catListSlotSym->used = true; - objFile->symbols.push_back(catListSlotSym); - - // Now link the category body into the newly created slot - createSymbolReference(catListSlotSym, nonErasedCatBody, 0, - infoCategoryWriter.catListInfo.relocTemplate); - } - } -} - -void ObjcCategoryMerger::eraseISec(ConcatInputSection *isec) { - isec->live = false; - for (auto &sym : isec->symbols) - sym->used = false; -} - -// This fully erases the merged categories, including their body, their names, -// their method/protocol/prop lists and the __objc_catlist entries that link to -// them. -void ObjcCategoryMerger::eraseMergedCategories() { - // Map of InputSection to a set of offsets of the categories that were merged - std::map> catListToErasedOffsets; - - for (auto &mapEntry : categoryMap) { - for (InfoInputCategory &catInfo : mapEntry.second) { - if (catInfo.wasMerged) { - eraseISec(catInfo.catListIsec); - catListToErasedOffsets[catInfo.catListIsec].insert( - catInfo.offCatListIsec); - } - } - } - - // If there were categories that we did not erase, we need to generate a new - // __objc_catList that contains only the un-merged categories, and get rid of - // the references to the ones we merged. - generateCatListForNonErasedCategories(catListToErasedOffsets); - - // Erase the old method lists & names of the categories that were merged - for (auto &mapEntry : categoryMap) { - for (InfoInputCategory &catInfo : mapEntry.second) { - if (!catInfo.wasMerged) - continue; - - eraseISec(catInfo.catBodyIsec); - tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset); - tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, - catLayout.instanceMethodsOffset); - tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, - catLayout.classMethodsOffset); - tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, - catLayout.protocolsOffset); - tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, - catLayout.classPropsOffset); - tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, - catLayout.instancePropsOffset); - } - } -} - -void ObjcCategoryMerger::doMerge() { - collectAndValidateCategoriesData(); - - for (auto &entry : categoryMap) - if (entry.second.size() > 1) - // Merge all categories into a new, single category - mergeCategoriesIntoSingleCategory(entry.second); - - // Erase all categories that were merged - eraseMergedCategories(); -} - -void ObjcCategoryMerger::doCleanup() { generatedSectionData.clear(); } - -StringRef ObjcCategoryMerger::newStringData(const char *str) { - uint32_t len = strlen(str); - auto &data = newSectionData(len + 1); - char *strData = reinterpret_cast(data.data()); - strncpy(strData, str, len); - return StringRef(strData, len); -} - -SmallVector &ObjcCategoryMerger::newSectionData(uint32_t size) { - generatedSectionData.push_back(SmallVector(size, 0)); - return generatedSectionData.back(); -} - -} // namespace - -void objc::mergeCategories() { - TimeTraceScope timeScope("ObjcCategoryMerger"); - - ObjcCategoryMerger merger(inputSections); - merger.doMerge(); -} - -void objc::doCleanup() { ObjcCategoryMerger::doCleanup(); } diff --git a/lld/MachO/ObjC.h b/lld/MachO/ObjC.h index 9fbe984e6223..4c65f9a1f788 100644 --- a/lld/MachO/ObjC.h +++ b/lld/MachO/ObjC.h @@ -17,26 +17,14 @@ namespace objc { namespace symbol_names { constexpr const char klass[] = "_OBJC_CLASS_$_"; -constexpr const char klassPropList[] = "__OBJC_$_CLASS_PROP_LIST_"; - constexpr const char metaclass[] = "_OBJC_METACLASS_$_"; constexpr const char ehtype[] = "_OBJC_EHTYPE_$_"; constexpr const char ivar[] = "_OBJC_IVAR_$_"; -constexpr const char listProprieties[] = "__OBJC_$_PROP_LIST_"; - -constexpr const char category[] = "__OBJC_$_CATEGORY_"; -constexpr const char categoryInstanceMethods[] = - "__OBJC_$_CATEGORY_INSTANCE_METHODS_"; -constexpr const char categoryClassMethods[] = - "__OBJC_$_CATEGORY_CLASS_METHODS_"; -constexpr const char categoryProtocols[] = "__OBJC_CATEGORY_PROTOCOLS_$_"; } // namespace symbol_names // Check for duplicate method names within related categories / classes. void checkCategories(); -void mergeCategories(); -void doCleanup(); } // namespace objc bool hasObjCSection(llvm::MemoryBufferRef); diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index 0d8ee2a0926b..a524e4a4c508 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -129,12 +129,6 @@ def strict_auto_link : Flag<["--"], "strict-auto-link">, def check_category_conflicts : Flag<["--"], "check-category-conflicts">, HelpText<"Check for conflicts between category & class methods">, Group; -def objc_category_merging : Flag<["-"], "objc_category_merging">, - HelpText<"Merge Objective-C categories that share the same base class">, - Group; -def no_objc_category_merging : Flag<["-"], "no_objc_category_merging">, - HelpText<"Do not merge Objective-C categories">, - Group; def lto_debug_pass_manager: Flag<["--"], "lto-debug-pass-manager">, HelpText<"Debug new pass manager">, Group; def cs_profile_generate: Flag<["--"], "cs-profile-generate">, @@ -972,6 +966,10 @@ def interposable_list : Separate<["-"], "interposable_list">, def no_function_starts : Flag<["-"], "no_function_starts">, HelpText<"Do not create table of function start addresses">, Group; +def no_objc_category_merging : Flag<["-"], "no_objc_category_merging">, + HelpText<"Do not merge Objective-C categories into their classes">, + Flags<[HelpHidden]>, + Group; def object_path_lto : Separate<["-"], "object_path_lto">, MetaVarName<"">, HelpText<"Retain any temporary mach-o file in that would otherwise be deleted during LTO">, diff --git a/lld/test/MachO/objc-category-merging-complete-test.s b/lld/test/MachO/objc-category-merging-complete-test.s deleted file mode 100644 index 3bc3ca26b6ae..000000000000 --- a/lld/test/MachO/objc-category-merging-complete-test.s +++ /dev/null @@ -1,762 +0,0 @@ -# REQUIRES: aarch64 -# RUN: rm -rf %t; split-file %s %t && cd %t - -## Create a dylib to link against(a64_file1.dylib) and merge categories in the main binary (file2_merge_a64.exe) -# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_file1.o a64_file1.s -# RUN: %lld -arch arm64 a64_file1.o -o a64_file1.dylib -dylib - -# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_file2.o a64_file2.s -# RUN: %lld -arch arm64 -o a64_file2_no_merge.exe a64_file1.dylib a64_file2.o -# RUN: %lld -arch arm64 -o a64_file2_merge.exe -objc_category_merging a64_file1.dylib a64_file2.o - -# RUN: llvm-objdump --objc-meta-data --macho a64_file2_no_merge.exe | FileCheck %s --check-prefixes=NO_MERGE_CATS -# RUN: llvm-objdump --objc-meta-data --macho a64_file2_merge.exe | FileCheck %s --check-prefixes=MERGE_CATS - - -MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_(Category02|Category03) -MERGE_CATS-NEXT: name {{.*}} Category02|Category03 -MERGE_CATS: instanceMethods -MERGE_CATS-NEXT: entsize 24 -MERGE_CATS-NEXT: count 4 -MERGE_CATS-NEXT: name {{.*}} class02InstanceMethod -MERGE_CATS-NEXT: types {{.*}} v16@0:8 -MERGE_CATS-NEXT: imp -[MyBaseClass(Category02) class02InstanceMethod] -MERGE_CATS-NEXT: name {{.*}} myProtocol02Method -MERGE_CATS-NEXT: types {{.*}} v16@0:8 -MERGE_CATS-NEXT: imp -[MyBaseClass(Category02) myProtocol02Method] -MERGE_CATS-NEXT: name {{.*}} class03InstanceMethod -MERGE_CATS-NEXT: types {{.*}} v16@0:8 -MERGE_CATS-NEXT: imp -[MyBaseClass(Category03) class03InstanceMethod] -MERGE_CATS-NEXT: name {{.*}} myProtocol03Method -MERGE_CATS-NEXT: types {{.*}} v16@0:8 -MERGE_CATS-NEXT: imp -[MyBaseClass(Category03) myProtocol03Method] -MERGE_CATS-NEXT: classMethods {{.*}} -MERGE_CATS-NEXT: entsize 24 -MERGE_CATS-NEXT: count 4 -MERGE_CATS-NEXT: name {{.*}} class02ClassMethod -MERGE_CATS-NEXT: types {{.*}} v16@0:8 -MERGE_CATS-NEXT: imp +[MyBaseClass(Category02) class02ClassMethod] -MERGE_CATS-NEXT: name {{.*}} MyProtocol02Prop -MERGE_CATS-NEXT: types {{.*}} i16@0:8 -MERGE_CATS-NEXT: imp +[MyBaseClass(Category02) MyProtocol02Prop] -MERGE_CATS-NEXT: name {{.*}} class03ClassMethod -MERGE_CATS-NEXT: types {{.*}} v16@0:8 -MERGE_CATS-NEXT: imp +[MyBaseClass(Category03) class03ClassMethod] -MERGE_CATS-NEXT: name {{.*}} MyProtocol03Prop -MERGE_CATS-NEXT: types {{.*}} i16@0:8 -MERGE_CATS-NEXT: imp +[MyBaseClass(Category03) MyProtocol03Prop] -MERGE_CATS-NEXT: protocols -MERGE_CATS-NEXT: count 2 -MERGE_CATS-NEXT: list[0] {{.*}} (struct protocol_t *) -MERGE_CATS-NEXT: isa 0x0 -MERGE_CATS-NEXT: name {{.*}} MyProtocol02 -MERGE_CATS-NEXT: protocols 0x0 -MERGE_CATS-NEXT: instanceMethods -MERGE_CATS-NEXT: entsize 24 -MERGE_CATS-NEXT: count 2 -MERGE_CATS-NEXT: name {{.*}} myProtocol02Method -MERGE_CATS-NEXT: types {{.*}} v16@0:8 -MERGE_CATS-NEXT: imp 0x0 -MERGE_CATS-NEXT: name {{.*}} MyProtocol02Prop -MERGE_CATS-NEXT: types {{.*}} i16@0:8 -MERGE_CATS-NEXT: imp 0x0 -MERGE_CATS-NEXT: classMethods -MERGE_CATS-NEXT: optionalInstanceMethods 0x0 -MERGE_CATS-NEXT: optionalClassMethods 0x0 -MERGE_CATS-NEXT: instanceProperties {{.*}} -MERGE_CATS-NEXT: list[1] {{.*}} -MERGE_CATS-NEXT: isa 0x0 -MERGE_CATS-NEXT: name {{.*}} MyProtocol03 -MERGE_CATS-NEXT: protocols 0x0 -MERGE_CATS-NEXT: instanceMethods -MERGE_CATS-NEXT: entsize 24 -MERGE_CATS-NEXT: count 2 -MERGE_CATS-NEXT: name {{.*}} myProtocol03Method -MERGE_CATS-NEXT: types {{.*}} v16@0:8 -MERGE_CATS-NEXT: imp 0x0 -MERGE_CATS-NEXT: name {{.*}} MyProtocol03Prop -MERGE_CATS-NEXT: types {{.*}} i16@0:8 -MERGE_CATS-NEXT: imp 0x0 -MERGE_CATS-NEXT: classMethods 0x0 -MERGE_CATS-NEXT: optionalInstanceMethods 0x0 -MERGE_CATS-NEXT: optionalClassMethods 0x0 -MERGE_CATS-NEXT: instanceProperties {{.*}} -MERGE_CATS-NEXT: instanceProperties -MERGE_CATS-NEXT: entsize 16 -MERGE_CATS-NEXT: count 2 -MERGE_CATS-NEXT: name {{.*}} MyProtocol02Prop -MERGE_CATS-NEXT: attributes {{.*}} Ti,R,D -MERGE_CATS-NEXT: name {{.*}} MyProtocol03Prop -MERGE_CATS-NEXT: attributes {{.*}} Ti,R,D - - -NO_MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_(Category02|Category03) -NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category02 -NO_MERGE_CATS: instanceMethods -NO_MERGE_CATS-NEXT: 24 -NO_MERGE_CATS-NEXT: 2 -NO_MERGE_CATS: classMethods -NO_MERGE_CATS-NEXT: 24 -NO_MERGE_CATS-NEXT: 2 - - -#--- a64_file1.s - -## @protocol MyProtocol01 -## - (void)myProtocol01Method; -## @property (nonatomic) int MyProtocol01Prop; -## @end -## -## __attribute__((objc_root_class)) -## @interface MyBaseClass -## - (void)baseInstanceMethod; -## - (void)myProtocol01Method; -## + (void)baseClassMethod; -## @end -## -## @implementation MyBaseClass -## @synthesize MyProtocol01Prop; -## - (void)baseInstanceMethod {} -## - (void)myProtocol01Method {} -## + (void)baseClassMethod {} -## @end -## -## void *_objc_empty_cache; - - .section __TEXT,__text,regular,pure_instructions - .p2align 2 ; -- Begin function -[MyBaseClass baseInstanceMethod] -"-[MyBaseClass baseInstanceMethod]": ; @"\01-[MyBaseClass baseInstanceMethod]" - .cfi_startproc -; %bb.0: ; %entry - ret - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function -[MyBaseClass myProtocol01Method] -"-[MyBaseClass myProtocol01Method]": ; @"\01-[MyBaseClass myProtocol01Method]" - .cfi_startproc -; %bb.0: ; %entry - ret - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function +[MyBaseClass baseClassMethod] -"+[MyBaseClass baseClassMethod]": ; @"\01+[MyBaseClass baseClassMethod]" - .cfi_startproc -; %bb.0: ; %entry - ret - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function -[MyBaseClass MyProtocol01Prop] -"-[MyBaseClass MyProtocol01Prop]": ; @"\01-[MyBaseClass MyProtocol01Prop]" - .cfi_startproc -; %bb.0: ; %entry -Lloh0: - adrp x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGE -Lloh1: - ldrsw x8, [x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGEOFF] - ldr w0, [x0, x8] - ret - .loh AdrpLdr Lloh0, Lloh1 - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function -[MyBaseClass setMyProtocol01Prop:] -"-[MyBaseClass setMyProtocol01Prop:]": ; @"\01-[MyBaseClass setMyProtocol01Prop:]" - .cfi_startproc -; %bb.0: ; %entry -Lloh2: - adrp x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGE -Lloh3: - ldrsw x8, [x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGEOFF] - str w2, [x0, x8] - ret - .loh AdrpLdr Lloh2, Lloh3 - .cfi_endproc - ; -- End function - .private_extern _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop ; @"OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop" - .section __DATA,__objc_ivar - .globl _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop - .p2align 2, 0x0 -_OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop: - .long 0 ; 0x0 - .section __DATA,__objc_data - .globl _OBJC_CLASS_$_MyBaseClass ; @"OBJC_CLASS_$_MyBaseClass" - .p2align 3, 0x0 -_OBJC_CLASS_$_MyBaseClass: - .quad _OBJC_METACLASS_$_MyBaseClass - .quad 0 - .quad __objc_empty_cache - .quad 0 - .quad __OBJC_CLASS_RO_$_MyBaseClass - .globl _OBJC_METACLASS_$_MyBaseClass ; @"OBJC_METACLASS_$_MyBaseClass" - .p2align 3, 0x0 -_OBJC_METACLASS_$_MyBaseClass: - .quad _OBJC_METACLASS_$_MyBaseClass - .quad _OBJC_CLASS_$_MyBaseClass - .quad __objc_empty_cache - .quad 0 - .quad __OBJC_METACLASS_RO_$_MyBaseClass - .section __TEXT,__objc_classname,cstring_literals -l_OBJC_CLASS_NAME_: ; @OBJC_CLASS_NAME_ - .asciz "MyBaseClass" - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_METH_VAR_NAME_: ; @OBJC_METH_VAR_NAME_ - .asciz "baseClassMethod" - .section __TEXT,__objc_methtype,cstring_literals -l_OBJC_METH_VAR_TYPE_: ; @OBJC_METH_VAR_TYPE_ - .asciz "v16@0:8" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_CLASS_METHODS_MyBaseClass" -__OBJC_$_CLASS_METHODS_MyBaseClass: - .long 24 ; 0x18 - .long 1 ; 0x1 - .quad l_OBJC_METH_VAR_NAME_ - .quad l_OBJC_METH_VAR_TYPE_ - .quad "+[MyBaseClass baseClassMethod]" - .section __TEXT,__objc_classname,cstring_literals -l_OBJC_CLASS_NAME_.1: ; @OBJC_CLASS_NAME_.1 - .asciz "MyProtocol01" - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_METH_VAR_NAME_.2: ; @OBJC_METH_VAR_NAME_.2 - .asciz "myProtocol01Method" -l_OBJC_METH_VAR_NAME_.3: ; @OBJC_METH_VAR_NAME_.3 - .asciz "MyProtocol01Prop" - .section __TEXT,__objc_methtype,cstring_literals -l_OBJC_METH_VAR_TYPE_.4: ; @OBJC_METH_VAR_TYPE_.4 - .asciz "i16@0:8" - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_METH_VAR_NAME_.5: ; @OBJC_METH_VAR_NAME_.5 - .asciz "setMyProtocol01Prop:" - .section __TEXT,__objc_methtype,cstring_literals -l_OBJC_METH_VAR_TYPE_.6: ; @OBJC_METH_VAR_TYPE_.6 - .asciz "v20@0:8i16" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol01" -__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol01: - .long 24 ; 0x18 - .long 3 ; 0x3 - .quad l_OBJC_METH_VAR_NAME_.2 - .quad l_OBJC_METH_VAR_TYPE_ - .quad 0 - .quad l_OBJC_METH_VAR_NAME_.3 - .quad l_OBJC_METH_VAR_TYPE_.4 - .quad 0 - .quad l_OBJC_METH_VAR_NAME_.5 - .quad l_OBJC_METH_VAR_TYPE_.6 - .quad 0 - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_PROP_NAME_ATTR_: ; @OBJC_PROP_NAME_ATTR_ - .asciz "MyProtocol01Prop" -l_OBJC_PROP_NAME_ATTR_.7: ; @OBJC_PROP_NAME_ATTR_.7 - .asciz "Ti,N" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyProtocol01" -__OBJC_$_PROP_LIST_MyProtocol01: - .long 16 ; 0x10 - .long 1 ; 0x1 - .quad l_OBJC_PROP_NAME_ATTR_ - .quad l_OBJC_PROP_NAME_ATTR_.7 - .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol01" -__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol01: - .quad l_OBJC_METH_VAR_TYPE_ - .quad l_OBJC_METH_VAR_TYPE_.4 - .quad l_OBJC_METH_VAR_TYPE_.6 - .private_extern __OBJC_PROTOCOL_$_MyProtocol01 ; @"_OBJC_PROTOCOL_$_MyProtocol01" - .section __DATA,__data - .globl __OBJC_PROTOCOL_$_MyProtocol01 - .weak_definition __OBJC_PROTOCOL_$_MyProtocol01 - .p2align 3, 0x0 -__OBJC_PROTOCOL_$_MyProtocol01: - .quad 0 - .quad l_OBJC_CLASS_NAME_.1 - .quad 0 - .quad __OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol01 - .quad 0 - .quad 0 - .quad 0 - .quad __OBJC_$_PROP_LIST_MyProtocol01 - .long 96 ; 0x60 - .long 0 ; 0x0 - .quad __OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol01 - .quad 0 - .quad 0 - .private_extern __OBJC_LABEL_PROTOCOL_$_MyProtocol01 ; @"_OBJC_LABEL_PROTOCOL_$_MyProtocol01" - .section __DATA,__objc_protolist,coalesced,no_dead_strip - .globl __OBJC_LABEL_PROTOCOL_$_MyProtocol01 - .weak_definition __OBJC_LABEL_PROTOCOL_$_MyProtocol01 - .p2align 3, 0x0 -__OBJC_LABEL_PROTOCOL_$_MyProtocol01: - .quad __OBJC_PROTOCOL_$_MyProtocol01 - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_CLASS_PROTOCOLS_$_MyBaseClass" -__OBJC_CLASS_PROTOCOLS_$_MyBaseClass: - .quad 1 ; 0x1 - .quad __OBJC_PROTOCOL_$_MyProtocol01 - .quad 0 - .p2align 3, 0x0 ; @"_OBJC_METACLASS_RO_$_MyBaseClass" -__OBJC_METACLASS_RO_$_MyBaseClass: - .long 3 ; 0x3 - .long 40 ; 0x28 - .long 40 ; 0x28 - .space 4 - .quad 0 - .quad l_OBJC_CLASS_NAME_ - .quad __OBJC_$_CLASS_METHODS_MyBaseClass - .quad __OBJC_CLASS_PROTOCOLS_$_MyBaseClass - .quad 0 - .quad 0 - .quad 0 - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_METH_VAR_NAME_.8: ; @OBJC_METH_VAR_NAME_.8 - .asciz "baseInstanceMethod" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_INSTANCE_METHODS_MyBaseClass" -__OBJC_$_INSTANCE_METHODS_MyBaseClass: - .long 24 ; 0x18 - .long 4 ; 0x4 - .quad l_OBJC_METH_VAR_NAME_.8 - .quad l_OBJC_METH_VAR_TYPE_ - .quad "-[MyBaseClass baseInstanceMethod]" - .quad l_OBJC_METH_VAR_NAME_.2 - .quad l_OBJC_METH_VAR_TYPE_ - .quad "-[MyBaseClass myProtocol01Method]" - .quad l_OBJC_METH_VAR_NAME_.3 - .quad l_OBJC_METH_VAR_TYPE_.4 - .quad "-[MyBaseClass MyProtocol01Prop]" - .quad l_OBJC_METH_VAR_NAME_.5 - .quad l_OBJC_METH_VAR_TYPE_.6 - .quad "-[MyBaseClass setMyProtocol01Prop:]" - .section __TEXT,__objc_methtype,cstring_literals -l_OBJC_METH_VAR_TYPE_.9: ; @OBJC_METH_VAR_TYPE_.9 - .asciz "i" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_INSTANCE_VARIABLES_MyBaseClass" -__OBJC_$_INSTANCE_VARIABLES_MyBaseClass: - .long 32 ; 0x20 - .long 1 ; 0x1 - .quad _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop - .quad l_OBJC_METH_VAR_NAME_.3 - .quad l_OBJC_METH_VAR_TYPE_.9 - .long 2 ; 0x2 - .long 4 ; 0x4 - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_PROP_NAME_ATTR_.10: ; @OBJC_PROP_NAME_ATTR_.10 - .asciz "Ti,N,VMyProtocol01Prop" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyBaseClass" -__OBJC_$_PROP_LIST_MyBaseClass: - .long 16 ; 0x10 - .long 1 ; 0x1 - .quad l_OBJC_PROP_NAME_ATTR_ - .quad l_OBJC_PROP_NAME_ATTR_.10 - .p2align 3, 0x0 ; @"_OBJC_CLASS_RO_$_MyBaseClass" -__OBJC_CLASS_RO_$_MyBaseClass: - .long 2 ; 0x2 - .long 0 ; 0x0 - .long 4 ; 0x4 - .space 4 - .quad 0 - .quad l_OBJC_CLASS_NAME_ - .quad __OBJC_$_INSTANCE_METHODS_MyBaseClass - .quad __OBJC_CLASS_PROTOCOLS_$_MyBaseClass - .quad __OBJC_$_INSTANCE_VARIABLES_MyBaseClass - .quad 0 - .quad __OBJC_$_PROP_LIST_MyBaseClass - .globl __objc_empty_cache ; @_objc_empty_cache -.zerofill __DATA,__common,__objc_empty_cache,8,3 - .section __DATA,__objc_classlist,regular,no_dead_strip - .p2align 3, 0x0 ; @"OBJC_LABEL_CLASS_$" -l_OBJC_LABEL_CLASS_$: - .quad _OBJC_CLASS_$_MyBaseClass - .no_dead_strip __OBJC_LABEL_PROTOCOL_$_MyProtocol01 - .no_dead_strip __OBJC_PROTOCOL_$_MyProtocol01 - .section __DATA,__objc_imageinfo,regular,no_dead_strip -L_OBJC_IMAGE_INFO: - .long 0 - .long 96 -.subsections_via_symbols - - -#--- a64_file2.s - -## @protocol MyProtocol01 -## - (void)myProtocol01Method; -## @end -## -## @protocol MyProtocol02 -## - (void)myProtocol02Method; -## @property(readonly) int MyProtocol02Prop; -## @end -## -## @protocol MyProtocol03 -## - (void)myProtocol03Method; -## @property(readonly) int MyProtocol03Prop; -## @end -## -## -## __attribute__((objc_root_class)) -## @interface MyBaseClass -## - (void)baseInstanceMethod; -## - (void)myProtocol01Method; -## + (void)baseClassMethod; -## @end -## -## -## -## @interface MyBaseClass(Category02) -## - (void)class02InstanceMethod; -## - (void)myProtocol02Method; -## + (void)class02ClassMethod; -## + (int)MyProtocol02Prop; -## @end -## -## @implementation MyBaseClass(Category02) -## - (void)class02InstanceMethod {} -## - (void)myProtocol02Method {} -## + (void)class02ClassMethod {} -## + (int)MyProtocol02Prop { return 0;} -## @dynamic MyProtocol02Prop; -## @end -## -## @interface MyBaseClass(Category03) -## - (void)class03InstanceMethod; -## - (void)myProtocol03Method; -## + (void)class03ClassMethod; -## + (int)MyProtocol03Prop; -## @end -## -## @implementation MyBaseClass(Category03) -## - (void)class03InstanceMethod {} -## - (void)myProtocol03Method {} -## + (void)class03ClassMethod {} -## + (int)MyProtocol03Prop { return 0;} -## @dynamic MyProtocol03Prop; -## @end -## -## int main() { -## return 0; -## } - - - .section __TEXT,__text,regular,pure_instructions - .p2align 2 ; -- Begin function -[MyBaseClass(Category02) class02InstanceMethod] -"-[MyBaseClass(Category02) class02InstanceMethod]": ; @"\01-[MyBaseClass(Category02) class02InstanceMethod]" - .cfi_startproc -; %bb.0: ; %entry - ret - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function -[MyBaseClass(Category02) myProtocol02Method] -"-[MyBaseClass(Category02) myProtocol02Method]": ; @"\01-[MyBaseClass(Category02) myProtocol02Method]" - .cfi_startproc -; %bb.0: ; %entry - ret - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function +[MyBaseClass(Category02) class02ClassMethod] -"+[MyBaseClass(Category02) class02ClassMethod]": ; @"\01+[MyBaseClass(Category02) class02ClassMethod]" - .cfi_startproc -; %bb.0: ; %entry - ret - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function +[MyBaseClass(Category02) MyProtocol02Prop] -"+[MyBaseClass(Category02) MyProtocol02Prop]": ; @"\01+[MyBaseClass(Category02) MyProtocol02Prop]" - .cfi_startproc -; %bb.0: ; %entry - b _OUTLINED_FUNCTION_0 - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function -[MyBaseClass(Category03) class03InstanceMethod] -"-[MyBaseClass(Category03) class03InstanceMethod]": ; @"\01-[MyBaseClass(Category03) class03InstanceMethod]" - .cfi_startproc -; %bb.0: ; %entry - ret - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function -[MyBaseClass(Category03) myProtocol03Method] -"-[MyBaseClass(Category03) myProtocol03Method]": ; @"\01-[MyBaseClass(Category03) myProtocol03Method]" - .cfi_startproc -; %bb.0: ; %entry - ret - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function +[MyBaseClass(Category03) class03ClassMethod] -"+[MyBaseClass(Category03) class03ClassMethod]": ; @"\01+[MyBaseClass(Category03) class03ClassMethod]" - .cfi_startproc -; %bb.0: ; %entry - ret - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function +[MyBaseClass(Category03) MyProtocol03Prop] -"+[MyBaseClass(Category03) MyProtocol03Prop]": ; @"\01+[MyBaseClass(Category03) MyProtocol03Prop]" - .cfi_startproc -; %bb.0: ; %entry - b _OUTLINED_FUNCTION_0 - .cfi_endproc - ; -- End function - .globl _main ; -- Begin function main - .p2align 2 -_main: ; @main - .cfi_startproc -; %bb.0: ; %entry - b _OUTLINED_FUNCTION_0 - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function OUTLINED_FUNCTION_0 -_OUTLINED_FUNCTION_0: ; @OUTLINED_FUNCTION_0 Tail Call - .cfi_startproc -; %bb.0: - mov w0, #0 - ret - .cfi_endproc - ; -- End function - .section __TEXT,__objc_classname,cstring_literals -l_OBJC_CLASS_NAME_: ; @OBJC_CLASS_NAME_ - .asciz "Category02" - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_METH_VAR_NAME_: ; @OBJC_METH_VAR_NAME_ - .asciz "class02InstanceMethod" - .section __TEXT,__objc_methtype,cstring_literals -l_OBJC_METH_VAR_TYPE_: ; @OBJC_METH_VAR_TYPE_ - .asciz "v16@0:8" - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_METH_VAR_NAME_.1: ; @OBJC_METH_VAR_NAME_.1 - .asciz "myProtocol02Method" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02" -__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02: - .long 24 ; 0x18 - .long 2 ; 0x2 - .quad l_OBJC_METH_VAR_NAME_ - .quad l_OBJC_METH_VAR_TYPE_ - .quad "-[MyBaseClass(Category02) class02InstanceMethod]" - .quad l_OBJC_METH_VAR_NAME_.1 - .quad l_OBJC_METH_VAR_TYPE_ - .quad "-[MyBaseClass(Category02) myProtocol02Method]" - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_METH_VAR_NAME_.2: ; @OBJC_METH_VAR_NAME_.2 - .asciz "class02ClassMethod" -l_OBJC_METH_VAR_NAME_.3: ; @OBJC_METH_VAR_NAME_.3 - .asciz "MyProtocol02Prop" - .section __TEXT,__objc_methtype,cstring_literals -l_OBJC_METH_VAR_TYPE_.4: ; @OBJC_METH_VAR_TYPE_.4 - .asciz "i16@0:8" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category02" -__OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category02: - .long 24 ; 0x18 - .long 2 ; 0x2 - .quad l_OBJC_METH_VAR_NAME_.2 - .quad l_OBJC_METH_VAR_TYPE_ - .quad "+[MyBaseClass(Category02) class02ClassMethod]" - .quad l_OBJC_METH_VAR_NAME_.3 - .quad l_OBJC_METH_VAR_TYPE_.4 - .quad "+[MyBaseClass(Category02) MyProtocol02Prop]" - .section __TEXT,__objc_classname,cstring_literals -l_OBJC_CLASS_NAME_.5: ; @OBJC_CLASS_NAME_.5 - .asciz "MyProtocol02" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol02" -__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol02: - .long 24 ; 0x18 - .long 2 ; 0x2 - .quad l_OBJC_METH_VAR_NAME_.1 - .quad l_OBJC_METH_VAR_TYPE_ - .quad 0 - .quad l_OBJC_METH_VAR_NAME_.3 - .quad l_OBJC_METH_VAR_TYPE_.4 - .quad 0 - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_PROP_NAME_ATTR_: ; @OBJC_PROP_NAME_ATTR_ - .asciz "MyProtocol02Prop" -l_OBJC_PROP_NAME_ATTR_.6: ; @OBJC_PROP_NAME_ATTR_.6 - .asciz "Ti,R" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyProtocol02" -__OBJC_$_PROP_LIST_MyProtocol02: - .long 16 ; 0x10 - .long 1 ; 0x1 - .quad l_OBJC_PROP_NAME_ATTR_ - .quad l_OBJC_PROP_NAME_ATTR_.6 - .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol02" -__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol02: - .quad l_OBJC_METH_VAR_TYPE_ - .quad l_OBJC_METH_VAR_TYPE_.4 - .private_extern __OBJC_PROTOCOL_$_MyProtocol02 ; @"_OBJC_PROTOCOL_$_MyProtocol02" - .section __DATA,__data - .globl __OBJC_PROTOCOL_$_MyProtocol02 - .weak_definition __OBJC_PROTOCOL_$_MyProtocol02 - .p2align 3, 0x0 -__OBJC_PROTOCOL_$_MyProtocol02: - .quad 0 - .quad l_OBJC_CLASS_NAME_.5 - .quad 0 - .quad __OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol02 - .quad 0 - .quad 0 - .quad 0 - .quad __OBJC_$_PROP_LIST_MyProtocol02 - .long 96 ; 0x60 - .long 0 ; 0x0 - .quad __OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol02 - .quad 0 - .quad 0 - .private_extern __OBJC_LABEL_PROTOCOL_$_MyProtocol02 ; @"_OBJC_LABEL_PROTOCOL_$_MyProtocol02" - .section __DATA,__objc_protolist,coalesced,no_dead_strip - .globl __OBJC_LABEL_PROTOCOL_$_MyProtocol02 - .weak_definition __OBJC_LABEL_PROTOCOL_$_MyProtocol02 - .p2align 3, 0x0 -__OBJC_LABEL_PROTOCOL_$_MyProtocol02: - .quad __OBJC_PROTOCOL_$_MyProtocol02 - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category02" -__OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category02: - .quad 1 ; 0x1 - .quad __OBJC_PROTOCOL_$_MyProtocol02 - .quad 0 - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_PROP_NAME_ATTR_.7: ; @OBJC_PROP_NAME_ATTR_.7 - .asciz "Ti,R,D" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyBaseClass_$_Category02" -__OBJC_$_PROP_LIST_MyBaseClass_$_Category02: - .long 16 ; 0x10 - .long 1 ; 0x1 - .quad l_OBJC_PROP_NAME_ATTR_ - .quad l_OBJC_PROP_NAME_ATTR_.7 - .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category02" -__OBJC_$_CATEGORY_MyBaseClass_$_Category02: - .quad l_OBJC_CLASS_NAME_ - .quad _OBJC_CLASS_$_MyBaseClass - .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02 - .quad __OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category02 - .quad __OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category02 - .quad __OBJC_$_PROP_LIST_MyBaseClass_$_Category02 - .quad 0 - .long 64 ; 0x40 - .space 4 - .section __TEXT,__objc_classname,cstring_literals -l_OBJC_CLASS_NAME_.8: ; @OBJC_CLASS_NAME_.8 - .asciz "Category03" - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_METH_VAR_NAME_.9: ; @OBJC_METH_VAR_NAME_.9 - .asciz "class03InstanceMethod" -l_OBJC_METH_VAR_NAME_.10: ; @OBJC_METH_VAR_NAME_.10 - .asciz "myProtocol03Method" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category03" -__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category03: - .long 24 ; 0x18 - .long 2 ; 0x2 - .quad l_OBJC_METH_VAR_NAME_.9 - .quad l_OBJC_METH_VAR_TYPE_ - .quad "-[MyBaseClass(Category03) class03InstanceMethod]" - .quad l_OBJC_METH_VAR_NAME_.10 - .quad l_OBJC_METH_VAR_TYPE_ - .quad "-[MyBaseClass(Category03) myProtocol03Method]" - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_METH_VAR_NAME_.11: ; @OBJC_METH_VAR_NAME_.11 - .asciz "class03ClassMethod" -l_OBJC_METH_VAR_NAME_.12: ; @OBJC_METH_VAR_NAME_.12 - .asciz "MyProtocol03Prop" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category03" -__OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category03: - .long 24 ; 0x18 - .long 2 ; 0x2 - .quad l_OBJC_METH_VAR_NAME_.11 - .quad l_OBJC_METH_VAR_TYPE_ - .quad "+[MyBaseClass(Category03) class03ClassMethod]" - .quad l_OBJC_METH_VAR_NAME_.12 - .quad l_OBJC_METH_VAR_TYPE_.4 - .quad "+[MyBaseClass(Category03) MyProtocol03Prop]" - .section __TEXT,__objc_classname,cstring_literals -l_OBJC_CLASS_NAME_.13: ; @OBJC_CLASS_NAME_.13 - .asciz "MyProtocol03" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol03" -__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol03: - .long 24 ; 0x18 - .long 2 ; 0x2 - .quad l_OBJC_METH_VAR_NAME_.10 - .quad l_OBJC_METH_VAR_TYPE_ - .quad 0 - .quad l_OBJC_METH_VAR_NAME_.12 - .quad l_OBJC_METH_VAR_TYPE_.4 - .quad 0 - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_PROP_NAME_ATTR_.14: ; @OBJC_PROP_NAME_ATTR_.14 - .asciz "MyProtocol03Prop" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyProtocol03" -__OBJC_$_PROP_LIST_MyProtocol03: - .long 16 ; 0x10 - .long 1 ; 0x1 - .quad l_OBJC_PROP_NAME_ATTR_.14 - .quad l_OBJC_PROP_NAME_ATTR_.6 - .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol03" -__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol03: - .quad l_OBJC_METH_VAR_TYPE_ - .quad l_OBJC_METH_VAR_TYPE_.4 - .private_extern __OBJC_PROTOCOL_$_MyProtocol03 ; @"_OBJC_PROTOCOL_$_MyProtocol03" - .section __DATA,__data - .globl __OBJC_PROTOCOL_$_MyProtocol03 - .weak_definition __OBJC_PROTOCOL_$_MyProtocol03 - .p2align 3, 0x0 -__OBJC_PROTOCOL_$_MyProtocol03: - .quad 0 - .quad l_OBJC_CLASS_NAME_.13 - .quad 0 - .quad __OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol03 - .quad 0 - .quad 0 - .quad 0 - .quad __OBJC_$_PROP_LIST_MyProtocol03 - .long 96 ; 0x60 - .long 0 ; 0x0 - .quad __OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol03 - .quad 0 - .quad 0 - .private_extern __OBJC_LABEL_PROTOCOL_$_MyProtocol03 ; @"_OBJC_LABEL_PROTOCOL_$_MyProtocol03" - .section __DATA,__objc_protolist,coalesced,no_dead_strip - .globl __OBJC_LABEL_PROTOCOL_$_MyProtocol03 - .weak_definition __OBJC_LABEL_PROTOCOL_$_MyProtocol03 - .p2align 3, 0x0 -__OBJC_LABEL_PROTOCOL_$_MyProtocol03: - .quad __OBJC_PROTOCOL_$_MyProtocol03 - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category03" -__OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category03: - .quad 1 ; 0x1 - .quad __OBJC_PROTOCOL_$_MyProtocol03 - .quad 0 - .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyBaseClass_$_Category03" -__OBJC_$_PROP_LIST_MyBaseClass_$_Category03: - .long 16 ; 0x10 - .long 1 ; 0x1 - .quad l_OBJC_PROP_NAME_ATTR_.14 - .quad l_OBJC_PROP_NAME_ATTR_.7 - .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category03" -__OBJC_$_CATEGORY_MyBaseClass_$_Category03: - .quad l_OBJC_CLASS_NAME_.8 - .quad _OBJC_CLASS_$_MyBaseClass - .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category03 - .quad __OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category03 - .quad __OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category03 - .quad __OBJC_$_PROP_LIST_MyBaseClass_$_Category03 - .quad 0 - .long 64 ; 0x40 - .space 4 - .section __DATA,__objc_catlist,regular,no_dead_strip - .p2align 3, 0x0 ; @"OBJC_LABEL_CATEGORY_$" -l_OBJC_LABEL_CATEGORY_$: - .quad __OBJC_$_CATEGORY_MyBaseClass_$_Category02 - .quad __OBJC_$_CATEGORY_MyBaseClass_$_Category03 - .no_dead_strip __OBJC_LABEL_PROTOCOL_$_MyProtocol02 - .no_dead_strip __OBJC_LABEL_PROTOCOL_$_MyProtocol03 - .no_dead_strip __OBJC_PROTOCOL_$_MyProtocol02 - .no_dead_strip __OBJC_PROTOCOL_$_MyProtocol03 - .section __DATA,__objc_imageinfo,regular,no_dead_strip -L_OBJC_IMAGE_INFO: - .long 0 - .long 96 -.subsections_via_symbols diff --git a/lld/test/MachO/objc-category-merging-extern-class-minimal.s b/lld/test/MachO/objc-category-merging-extern-class-minimal.s deleted file mode 100644 index ede7ef5d9c32..000000000000 --- a/lld/test/MachO/objc-category-merging-extern-class-minimal.s +++ /dev/null @@ -1,155 +0,0 @@ -# REQUIRES: aarch64 -# RUN: rm -rf %t; split-file %s %t && cd %t - -## Create a dylib with a fake base class to link against -# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_fakedylib.o a64_fakedylib.s -# RUN: %lld -arch arm64 a64_fakedylib.o -o a64_fakedylib.dylib -dylib - -## Create our main testing dylib - linking against the fake dylib above -# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_cat_minimal.o merge_cat_minimal.s -# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_no_merge.dylib a64_fakedylib.dylib merge_cat_minimal.o -# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_merge.dylib -objc_category_merging a64_fakedylib.dylib merge_cat_minimal.o - -## Now verify that the flag caused category merging to happen appropriatelly -# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_no_merge.dylib | FileCheck %s --check-prefixes=NO_MERGE_CATS -# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_merge.dylib | FileCheck %s --check-prefixes=MERGE_CATS - -#### Check merge categories enabled ### -# Check that the original categories are not there -MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category01 -MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02 - -# Check that the merged cateogry is there, in the correct format -MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_(Category01|Category02) -MERGE_CATS-NEXT: name {{.*}} Category01|Category02 -MERGE_CATS: instanceMethods -MERGE_CATS-NEXT: 24 -MERGE_CATS-NEXT: 2 -MERGE_CATS-NEXT: name {{.*}} cat01_InstanceMethod -MERGE_CATS-NEXT: types {{.*}} v16@0:8 -MERGE_CATS-NEXT: imp -[MyBaseClass(Category01) cat01_InstanceMethod] -MERGE_CATS-NEXT: name {{.*}} cat02_InstanceMethod -MERGE_CATS-NEXT: types {{.*}} v16@0:8 -MERGE_CATS-NEXT: imp -[MyBaseClass(Category02) cat02_InstanceMethod] -MERGE_CATS-NEXT: classMethods 0x0 -MERGE_CATS-NEXT: protocols 0x0 -MERGE_CATS-NEXT: instanceProperties 0x0 - -#### Check merge categories disabled ### -# Check that the merged category is not there -NO_MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_(Category01|Category02) - -# Check that the original categories are there -NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category01 -NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category02 - - - -#--- a64_fakedylib.s - - .section __DATA,__objc_data - .globl _OBJC_CLASS_$_MyBaseClass -_OBJC_CLASS_$_MyBaseClass: - .quad 0 - -#--- merge_cat_minimal.s - -; ================== Generated from ObjC: ================== -; __attribute__((objc_root_class)) -; @interface MyBaseClass -; - (void)baseInstanceMethod; -; @end -; -; @interface MyBaseClass(Category01) -; - (void)cat01_InstanceMethod; -; @end -; -; @implementation MyBaseClass(Category01) -; - (void)cat01_InstanceMethod {} -; @end -; -; @interface MyBaseClass(Category02) -; - (void)cat02_InstanceMethod; -; @end -; -; @implementation MyBaseClass(Category02) -; - (void)cat02_InstanceMethod {} -; @end -; ================== Generated from ObjC: ================== - - .section __TEXT,__text,regular,pure_instructions - .p2align 2 ; -- Begin function -[MyBaseClass(Category01) cat01_InstanceMethod] -"-[MyBaseClass(Category01) cat01_InstanceMethod]": ; @"\01-[MyBaseClass(Category01) cat01_InstanceMethod]" - .cfi_startproc - ret - .cfi_endproc - ; -- End function - .p2align 2 ; -- Begin function -[MyBaseClass(Category02) cat02_InstanceMethod] -"-[MyBaseClass(Category02) cat02_InstanceMethod]": ; @"\01-[MyBaseClass(Category02) cat02_InstanceMethod]" - .cfi_startproc - ret - .cfi_endproc - ; -- End function - .section __TEXT,__objc_classname,cstring_literals -l_OBJC_CLASS_NAME_: ; @OBJC_CLASS_NAME_ - .asciz "Category01" - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_METH_VAR_NAME_: ; @OBJC_METH_VAR_NAME_ - .asciz "cat01_InstanceMethod" - .section __TEXT,__objc_methtype,cstring_literals -l_OBJC_METH_VAR_TYPE_: ; @OBJC_METH_VAR_TYPE_ - .asciz "v16@0:8" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01" -__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01: - .long 24 ; 0x18 - .long 1 ; 0x1 - .quad l_OBJC_METH_VAR_NAME_ - .quad l_OBJC_METH_VAR_TYPE_ - .quad "-[MyBaseClass(Category01) cat01_InstanceMethod]" - .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category01" -__OBJC_$_CATEGORY_MyBaseClass_$_Category01: - .quad l_OBJC_CLASS_NAME_ - .quad _OBJC_CLASS_$_MyBaseClass - .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01 - .quad 0 - .quad 0 - .quad 0 - .quad 0 - .long 64 ; 0x40 - .space 4 - .section __TEXT,__objc_classname,cstring_literals -l_OBJC_CLASS_NAME_.1: ; @OBJC_CLASS_NAME_.1 - .asciz "Category02" - .section __TEXT,__objc_methname,cstring_literals -l_OBJC_METH_VAR_NAME_.2: ; @OBJC_METH_VAR_NAME_.2 - .asciz "cat02_InstanceMethod" - .section __DATA,__objc_const - .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02" -__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02: - .long 24 ; 0x18 - .long 1 ; 0x1 - .quad l_OBJC_METH_VAR_NAME_.2 - .quad l_OBJC_METH_VAR_TYPE_ - .quad "-[MyBaseClass(Category02) cat02_InstanceMethod]" - .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category02" -__OBJC_$_CATEGORY_MyBaseClass_$_Category02: - .quad l_OBJC_CLASS_NAME_.1 - .quad _OBJC_CLASS_$_MyBaseClass - .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02 - .quad 0 - .quad 0 - .quad 0 - .quad 0 - .long 64 ; 0x40 - .space 4 - .section __DATA,__objc_catlist,regular,no_dead_strip - .p2align 3, 0x0 ; @"OBJC_LABEL_CATEGORY_$" -l_OBJC_LABEL_CATEGORY_$: - .quad __OBJC_$_CATEGORY_MyBaseClass_$_Category01 - .quad __OBJC_$_CATEGORY_MyBaseClass_$_Category02 - .section __DATA,__objc_imageinfo,regular,no_dead_strip -L_OBJC_IMAGE_INFO: - .long 0 - .long 96 -.subsections_via_symbols -- GitLab From d66121d74a458e098511b9de920d815440acaa1b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 18 Mar 2024 19:55:34 -0500 Subject: [PATCH 011/307] [WebAssembly] Change the default linker for `wasm32-wasip2` (#84569) This commit changes the default linker in the WebAssembly toolchain for the `wasm32-wasip2` target. This target is being added to the WebAssembly/wasi-sdk and WebAssembly/wasi-libc projects to target the Component Model by default, in contrast with the preexisting `wasm32-wasi` target (in the process of being renamed to `wasm32-wasip1`) which outputs a core WebAssembly module by default. The `wasm-component-ld` project currently lives in my GitHub account at https://github.com/alexcrichton/wasm-component-ld and isn't necessarily "official" yet, but it's expected to continue to evolve as the `wasm32-wasip2` target continues to shape up and evolve. --- clang/lib/Driver/ToolChains/WebAssembly.cpp | 27 +++++++++++++++++++-- clang/lib/Driver/ToolChains/WebAssembly.h | 2 +- clang/test/Driver/wasm-toolchain.c | 24 ++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp index b8c2573d6265..b7c6efab83e8 100644 --- a/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -44,8 +44,15 @@ std::string wasm::Linker::getLinkerPath(const ArgList &Args) const { llvm::sys::fs::can_execute(UseLinker)) return std::string(UseLinker); - // Accept 'lld', and 'ld' as aliases for the default linker - if (UseLinker != "lld" && UseLinker != "ld") + // Interpret 'lld' as explicitly requesting `wasm-ld`, so look for that + // linker. Note that for `wasm32-wasip2` this overrides the default linker + // of `wasm-component-ld`. + if (UseLinker == "lld") { + return ToolChain.GetProgramPath("wasm-ld"); + } + + // Allow 'ld' as an alias for the default linker + if (UseLinker != "ld") ToolChain.getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); } @@ -73,6 +80,16 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_s)) CmdArgs.push_back("--strip-all"); + // On `wasip2` the default linker is `wasm-component-ld` which wraps the + // execution of `wasm-ld`. Find `wasm-ld` and pass it as an argument of where + // to find it to avoid it needing to hunt and rediscover or search `PATH` for + // where it is. + if (llvm::sys::path::stem(Linker).ends_with_insensitive( + "wasm-component-ld")) { + CmdArgs.push_back("--wasm-ld-path"); + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetProgramPath("wasm-ld"))); + } + Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u}); ToolChain.AddFilePathLibArgs(Args, CmdArgs); @@ -221,6 +238,12 @@ WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple, } } +const char *WebAssembly::getDefaultLinker() const { + if (getOS() == "wasip2") + return "wasm-component-ld"; + return "wasm-ld"; +} + bool WebAssembly::IsMathErrnoDefault() const { return false; } bool WebAssembly::IsObjCNonFragileABIDefault() const { return true; } diff --git a/clang/lib/Driver/ToolChains/WebAssembly.h b/clang/lib/Driver/ToolChains/WebAssembly.h index ae60f464c108..76e0ca39bd74 100644 --- a/clang/lib/Driver/ToolChains/WebAssembly.h +++ b/clang/lib/Driver/ToolChains/WebAssembly.h @@ -67,7 +67,7 @@ private: llvm::opt::ArgStringList &CmdArgs) const override; SanitizerMask getSupportedSanitizers() const override; - const char *getDefaultLinker() const override { return "wasm-ld"; } + const char *getDefaultLinker() const override; CXXStdlibType GetDefaultCXXStdlibType() const override { return ToolChain::CST_Libcxx; diff --git a/clang/test/Driver/wasm-toolchain.c b/clang/test/Driver/wasm-toolchain.c index f950283ec42a..88590a3ba4c4 100644 --- a/clang/test/Driver/wasm-toolchain.c +++ b/clang/test/Driver/wasm-toolchain.c @@ -197,3 +197,27 @@ // RUN: not %clang -### %s --target=wasm32-unknown-unknown --sysroot=%s/no-sysroot-there -fPIC -mno-mutable-globals %s 2>&1 \ // RUN: | FileCheck -check-prefix=PIC_NO_MUTABLE_GLOBALS %s // PIC_NO_MUTABLE_GLOBALS: error: invalid argument '-fPIC' not allowed with '-mno-mutable-globals' + +// Test that `wasm32-wasip2` invokes the `wasm-component-ld` linker by default +// instead of `wasm-ld`. + +// RUN: %clang -### -O2 --target=wasm32-wasip2 %s --sysroot /foo 2>&1 \ +// RUN: | FileCheck -check-prefix=LINK_WASIP2 %s +// LINK_WASIP2: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" +// LINK_WASIP2: wasm-component-ld{{.*}}" "-L/foo/lib/wasm32-wasip2" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" + +// Test that on `wasm32-wasip2` the `wasm-component-ld` programs is told where +// to find `wasm-ld` by default. + +// RUN: %clang -### -O2 --target=wasm32-wasip2 %s --sysroot /foo 2>&1 \ +// RUN: | FileCheck -check-prefix=LINK_WASIP2_FIND_WASMLD %s +// LINK_WASIP2_FIND_WASMLD: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" +// LINK_WASIP2_FIND_WASMLD: wasm-component-ld{{.*}}" {{.*}} "--wasm-ld-path" "{{.*}}wasm-ld{{.*}}" {{.*}} "[[temp]]" {{.*}} + +// If `wasm32-wasip2` is configured with `wasm-ld` as a linker then don't pass +// the `--wasm-ld-path` flag. + +// RUN: %clang -### -O2 --target=wasm32-wasip2 -fuse-ld=lld %s --sysroot /foo 2>&1 \ +// RUN: | FileCheck -check-prefix=LINK_WASIP2_USE_WASMLD %s +// LINK_WASIP2_USE_WASMLD: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" +// LINK_WASIP2_USE_WASMLD: wasm-ld{{.*}}" "-m" "wasm32" {{.*}} "[[temp]]" {{.*}} -- GitLab From a629621454838207ca49bcfd773d5aa0671659f1 Mon Sep 17 00:00:00 2001 From: lntue <35648136+lntue@users.noreply.github.com> Date: Mon, 18 Mar 2024 21:10:50 -0400 Subject: [PATCH 012/307] [libc][math] Improve atanf performance. (#85463) Simplify the range reduction logic and computations. Performance test using `perf.sh` from CORE-MATH project on Ryzen 5900X: Before: ``` $ ./perf.sh atanf --rdtsc --path1 LIBC-location: /home/lnt/experiment/llvm-project/build/projects/libc/lib/libllvmlibc.a GNU libc version: 2.35 GNU libc release: stable -- CORE-MATH reciprocal throughput -- [####################] 100 % Ntrial = 20 ; Min = 14.369 + 0.556 clc/call; Median-Min = 0.613 clc/call; Max = 15.061 clc/call; -- System LIBC reciprocal throughput -- [####################] 100 % Ntrial = 20 ; Min = 26.180 + 0.015 clc/call; Median-Min = 0.014 clc/call; Max = 26.260 clc/call; -- LIBC reciprocal throughput -- [####################] 100 % Ntrial = 20 ; Min = 21.237 + 0.022 clc/call; Median-Min = 0.020 clc/call; Max = 21.272 clc/call; $ ./perf.sh atanf --rdtsc --path1 --latency LIBC-location: /home/lnt/experiment/llvm-project/build/projects/libc/lib/libllvmlibc.a GNU libc version: 2.35 GNU libc release: stable -- CORE-MATH latency -- [####################] 100 % Ntrial = 20 ; Min = 50.505 + 0.045 clc/call; Median-Min = 0.037 clc/call; Max = 50.579 clc/call; -- System LIBC latency -- [####################] 100 % Ntrial = 20 ; Min = 62.438 + 0.836 clc/call; Median-Min = 0.049 clc/call; Max = 64.498 clc/call; -- LIBC latency -- [####################] 100 % Ntrial = 20 ; Min = 67.781 + 0.546 clc/call; Median-Min = 0.028 clc/call; Max = 68.844 clc/call; ``` After: ``` $ ./perf.sh atanf --rdtsc --path2 LIBC-location: /home/lnt/experiment/llvm/llvm-project/build/projects/libc/lib/libllvmlibc.a GNU libc version: 2.35 GNU libc release: stable -- CORE-MATH reciprocal throughput -- [####################] 100 % Ntrial = 20 ; Min = 14.400 + 0.353 clc/call; Median-Min = 0.404 clc/call; Max = 14.863 clc/call; -- System LIBC reciprocal throughput -- [####################] 100 % Ntrial = 20 ; Min = 25.247 + 0.783 clc/call; Median-Min = 0.714 clc/call; Max = 26.238 clc/call; -- LIBC reciprocal throughput -- [####################] 100 % Ntrial = 20 ; Min = 13.751 + 0.158 clc/call; Median-Min = 0.140 clc/call; Max = 14.006 clc/call; $ ./perf.sh atanf --rdtsc --path2 --latency LIBC-location: /home/lnt/experiment/llvm/llvm-project/build/projects/libc/lib/libllvmlibc.a GNU libc version: 2.35 GNU libc release: stable -- CORE-MATH latency -- [####################] 100 % Ntrial = 20 ; Min = 51.837 + 0.073 clc/call; Median-Min = 0.058 clc/call; Max = 52.000 clc/call; -- System LIBC latency -- [####################] 100 % Ntrial = 20 ; Min = 62.487 + 1.878 clc/call; Median-Min = 1.965 clc/call; Max = 64.569 clc/call; OK -- LIBC latency -- [####################] 100 % Ntrial = 20 ; Min = 55.414 + 1.312 clc/call; Median-Min = 0.345 clc/call; Max = 58.362 clc/call; ``` --- libc/src/math/generic/CMakeLists.txt | 14 +- libc/src/math/generic/atanf.cpp | 125 +++++++++++++----- libc/src/math/generic/inv_trigf_utils.cpp | 80 +++++++++-- libc/src/math/generic/inv_trigf_utils.h | 83 +++--------- libc/test/src/math/CMakeLists.txt | 14 -- libc/test/src/math/atanf_test.cpp | 11 +- libc/test/src/math/exhaustive/atanf_test.cpp | 2 +- libc/test/src/math/inv_trigf_utils_test.cpp | 34 ----- .../llvm-project-overlay/libc/BUILD.bazel | 4 - 9 files changed, 186 insertions(+), 181 deletions(-) delete mode 100644 libc/test/src/math/inv_trigf_utils_test.cpp diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index b0a35c652cd5..176c32e47768 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -2155,16 +2155,9 @@ add_object_library( SRCS inv_trigf_utils.cpp DEPENDS - .math_utils - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.nearest_integer - libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.FPUtil.multiply_add libc.src.__support.FPUtil.polyeval libc.src.__support.common - libc.include.errno - libc.src.errno.errno - libc.include.math ) add_entrypoint_object( @@ -2211,8 +2204,11 @@ add_entrypoint_object( ../atanf.h DEPENDS .inv_trigf_utils - .math_utils + libc.src.__support.FPUtil.except_value_utils libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.nearest_integer + libc.src.__support.FPUtil.polyeval libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization COMPILE_OPTIONS diff --git a/libc/src/math/generic/atanf.cpp b/libc/src/math/generic/atanf.cpp index e0f8a1bfc2ec..69fd45ddd767 100644 --- a/libc/src/math/generic/atanf.cpp +++ b/libc/src/math/generic/atanf.cpp @@ -7,11 +7,14 @@ //===----------------------------------------------------------------------===// #include "src/math/atanf.h" -#include "math_utils.h" +#include "inv_trigf_utils.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/PolyEval.h" +#include "src/__support/FPUtil/except_value_utils.h" +#include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/FPUtil/nearest_integer.h" #include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY -#include "src/math/generic/inv_trigf_utils.h" namespace LIBC_NAMESPACE { @@ -19,48 +22,100 @@ LLVM_LIBC_FUNCTION(float, atanf, (float x)) { using FPBits = typename fputil::FPBits; using Sign = fputil::Sign; - // x == 0.0 - if (LIBC_UNLIKELY(x == 0.0f)) - return x; + constexpr double FINAL_SIGN[2] = {1.0, -1.0}; + constexpr double SIGNED_PI_OVER_2[2] = {0x1.921fb54442d18p0, + -0x1.921fb54442d18p0}; - FPBits xbits(x); - Sign sign = xbits.sign(); - xbits.set_sign(Sign::POS); + FPBits x_bits(x); + Sign sign = x_bits.sign(); + x_bits.set_sign(Sign::POS); + uint32_t x_abs = x_bits.uintval(); - if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) { - if (xbits.is_inf()) - return static_cast( - opt_barrier(sign.is_neg() ? -M_MATH_PI_2 : M_MATH_PI_2)); - else + // x is inf or nan, |x| < 2^-4 or |x|= > 16. + if (LIBC_UNLIKELY(x_abs <= 0x3d80'0000U || x_abs >= 0x4180'0000U)) { + double x_d = static_cast(x); + double const_term = 0.0; + if (LIBC_UNLIKELY(x_abs >= 0x4180'0000)) { + // atan(+-Inf) = +-pi/2. + if (x_bits.is_inf()) + return static_cast(SIGNED_PI_OVER_2[sign.is_neg()]); + if (x_bits.is_nan()) + return x; + // x >= 16 + x_d = -1.0 / x_d; + const_term = SIGNED_PI_OVER_2[sign.is_neg()]; + } + // 0 <= x < 1/16; + if (LIBC_UNLIKELY(x_bits.is_zero())) return x; - } - // |x| == 0.06905200332403183 - if (LIBC_UNLIKELY(xbits.uintval() == 0x3d8d6b23U)) { - if (fputil::fenv_is_round_to_nearest()) { - // 0.06894256919622421 - FPBits br(0x3d8d31c3U); - br.set_sign(sign); - return br.get_val(); + // x <= 2^-12; + if (LIBC_UNLIKELY(x_abs < 0x3980'0000)) { +#if defined(LIBC_TARGET_CPU_HAS_FMA) + return fputil::multiply_add(x, -0x1.0p-25f, x); +#else + double x_d = static_cast(x); + return static_cast(fputil::multiply_add(x_d, -0x1.0p-25, x_d)); +#endif // LIBC_TARGET_CPU_HAS_FMA } + // Use Taylor polynomial: + // atan(x) ~ x * (1 - x^2 / 3 + x^4 / 5 - x^6 / 7 + x^8 / 9 - x^10 / 11). + double x2 = x_d * x_d; + double x4 = x2 * x2; + double c0 = fputil::multiply_add(x2, ATAN_COEFFS[0][1], ATAN_COEFFS[0][0]); + double c1 = fputil::multiply_add(x2, ATAN_COEFFS[0][3], ATAN_COEFFS[0][2]); + double c2 = fputil::multiply_add(x2, ATAN_COEFFS[0][5], ATAN_COEFFS[0][4]); + double p = fputil::polyeval(x4, c0, c1, c2); + double r = fputil::multiply_add(x_d, p, const_term); + return static_cast(r); } - // |x| == 1.8670953512191772 - if (LIBC_UNLIKELY(xbits.uintval() == 0x3feefcfbU)) { - int rounding_mode = fputil::quick_get_round(); - if (sign.is_neg()) { - if (rounding_mode == FE_DOWNWARD) { - // -1.0790828466415405 - return FPBits(0xbf8a1f63U).get_val(); - } - } else { - if (rounding_mode == FE_UPWARD) { - // 1.0790828466415405 - return FPBits(0x3f8a1f63U).get_val(); - } + // Range reduction steps: + // 1) atan(x) = sign(x) * atan(|x|) + // 2) If |x| > 1, atan(|x|) = pi/2 - atan(1/|x|) + // 3) For 1/16 < x <= 1, we find k such that: |x - k/16| <= 1/32. + // 4) Then we use polynomial approximation: + // atan(x) ~ atan((k/16) + (x - (k/16)) * Q(x - k/16) + // = P(x - k/16) + double x_d, const_term, final_sign; + int idx; + + if (x_abs > 0x3f80'0000U) { + // Exceptional value: + if (LIBC_UNLIKELY(x_abs == 0x3ffe'2ec1U)) { // |x| = 0x1.fc5d82p+0 + return sign.is_pos() ? fputil::round_result_slightly_up(0x1.1ab2fp0f) + : fputil::round_result_slightly_down(-0x1.1ab2fp0f); } + // |x| > 1, we need to invert x, so we will perform range reduction in + // double precision. + x_d = 1.0 / static_cast(x_bits.get_val()); + double k_d = fputil::nearest_integer(x_d * 0x1.0p4); + x_d = fputil::multiply_add(k_d, -0x1.0p-4, x_d); + idx = static_cast(k_d); + final_sign = FINAL_SIGN[sign.is_pos()]; + // Adjust constant term of the polynomial by +- pi/2. + const_term = fputil::multiply_add(final_sign, ATAN_COEFFS[idx][0], + SIGNED_PI_OVER_2[sign.is_neg()]); + } else { + // Exceptional value: + if (LIBC_UNLIKELY(x_abs == 0x3dbb'6ac7U)) { // |x| = 0x1.76d58ep-4 + return sign.is_pos() + ? fputil::round_result_slightly_up(0x1.75cb06p-4f) + : fputil::round_result_slightly_down(-0x1.75cb06p-4f); + } + // Perform range reduction in single precision. + float x_f = x_bits.get_val(); + float k_f = fputil::nearest_integer(x_f * 0x1.0p4f); + x_f = fputil::multiply_add(k_f, -0x1.0p-4f, x_f); + x_d = static_cast(x_f); + idx = static_cast(k_f); + final_sign = FINAL_SIGN[sign.is_neg()]; + const_term = final_sign * ATAN_COEFFS[idx][0]; } - return static_cast(atan_eval(x)); + double p = atan_eval(x_d, idx); + double r = fputil::multiply_add(final_sign * x_d, p, const_term); + + return static_cast(r); } } // namespace LIBC_NAMESPACE diff --git a/libc/src/math/generic/inv_trigf_utils.cpp b/libc/src/math/generic/inv_trigf_utils.cpp index 8013c0470aff..93d5bcbf7b56 100644 --- a/libc/src/math/generic/inv_trigf_utils.cpp +++ b/libc/src/math/generic/inv_trigf_utils.cpp @@ -10,19 +10,71 @@ namespace LIBC_NAMESPACE { -// N[Table[ArcTan[x], {x, 1/16, 16/16, 1/16}], 40] -alignas(64) const double ATAN_T[ATAN_T_SIZE] = { - 0x1.ff55bb72cfdeap-5, 0x1.fd5ba9aac2f6ep-4, 0x1.7b97b4bce5b02p-3, - 0x1.f5b75f92c80ddp-3, 0x1.362773707ebccp-2, 0x1.6f61941e4def1p-2, - 0x1.a64eec3cc23fdp-2, 0x1.dac670561bb4fp-2, 0x1.0657e94db30d0p-1, - 0x1.1e00babdefeb4p-1, 0x1.345f01cce37bbp-1, 0x1.4978fa3269ee1p-1, - 0x1.5d58987169b18p-1, 0x1.700a7c5784634p-1, 0x1.819d0b7158a4dp-1, - 0x1.921fb54442d18p-1}; - -// for(int i = 0; i < 5; i++) -// printf("%.13a,\n", (-2 * (i % 2) + 1) * 1.0 / (2 * i + 1)); -alignas(64) const double ATAN_K[5] = { - 0x1.0000000000000p+0, -0x1.5555555555555p-2, 0x1.999999999999ap-3, - -0x1.2492492492492p-3, 0x1.c71c71c71c71cp-4}; +// Polynomial approximation for 0 <= x <= 1: +// atan(x) ~ atan((i/16) + (x - (i/16)) * Q(x - i/16) +// = P(x - i/16) +// Generated by Sollya with: +// > for i from 1 to 16 do { +// mid_point = i/16; +// P = fpminimax(atan(mid_point + x), 7, [|D...|], [-1/32, 1/32]); +// print("{", coeff(P, 0), ",", coeff(P, 1), ",", coeff(P, 2), ",", +// coeff(P, 3), ",", coeff(P, 4), ",", coeff(P, 5), ",", coeff(P, 6), +// ",", coeff(P, 7), "},"); +// }; +// For i = 0, ATAN_COEFFS[0][j] = (-1)^j * (1/(2*j + 1)) is the odd coefficients +// of the Taylor polynomial of atan(x). +double ATAN_COEFFS[17][8] = { + {0x1.0000000000000p+0, -0x1.5555555555555p-2, 0x1.999999999999ap-3, + -0x1.2492492492492p-3, 0x1.c71c71c71c71cp-4, -0x1.745d1745d1746p-4, + 0x1.3b13b13b13b14p-4, -0x1.1111111111111p-4}, + {0x1.ff55bb72cfdb1p-5, 0x1.fe01fe01fe1bp-1, -0x1.fc05f80821d1ap-5, + -0x1.4d6930419fc5fp-2, 0x1.f61b9f6d69313p-5, 0x1.8208a32f4346cp-3, + -0x1.ecb8fc53d04efp-5, -0x1.060710cb59cbcp-3}, + {0x1.fd5ba9aac2f3cp-4, 0x1.f81f81f81f96ap-1, -0x1.f05e09cf4c1b2p-4, + -0x1.368c3aac7543ep-2, 0x1.d9b14bddfac55p-4, 0x1.4048e55ec725ep-3, + -0x1.b98ca3c1594b5p-4, -0x1.664eabaabbc16p-4}, + {0x1.7b97b4bce5ae7p-3, 0x1.ee9c7f8458f06p-1, -0x1.665c226c8dc69p-3, + -0x1.1344bb77961b7p-2, 0x1.42ac97745d3ccp-3, 0x1.c32e142047ec1p-4, + -0x1.137ae41ab96cbp-3, -0x1.1a6ae8c09a4b6p-5}, + {0x1.f5b75f92c80c6p-3, 0x1.e1e1e1e1e1ed4p-1, -0x1.c5894d101ad4p-3, + -0x1.ce6de02b38c38p-3, 0x1.78a3920c336b9p-3, 0x1.dd5ff94a9d499p-5, + -0x1.1ac2d3f9d072ep-3, 0x1.0af9735dff373p-6}, + {0x1.362773707ebc5p-2, 0x1.d272ca3fc5b8bp-1, -0x1.0997e8ae90cb6p-2, + -0x1.6cf6667146798p-3, 0x1.8dd1dff17f3d3p-3, 0x1.24860eced656fp-7, + -0x1.f4220e8f18ed5p-4, 0x1.b700aed7cdc34p-5}, + {0x1.6f61941e4deeep-2, 0x1.c0e070381c115p-1, -0x1.2726dd1347c7ep-2, + -0x1.09f37b3ad010dp-3, 0x1.85eaca5196f5cp-3, -0x1.04d640117852ap-5, + -0x1.802c2956871c7p-4, 0x1.2992b45df0ee7p-4}, + {0x1.a64eec3cc23fep-2, 0x1.adbe87f94906bp-1, -0x1.3b9d8eab5eae5p-2, + -0x1.57c09646faabbp-4, 0x1.6795330e73aep-3, -0x1.f2d89a702a652p-5, + -0x1.f3afd90a9d4d7p-5, 0x1.3261723d3f153p-4}, + {0x1.dac670561bb53p-2, 0x1.999999999998fp-1, -0x1.47ae147afd8cap-2, + -0x1.5d867c3dfd72ap-5, 0x1.3a92a76cba833p-3, -0x1.3ec460286928ap-4, + -0x1.ed02ff86892acp-6, 0x1.0a674c8f05727p-4}, + {0x1.0657e94db30d2p-1, 0x1.84f00c27805ffp-1, -0x1.4c62cb564f677p-2, + -0x1.e6495b262dfe7p-8, 0x1.063c34eca262bp-3, -0x1.58b78dc79b5aep-4, + -0x1.4623815233be1p-8, 0x1.93afe94328089p-5}, + {0x1.1e00babdefeb6p-1, 0x1.702e05c0b8159p-1, -0x1.4af2b78236bd6p-2, + 0x1.5d0b7ea46ed08p-6, 0x1.a124870236935p-4, -0x1.519e1ec133a88p-4, + 0x1.a54632a3f48c7p-7, 0x1.099ca0945096dp-5}, + {0x1.345f01cce37bdp-1, 0x1.5babcc647fa7ep-1, -0x1.449db09443a67p-2, + 0x1.655caac78a0fcp-5, 0x1.3bbbdb0d09efap-4, -0x1.34a306c27e021p-4, + 0x1.83fe749c7966p-6, 0x1.2057cc96d9edcp-6}, + {0x1.4978fa3269ee2p-1, 0x1.47ae147ae146bp-1, -0x1.3a92a305652e1p-2, + 0x1.ec21b5172657fp-5, 0x1.c2f8c45d2f4eep-5, -0x1.0ba99c4aeb8acp-4, + 0x1.d716a4af4d1d6p-6, 0x1.97fba0a9696dep-8}, + {0x1.5d58987169b19p-1, 0x1.34679ace0133cp-1, -0x1.2ddfb03920e2fp-2, + 0x1.2491307c0fa0bp-4, 0x1.29c7eca0136fp-5, -0x1.bca792caa6f1cp-5, + 0x1.e5d92545576bcp-6, -0x1.8ca76fcf5ccd2p-10}, + {0x1.700a7c5784634p-1, 0x1.21fb78121fb71p-1, -0x1.1f6a8499ea541p-2, + 0x1.41b15e5e77bcfp-4, 0x1.59bc9bf54fb02p-6, -0x1.63b54ff058e0fp-5, + 0x1.c8da01221306fp-6, -0x1.906b2c274c39cp-8}, + {0x1.819d0b7158a4dp-1, 0x1.107fbbe01107cp-1, -0x1.0feeb40897d4ep-2, + 0x1.50e5afb95f5d6p-4, 0x1.2a7c2f0c7495dp-7, -0x1.12bd2bb5062cdp-5, + 0x1.93e8ceb89afebp-6, -0x1.10da9b8c6b731p-7}, + {0x1.921fb54442d18p-1, 0x1.fffffffffffebp-2, -0x1.fffffffffcbbcp-3, + 0x1.555555564e2fep-4, -0x1.20b17d5dd89dcp-30, -0x1.9999c5ad71711p-6, + 0x1.5558b76e7aaf9p-6, -0x1.236e803c6c1f6p-7}, +}; } // namespace LIBC_NAMESPACE diff --git a/libc/src/math/generic/inv_trigf_utils.h b/libc/src/math/generic/inv_trigf_utils.h index 20f912de2ac0..308bdc44e3f8 100644 --- a/libc/src/math/generic/inv_trigf_utils.h +++ b/libc/src/math/generic/inv_trigf_utils.h @@ -9,85 +9,32 @@ #ifndef LLVM_LIBC_SRC_MATH_GENERIC_INV_TRIGF_UTILS_H #define LLVM_LIBC_SRC_MATH_GENERIC_INV_TRIGF_UTILS_H -#include "math_utils.h" -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/PolyEval.h" -#include "src/__support/FPUtil/nearest_integer.h" +#include "src/__support/FPUtil/multiply_add.h" #include "src/__support/common.h" -#include - namespace LIBC_NAMESPACE { // PI and PI / 2 constexpr double M_MATH_PI = 0x1.921fb54442d18p+1; constexpr double M_MATH_PI_2 = 0x1.921fb54442d18p+0; -// atan table size -constexpr int ATAN_T_BITS = 4; -constexpr int ATAN_T_SIZE = 1 << ATAN_T_BITS; - -// N[Table[ArcTan[x], {x, 1/8, 8/8, 1/8}], 40] -extern const double ATAN_T[ATAN_T_SIZE]; -extern const double ATAN_K[5]; - -// The main idea of the function is to use formula -// atan(u) + atan(v) = atan((u+v)/(1-uv)) - -// x should be positive, normal finite value -LIBC_INLINE double atan_eval(double x) { - using FPB = fputil::FPBits; - using Sign = fputil::Sign; - // Added some small value to umin and umax mantissa to avoid possible rounding - // errors. - FPB::StorageType umin = - FPB::create_value(Sign::POS, FPB::EXP_BIAS - ATAN_T_BITS - 1, - 0x100000000000UL) - .uintval(); - FPB::StorageType umax = - FPB::create_value(Sign::POS, FPB::EXP_BIAS + ATAN_T_BITS, - 0xF000000000000UL) - .uintval(); - - FPB bs(x); - auto x_abs = bs.abs().uintval(); - - if (x_abs <= umin) { - double pe = LIBC_NAMESPACE::fputil::polyeval( - x * x, 0.0, ATAN_K[1], ATAN_K[2], ATAN_K[3], ATAN_K[4]); - return fputil::multiply_add(pe, x, x); - } - - if (x_abs >= umax) { - double one_over_x_m = -1.0 / x; - double one_over_x2 = one_over_x_m * one_over_x_m; - double pe = LIBC_NAMESPACE::fputil::polyeval( - one_over_x2, ATAN_K[0], ATAN_K[1], ATAN_K[2], ATAN_K[3]); - return fputil::multiply_add(pe, one_over_x_m, - bs.is_neg() ? (-M_MATH_PI_2) : (M_MATH_PI_2)); - } +extern double ATAN_COEFFS[17][8]; - double pos_x = FPB(x_abs).get_val(); - bool one_over_x = pos_x > 1.0; - if (one_over_x) { - pos_x = 1.0 / pos_x; - } +// For |x| <= 1/32 and 1 <= i <= 16, return Q(x) such that: +// Q(x) ~ (atan(x + i/16) - atan(i/16)) / x. +LIBC_INLINE constexpr double atan_eval(double x, int i) { + double x2 = x * x; - double near_x = fputil::nearest_integer(pos_x * ATAN_T_SIZE); - int val = static_cast(near_x); - near_x *= 1.0 / ATAN_T_SIZE; + double c0 = fputil::multiply_add(x, ATAN_COEFFS[i][2], ATAN_COEFFS[i][1]); + double c1 = fputil::multiply_add(x, ATAN_COEFFS[i][4], ATAN_COEFFS[i][3]); + double c2 = fputil::multiply_add(x, ATAN_COEFFS[i][6], ATAN_COEFFS[i][5]); - double v = (pos_x - near_x) / fputil::multiply_add(near_x, pos_x, 1.0); - double v2 = v * v; - double pe = LIBC_NAMESPACE::fputil::polyeval(v2, ATAN_K[0], ATAN_K[1], - ATAN_K[2], ATAN_K[3], ATAN_K[4]); - double result; - if (one_over_x) - result = M_MATH_PI_2 - fputil::multiply_add(pe, v, ATAN_T[val - 1]); - else - result = fputil::multiply_add(pe, v, ATAN_T[val - 1]); - return bs.is_neg() ? -result : result; + double x4 = x2 * x2; + double d1 = fputil::multiply_add(x2, c1, c0); + double d2 = fputil::multiply_add(x2, ATAN_COEFFS[i][7], c2); + double p = fputil::multiply_add(x4, d2, d1); + return p; } // > Q = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20|], @@ -99,7 +46,7 @@ constexpr double ASIN_COEFFS[10] = {0x1.5555555540fa1p-3, 0x1.333333512edc2p-4, -0x1.df946fa875ddp-8, 0x1.02311ecf99c28p-5}; // Evaluate P(x^2) - 1, where P(x^2) ~ asin(x)/x -LIBC_INLINE double asin_eval(double xsq) { +LIBC_INLINE constexpr double asin_eval(double xsq) { double x4 = xsq * xsq; double r1 = fputil::polyeval(x4, ASIN_COEFFS[0], ASIN_COEFFS[2], ASIN_COEFFS[4], ASIN_COEFFS[6], ASIN_COEFFS[8]); diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt index 9d62b1cf7ef7..026bcd12928b 100644 --- a/libc/test/src/math/CMakeLists.txt +++ b/libc/test/src/math/CMakeLists.txt @@ -1645,20 +1645,6 @@ add_fp_unittest( libc.src.__support.FPUtil.fp_bits ) -add_fp_unittest( - inv_trigf_utils_test - NEED_MPFR - SUITE - libc-math-unittests - HDRS - in_float_range_test_helper.h - SRCS - inv_trigf_utils_test.cpp - DEPENDS - libc.src.math.generic.inv_trigf_utils - libc.src.__support.FPUtil.fp_bits -) - add_fp_unittest( scalbn_test NEED_MPFR diff --git a/libc/test/src/math/atanf_test.cpp b/libc/test/src/math/atanf_test.cpp index fdd69d3dc791..e51932fc4955 100644 --- a/libc/test/src/math/atanf_test.cpp +++ b/libc/test/src/math/atanf_test.cpp @@ -53,8 +53,15 @@ TEST_F(LlvmLibcAtanfTest, InFloatRange) { // For small values, tanh(x) is x. TEST_F(LlvmLibcAtanfTest, SpecialValues) { - uint32_t val_arr[] = {0x3d8d6b23U, 0x3feefcfbU, 0xbd8d6b23U, - 0xbfeefcfbU, 0x7F800000U, 0xFF800000U}; + uint32_t val_arr[] = { + 0x3d8d6b23U, // x = 0x1.1ad646p-4f + 0x3feefcfbU, // x = 0x1.ddf9f6p+0f + 0xbd8d6b23U, // x = -0x1.1ad646p-4f + 0xbfeefcfbU, // x = -0x1.ddf9f6p+0f + 0x7F800000U, // x = +Inf + 0xFF800000U, // x = -Inf + 0xbffe2ec1U, // x = -0x1.fc5d82p+0f + }; for (uint32_t v : val_arr) { float x = FPBits(v).get_val(); EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x, diff --git a/libc/test/src/math/exhaustive/atanf_test.cpp b/libc/test/src/math/exhaustive/atanf_test.cpp index 508c288b050c..6f23231d4267 100644 --- a/libc/test/src/math/exhaustive/atanf_test.cpp +++ b/libc/test/src/math/exhaustive/atanf_test.cpp @@ -25,7 +25,7 @@ TEST_F(LlvmLibcAtanfExhaustiveTest, PostiveRange) { } // Range: [-Inf, 0]; -static constexpr uint32_t NEG_START = 0xb000'0000U; +static constexpr uint32_t NEG_START = 0x8000'0000U; static constexpr uint32_t NEG_STOP = 0xff80'0000U; TEST_F(LlvmLibcAtanfExhaustiveTest, NegativeRange) { diff --git a/libc/test/src/math/inv_trigf_utils_test.cpp b/libc/test/src/math/inv_trigf_utils_test.cpp deleted file mode 100644 index ebf21765b26d..000000000000 --- a/libc/test/src/math/inv_trigf_utils_test.cpp +++ /dev/null @@ -1,34 +0,0 @@ -//===-- Unittests for supfuncf --------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "in_float_range_test_helper.h" -#include "include/llvm-libc-macros/math-macros.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/math/generic/inv_trigf_utils.h" -#include "test/UnitTest/FPMatcher.h" -#include "test/UnitTest/Test.h" -#include "utils/MPFRWrapper/MPFRUtils.h" - -using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest; - -namespace mpfr = LIBC_NAMESPACE::testing::mpfr; - -constexpr int def_count = 100003; -constexpr float def_prec = 0.500001f; - -auto f_normal = [](float x) -> bool { return !(isnan(x) || isinf(x)); }; - -TEST_F(LlvmLibcAtanfTest, InPositiveRange) { - CHECK_DATA(0.0f, inf, mpfr::Operation::Atan, LIBC_NAMESPACE::atan_eval, - f_normal, def_count, def_prec); -} - -TEST_F(LlvmLibcAtanfTest, InNegativeRange) { - CHECK_DATA(-0.0f, neg_inf, mpfr::Operation::Atan, LIBC_NAMESPACE::atan_eval, - f_normal, def_count, def_prec); -} diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 0ec8e350281d..01bb8b4298cd 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -1252,13 +1252,9 @@ libc_support_library( hdrs = ["src/math/generic/inv_trigf_utils.h"], deps = [ ":__support_common", - ":__support_fputil_fenv_impl", ":__support_fputil_fma", - ":__support_fputil_fp_bits", ":__support_fputil_multiply_add", - ":__support_fputil_nearest_integer", ":__support_fputil_polyeval", - ":math_utils", ], ) -- GitLab From a5f576e5961ecc099bd7ccf8565da090edc84b0d Mon Sep 17 00:00:00 2001 From: Kelvin Li Date: Mon, 18 Mar 2024 21:35:56 -0400 Subject: [PATCH 013/307] [flang] Diagnose calling impure final procedure due to finalization in FORALL (#85685) This patch checks the LHS of an assignment in a FORALL loop and diagnoses if any impure final procedure is called. --- flang/lib/Semantics/check-do-forall.cpp | 12 +++++ flang/test/Semantics/forall02.f90 | 67 +++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 flang/test/Semantics/forall02.f90 diff --git a/flang/lib/Semantics/check-do-forall.cpp b/flang/lib/Semantics/check-do-forall.cpp index 36340a4c5259..51f536f3d772 100644 --- a/flang/lib/Semantics/check-do-forall.cpp +++ b/flang/lib/Semantics/check-do-forall.cpp @@ -438,6 +438,18 @@ public: CheckForallIndexesUsed(*assignment); CheckForImpureCall(assignment->lhs); CheckForImpureCall(assignment->rhs); + + if (IsVariable(assignment->lhs)) { + if (const Symbol * symbol{GetLastSymbol(assignment->lhs)}) { + if (auto impureFinal{ + HasImpureFinal(*symbol, assignment->lhs.Rank())}) { + context_.SayWithDecl(*symbol, parser::FindSourceLocation(stmt), + "Impure procedure '%s' is referenced by finalization in a %s"_err_en_US, + impureFinal->name(), LoopKindName()); + } + } + } + if (const auto *proc{ std::get_if(&assignment->u)}) { CheckForImpureCall(*proc); diff --git a/flang/test/Semantics/forall02.f90 b/flang/test/Semantics/forall02.f90 new file mode 100644 index 000000000000..c4f4311a175a --- /dev/null +++ b/flang/test/Semantics/forall02.f90 @@ -0,0 +1,67 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 + +module m1 + type :: impureFinal + contains + final :: impureSub + final :: impureSubRank1 + final :: impureSubRank2 + end type + + contains + + impure subroutine impureSub(x) + type(impureFinal), intent(in) :: x + end subroutine + + impure subroutine impureSubRank1(x) + type(impureFinal), intent(in) :: x(:) + end subroutine + + impure subroutine impureSubRank2(x) + type(impureFinal), intent(in) :: x(:,:) + end subroutine + + subroutine s1() + implicit none + integer :: i + type(impureFinal), allocatable :: ifVar, ifvar1 + type(impureFinal), allocatable :: ifArr1(:), ifArr2(:,:) + type(impureFinal) :: if0 + integer a(10) + allocate(ifVar) + allocate(ifVar1) + allocate(ifArr1(5), ifArr2(5,5)) + + ! Error to invoke an IMPURE FINAL procedure in a FORALL + forall (i = 1:10) + !WARNING: FORALL index variable 'i' not used on left-hand side of assignment + !ERROR: Impure procedure 'impuresub' is referenced by finalization in a FORALL + ifvar = ifvar1 + end forall + + forall (i = 1:5) + !ERROR: Impure procedure 'impuresub' is referenced by finalization in a FORALL + ifArr1(i) = if0 + end forall + + forall (i = 1:5) + !WARNING: FORALL index variable 'i' not used on left-hand side of assignment + !ERROR: Impure procedure 'impuresubrank1' is referenced by finalization in a FORALL + ifArr1 = if0 + end forall + + forall (i = 1:5) + !ERROR: Impure procedure 'impuresubrank1' is referenced by finalization in a FORALL + ifArr2(i,:) = if0 + end forall + + forall (i = 1:5) + !WARNING: FORALL index variable 'i' not used on left-hand side of assignment + !ERROR: Impure procedure 'impuresubrank2' is referenced by finalization in a FORALL + ifArr2(:,:) = if0 + end forall + end subroutine + +end module m1 + -- GitLab From aec50cd840418097e8eeb4bd5d0672c95c08d1ec Mon Sep 17 00:00:00 2001 From: Jake Egan Date: Mon, 18 Mar 2024 22:19:53 -0400 Subject: [PATCH 014/307] [NFC] Disable llvm-objdump test on AIX After commit 9d5edfde5c3dbc4eb559d316e82e664f291fc2bf the test is failing on the AIX bot. XFAIL for now to unblock the bot and give time to investigate. --- .../llvm-objdump/MachO/AArch64/macho-relative-method-lists.test | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test b/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test index b1b96a41a329..8e1a9b679704 100644 --- a/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test +++ b/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test @@ -1,3 +1,4 @@ +XFAIL: system-aix RUN: llvm-objdump --macho --objc-meta-data %p/Inputs/rel-method-lists-arm64_32.dylib | FileCheck %s --check-prefix=CHK32 RUN: llvm-otool -ov %p/Inputs/rel-method-lists-arm64_32.dylib | FileCheck %s --check-prefix=CHK32 -- GitLab From f6a2a55ba1fe1a4b720b8760704785d12137b35e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Clement=20=28=E3=83=90=E3=83=AC=E3=83=B3?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=B3=20=E3=82=AF=E3=83=AC=E3=83=A1?= =?UTF-8?q?=E3=83=B3=29?= Date: Mon, 18 Mar 2024 19:46:11 -0700 Subject: [PATCH 015/307] [flang][cuda] Handle lowering of stars in cuf kernel launch parameters (#85695) Parsing of the cuf kernel loop directive has been updated to handle variants with the * syntax. This patch updates the lowering to make use of them. - If the grid or block syntax uses only stars then the operation variadic operand remains empty. - If there is values and stars, then stars are represented as a zero constant value. --- .../include/flang/Optimizer/Dialect/FIROps.td | 10 +++++ flang/lib/Lower/Bridge.cpp | 45 +++++++++++++------ .../Lower/CUDA/cuda-kernel-loop-directive.cuf | 19 ++++++-- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index f4792637f481..6e520d111701 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -3131,6 +3131,16 @@ def fir_BoxOffsetOp : fir_Op<"box_offset", [NoMemoryEffect]> { def fir_CUDAKernelOp : fir_Op<"cuda_kernel", [AttrSizedOperandSegments, DeclareOpInterfaceMethods]> { + let description = [{ + Represent the CUDA Fortran kernel directive. The operation is a loop like + operation that represents the iteration range of the embedded loop nest. + + When grid or block variadic operands are empty, a `*` only syntax was used + in the Fortran code. + If the `*` is mixed with values for either grid or block, these are + represented by a 0 constant value. + }]; + let arguments = (ins Variadic:$grid, // empty means `*` Variadic:$block, // empty means `*` diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 6c32c537198c..c3cb9ba6a47e 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -2529,23 +2529,42 @@ private: const std::optional &stream = std::get<3>(dir.t); + auto isOnlyStars = + [&](const std::list + &list) -> bool { + for (const Fortran::parser::CUFKernelDoConstruct::StarOrExpr &expr : + list) { + if (expr.v) + return false; + } + return true; + }; + + mlir::Value zero = + builder->createIntegerConstant(loc, builder->getI32Type(), 0); + llvm::SmallVector gridValues; - for (const Fortran::parser::CUFKernelDoConstruct::StarOrExpr &expr : grid) { - if (expr.v) { - gridValues.push_back(fir::getBase( - genExprValue(*Fortran::semantics::GetExpr(*expr.v), stmtCtx))); - } else { - // TODO: '*' + if (!isOnlyStars(grid)) { + for (const Fortran::parser::CUFKernelDoConstruct::StarOrExpr &expr : + grid) { + if (expr.v) { + gridValues.push_back(fir::getBase( + genExprValue(*Fortran::semantics::GetExpr(*expr.v), stmtCtx))); + } else { + gridValues.push_back(zero); + } } } llvm::SmallVector blockValues; - for (const Fortran::parser::CUFKernelDoConstruct::StarOrExpr &expr : - block) { - if (expr.v) { - blockValues.push_back(fir::getBase( - genExprValue(*Fortran::semantics::GetExpr(*expr.v), stmtCtx))); - } else { - // TODO: '*' + if (!isOnlyStars(block)) { + for (const Fortran::parser::CUFKernelDoConstruct::StarOrExpr &expr : + block) { + if (expr.v) { + blockValues.push_back(fir::getBase( + genExprValue(*Fortran::semantics::GetExpr(*expr.v), stmtCtx))); + } else { + blockValues.push_back(zero); + } } } mlir::Value streamValue; diff --git a/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf b/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf index c017561447f8..6179e609db38 100644 --- a/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf +++ b/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf @@ -42,7 +42,20 @@ subroutine sub1() ! CHECK: fir.cuda_kernel<<<%c1{{.*}}, (%c256{{.*}}, %c1{{.*}})>>> (%{{.*}} : index, %{{.*}} : index) = (%{{.*}}, %{{.*}} : index, index) to (%{{.*}}, %{{.*}} : index, index) step (%{{.*}}, %{{.*}} : index, index) ! CHECK: {n = 2 : i64} -! TODO: lowering for these cases -! !$cuf kernel do(2) <<< (1,*), (256,1) >>> -! !$cuf kernel do(2) <<< (*,*), (32,4) >>> + !$cuf kernel do(2) <<< (1,*), (256,1) >>> + do i = 1, n + do j = 1, n + c(i,j) = c(i,j) * d(i,j) + end do + end do +! CHECK: fir.cuda_kernel<<<(%c1{{.*}}, %c0{{.*}}), (%c256{{.*}}, %c1{{.*}})>>> (%{{.*}} : index, %{{.*}} : index) = (%{{.*}}, %{{.*}} : index, index) to (%{{.*}}, %{{.*}} : index, index) step (%{{.*}}, %{{.*}} : index, index) + +!$cuf kernel do(2) <<< (*,*), (32,4) >>> + do i = 1, n + do j = 1, n + c(i,j) = c(i,j) * d(i,j) + end do + end do + +! CHECK: fir.cuda_kernel<<<*, (%c32{{.*}}, %c4{{.*}})>>> (%{{.*}} : index, %{{.*}} : index) = (%{{.*}}, %{{.*}} : index, index) to (%{{.*}}, %{{.*}} : index, index) step (%{{.*}}, %{{.*}} : index, index) end -- GitLab From a2527e06d77766d00e83ecb7988844aae7088bb1 Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Mon, 18 Mar 2024 20:17:49 -0700 Subject: [PATCH 016/307] [clang-format] Put erroneously removed braces back into a unit test See https://github.com/llvm/llvm-project/pull/85470#discussion_r1528904789 --- clang/unittests/Format/FormatTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index a14b002c37c6..bea989c8c306 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -11475,10 +11475,10 @@ TEST_F(FormatTest, UnderstandsNewAndDelete) { "void new (link p);\n" "void delete (link p);"); - verifyFormat("p->new();\n" - "p->delete();", - "p->new ();\n" - "p->delete ();"); + verifyFormat("{ p->new(); }\n" + "{ p->delete(); }", + "{ p->new (); }\n" + "{ p->delete (); }"); FormatStyle AfterPlacementOperator = getLLVMStyle(); AfterPlacementOperator.SpaceBeforeParens = FormatStyle::SBPO_Custom; -- GitLab From bda05140fb758156ae35f3919e6283d94bfa3905 Mon Sep 17 00:00:00 2001 From: lntue <35648136+lntue@users.noreply.github.com> Date: Mon, 18 Mar 2024 23:43:57 -0400 Subject: [PATCH 017/307] [libc] Remove constexpr from atan_eval and asin_eval. (#85725) Fix aarch64 and gcc full build bots: https://lab.llvm.org/buildbot/#/builders/223/builds/38235/steps/4/logs/stdio --- libc/src/math/generic/inv_trigf_utils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libc/src/math/generic/inv_trigf_utils.h b/libc/src/math/generic/inv_trigf_utils.h index 308bdc44e3f8..c621f27e1014 100644 --- a/libc/src/math/generic/inv_trigf_utils.h +++ b/libc/src/math/generic/inv_trigf_utils.h @@ -23,7 +23,7 @@ extern double ATAN_COEFFS[17][8]; // For |x| <= 1/32 and 1 <= i <= 16, return Q(x) such that: // Q(x) ~ (atan(x + i/16) - atan(i/16)) / x. -LIBC_INLINE constexpr double atan_eval(double x, int i) { +LIBC_INLINE double atan_eval(double x, int i) { double x2 = x * x; double c0 = fputil::multiply_add(x, ATAN_COEFFS[i][2], ATAN_COEFFS[i][1]); @@ -46,7 +46,7 @@ constexpr double ASIN_COEFFS[10] = {0x1.5555555540fa1p-3, 0x1.333333512edc2p-4, -0x1.df946fa875ddp-8, 0x1.02311ecf99c28p-5}; // Evaluate P(x^2) - 1, where P(x^2) ~ asin(x)/x -LIBC_INLINE constexpr double asin_eval(double xsq) { +LIBC_INLINE double asin_eval(double xsq) { double x4 = xsq * xsq; double r1 = fputil::polyeval(x4, ASIN_COEFFS[0], ASIN_COEFFS[2], ASIN_COEFFS[4], ASIN_COEFFS[6], ASIN_COEFFS[8]); -- GitLab From e04dd68a3a26d3ebdc2db07cf2f8807a02d30ce2 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 18 Mar 2024 21:14:26 -0700 Subject: [PATCH 018/307] [GlobalMerge] Use vector::assign in place of fill+resize. NFC (#85723) Noticed while reviewing the code. If the resize causes a new allocation, this will fill the new allocation with zeroes directly. Previously, we would fill the old allocation with zeroes, then copy them to the new allocation before filling the additional space with zeros. --- llvm/lib/CodeGen/GlobalMerge.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalMerge.cpp b/llvm/lib/CodeGen/GlobalMerge.cpp index 4941d5b01ae0..545ee1741834 100644 --- a/llvm/lib/CodeGen/GlobalMerge.cpp +++ b/llvm/lib/CodeGen/GlobalMerge.cpp @@ -309,10 +309,9 @@ bool GlobalMergeImpl::doMerge(SmallVectorImpl &Globals, for (size_t GI = 0, GE = Globals.size(); GI != GE; ++GI) { GlobalVariable *GV = Globals[GI]; - // Reset the encountered sets for this global... - std::fill(EncounteredUGS.begin(), EncounteredUGS.end(), 0); - // ...and grow it in case we created new sets for the previous global. - EncounteredUGS.resize(UsedGlobalSets.size()); + // Reset the encountered sets for this global and grow it in case we created + // new sets for the previous global. + EncounteredUGS.assign(UsedGlobalSets.size(), 0); // We might need to create a set that only consists of the current global. // Keep track of its index into UsedGlobalSets. -- GitLab From 924a1dceb59944fa9051acbbb7d2daac129ee0ef Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Tue, 19 Mar 2024 09:13:17 +0300 Subject: [PATCH 019/307] [Dwarf] Support `__ptrauth` qualifier in metadata nodes (#83862) Reland #82363 after fixing build failure https://lab.llvm.org/buildbot/#/builders/5/builds/41428. Memory sanitizer detects usage of `RawData` union member which is not filled directly. Instead, the code relies on filling `Data` union member, which is a struct consisting of signing schema parameters. According to https://en.cppreference.com/w/cpp/language/union, this is UB: "It is undefined behavior to read from the member of the union that wasn't most recently written". Instead of relying on compiler allowing us to do dirty things, do not use union and only store `RawData`. Particular ptrauth parameters are obtained on demand via bit operations. Original PR description below. Emit `__ptrauth`-qualified types as `DIDerivedType` metadata nodes in IR with tag `DW_TAG_LLVM_ptrauth_type`, baseType referring to the type which has the qualifier applied, and the following parameters representing the signing schema: - `ptrAuthKey` (integer) - `ptrAuthIsAddressDiscriminated` (boolean) - `ptrAuthExtraDiscriminator` (integer) - `ptrAuthIsaPointer` (boolean) - `ptrAuthAuthenticatesNullValues` (boolean) Co-authored-by: Ahmed Bougacha --- llvm/include/llvm/IR/DIBuilder.h | 7 ++ llvm/include/llvm/IR/DebugInfoMetadata.h | 98 ++++++++++++++++----- llvm/lib/AsmParser/LLParser.cpp | 23 ++++- llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 17 +++- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 5 ++ llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 12 +++ llvm/lib/IR/AsmWriter.cpp | 10 +++ llvm/lib/IR/DIBuilder.cpp | 58 +++++++----- llvm/lib/IR/DebugInfo.cpp | 6 +- llvm/lib/IR/DebugInfoMetadata.cpp | 32 ++++--- llvm/lib/IR/LLVMContextImpl.h | 15 ++-- llvm/lib/IR/Verifier.cpp | 1 + llvm/test/Assembler/debug-info.ll | 16 +++- llvm/test/DebugInfo/AArch64/ptrauth.ll | 70 +++++++++++++++ llvm/unittests/IR/MetadataTest.cpp | 85 ++++++++++++------ mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 3 +- 16 files changed, 358 insertions(+), 100 deletions(-) create mode 100644 llvm/test/DebugInfo/AArch64/ptrauth.ll diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index 94af17af8160..d758d2494286 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -270,6 +270,13 @@ namespace llvm { std::optional DWARFAddressSpace = std::nullopt, StringRef Name = "", DINodeArray Annotations = nullptr); + /// Create a __ptrauth qualifier. + DIDerivedType *createPtrAuthQualifiedType(DIType *FromTy, unsigned Key, + bool IsAddressDiscriminated, + unsigned ExtraDiscriminator, + bool IsaPointer, + bool authenticatesNullValues); + /// Create debugging information entry for a pointer to member. /// \param PointeeTy Type pointed to by this pointer. /// \param SizeInBits Size. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 156f6eb49253..5e827b4a2e03 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -745,7 +745,7 @@ public: unsigned getLine() const { return Line; } uint64_t getSizeInBits() const { return SizeInBits; } - uint32_t getAlignInBits() const { return SubclassData32; } + uint32_t getAlignInBits() const; uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; } uint64_t getOffsetInBits() const { return OffsetInBits; } DIFlags getFlags() const { return Flags; } @@ -972,6 +972,35 @@ public: /// /// TODO: Split out members (inheritance, fields, methods, etc.). class DIDerivedType : public DIType { +public: + /// Pointer authentication (__ptrauth) metadata. + struct PtrAuthData { + // RawData layout: + // - Bits 0..3: Key + // - Bit 4: IsAddressDiscriminated + // - Bits 5..20: ExtraDiscriminator + // - Bit 21: IsaPointer + // - Bit 22: AuthenticatesNullValues + unsigned RawData; + + PtrAuthData(unsigned FromRawData) : RawData(FromRawData) {} + PtrAuthData(unsigned Key, bool IsDiscr, unsigned Discriminator, + bool IsaPointer, bool AuthenticatesNullValues) { + assert(Key < 16); + assert(Discriminator <= 0xffff); + RawData = (Key << 0) | (IsDiscr ? (1 << 4) : 0) | (Discriminator << 5) | + (IsaPointer ? (1 << 21) : 0) | + (AuthenticatesNullValues ? (1 << 22) : 0); + } + + unsigned key() { return (RawData >> 0) & 0b1111; } + bool isAddressDiscriminated() { return (RawData >> 4) & 1; } + unsigned extraDiscriminator() { return (RawData >> 5) & 0xffff; } + bool isaPointer() { return (RawData >> 21) & 1; } + bool authenticatesNullValues() { return (RawData >> 22) & 1; } + }; + +private: friend class LLVMContextImpl; friend class MDNode; @@ -982,59 +1011,70 @@ class DIDerivedType : public DIType { DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag, unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, ArrayRef Ops) : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags, Ops), - DWARFAddressSpace(DWARFAddressSpace) {} + DWARFAddressSpace(DWARFAddressSpace) { + if (PtrAuthData) + SubclassData32 = PtrAuthData->RawData; + } ~DIDerivedType() = default; static DIDerivedType * getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData, DINodeArray Annotations, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, - DWARFAddressSpace, Flags, ExtraData, Annotations.get(), - Storage, ShouldCreate); + DWARFAddressSpace, PtrAuthData, Flags, ExtraData, + Annotations.get(), Storage, ShouldCreate); } static DIDerivedType * getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData, Metadata *Annotations, StorageType Storage, bool ShouldCreate = true); TempDIDerivedType cloneImpl() const { - return getTemporary( - getContext(), getTag(), getName(), getFile(), getLine(), getScope(), - getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(), - getDWARFAddressSpace(), getFlags(), getExtraData(), getAnnotations()); + return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(), + getScope(), getBaseType(), getSizeInBits(), + getAlignInBits(), getOffsetInBits(), + getDWARFAddressSpace(), getPtrAuthData(), getFlags(), + getExtraData(), getAnnotations()); } public: - DEFINE_MDNODE_GET( - DIDerivedType, - (unsigned Tag, MDString *Name, Metadata *File, unsigned Line, - Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, - Metadata *ExtraData = nullptr, Metadata *Annotations = nullptr), - (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, DWARFAddressSpace, Flags, ExtraData, Annotations)) + DEFINE_MDNODE_GET(DIDerivedType, + (unsigned Tag, MDString *Name, Metadata *File, + unsigned Line, Metadata *Scope, Metadata *BaseType, + uint64_t SizeInBits, uint32_t AlignInBits, + uint64_t OffsetInBits, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, + Metadata *ExtraData = nullptr, + Metadata *Annotations = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, + AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData, + Flags, ExtraData, Annotations)) DEFINE_MDNODE_GET(DIDerivedType, (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData = nullptr, DINodeArray Annotations = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, - ExtraData, Annotations)) + AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData, + Flags, ExtraData, Annotations)) TempDIDerivedType clone() const { return cloneImpl(); } @@ -1048,6 +1088,8 @@ public: return DWARFAddressSpace; } + std::optional getPtrAuthData() const; + /// Get extra data associated with this derived type. /// /// Class type for pointer-to-members, objective-c property node for ivars, @@ -1087,6 +1129,16 @@ public: } }; +inline bool operator==(DIDerivedType::PtrAuthData Lhs, + DIDerivedType::PtrAuthData Rhs) { + return Lhs.RawData == Rhs.RawData; +} + +inline bool operator!=(DIDerivedType::PtrAuthData Lhs, + DIDerivedType::PtrAuthData Rhs) { + return !(Lhs == Rhs); +} + /// Composite types. /// /// TODO: Detach from DerivedTypeBase (split out MDEnumType?). diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 2e0f5ba82220..ad1fdf64015b 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5184,7 +5184,11 @@ bool LLParser::parseDIStringType(MDNode *&Result, bool IsDistinct) { /// ::= !DIDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0, /// line: 7, scope: !1, baseType: !2, size: 32, /// align: 32, offset: 0, flags: 0, extraData: !3, -/// dwarfAddressSpace: 3) +/// dwarfAddressSpace: 3, ptrAuthKey: 1, +/// ptrAuthIsAddressDiscriminated: true, +/// ptrAuthExtraDiscriminator: 0x1234, +/// ptrAuthIsaPointer: 1, ptrAuthAuthenticatesNullValues:1 +/// ) bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(tag, DwarfTagField, ); \ @@ -5199,19 +5203,30 @@ bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) { OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(extraData, MDField, ); \ OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX)); \ - OPTIONAL(annotations, MDField, ); + OPTIONAL(annotations, MDField, ); \ + OPTIONAL(ptrAuthKey, MDUnsignedField, (0, 7)); \ + OPTIONAL(ptrAuthIsAddressDiscriminated, MDBoolField, ); \ + OPTIONAL(ptrAuthExtraDiscriminator, MDUnsignedField, (0, 0xffff)); \ + OPTIONAL(ptrAuthIsaPointer, MDBoolField, ); \ + OPTIONAL(ptrAuthAuthenticatesNullValues, MDBoolField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS std::optional DWARFAddressSpace; if (dwarfAddressSpace.Val != UINT32_MAX) DWARFAddressSpace = dwarfAddressSpace.Val; + std::optional PtrAuthData; + if (ptrAuthKey.Val) + PtrAuthData.emplace( + (unsigned)ptrAuthKey.Val, ptrAuthIsAddressDiscriminated.Val, + (unsigned)ptrAuthExtraDiscriminator.Val, ptrAuthIsaPointer.Val, + ptrAuthAuthenticatesNullValues.Val); Result = GET_OR_DISTINCT(DIDerivedType, (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, size.Val, align.Val, - offset.Val, DWARFAddressSpace, flags.Val, - extraData.Val, annotations.Val)); + offset.Val, DWARFAddressSpace, PtrAuthData, + flags.Val, extraData.Val, annotations.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 770eb83af17f..3807320e7f17 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1556,7 +1556,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_DERIVED_TYPE: { - if (Record.size() < 12 || Record.size() > 14) + if (Record.size() < 12 || Record.size() > 15) return error("Invalid record"); // DWARF address space is encoded as N->getDWARFAddressSpace() + 1. 0 means @@ -1566,8 +1566,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( DWARFAddressSpace = Record[12] - 1; Metadata *Annotations = nullptr; - if (Record.size() > 13 && Record[13]) - Annotations = getMDOrNull(Record[13]); + std::optional PtrAuthData; + + // Only look for annotations/ptrauth if both are allocated. + // If not, we can't tell which was intended to be embedded, as both ptrauth + // and annotations have been expected at Record[13] at various times. + if (Record.size() > 14) { + if (Record[13]) + Annotations = getMDOrNull(Record[13]); + if (Record[14]) + PtrAuthData.emplace(Record[14]); + } IsDistinct = Record[0]; DINode::DIFlags Flags = static_cast(Record[10]); @@ -1577,7 +1586,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( getMDOrNull(Record[3]), Record[4], getDITypeRefOrNull(Record[5]), getDITypeRefOrNull(Record[6]), Record[7], Record[8], - Record[9], DWARFAddressSpace, Flags, + Record[9], DWARFAddressSpace, PtrAuthData, Flags, getDITypeRefOrNull(Record[11]), Annotations)), NextMetadataNo); NextMetadataNo++; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 6f0879a4e0ee..2e26e95064c3 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1829,6 +1829,11 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N, Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); + if (auto PtrAuthData = N->getPtrAuthData()) + Record.push_back(PtrAuthData->RawData); + else + Record.push_back(0); + Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev); Record.clear(); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index d462859e4894..c40beeeb925e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -803,6 +803,18 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) { if (DTy->getDWARFAddressSpace()) addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4, *DTy->getDWARFAddressSpace()); + if (auto PtrAuthData = DTy->getPtrAuthData()) { + addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_key, dwarf::DW_FORM_data1, + PtrAuthData->key()); + if (PtrAuthData->isAddressDiscriminated()) + addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_address_discriminated); + addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_extra_discriminator, + dwarf::DW_FORM_data2, PtrAuthData->extraDiscriminator()); + if (PtrAuthData->isaPointer()) + addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_isa_pointer); + if (PtrAuthData->authenticatesNullValues()) + addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_authenticates_null_values); + } } void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) { diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 19acc89f73fb..f65762123bf3 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2141,6 +2141,16 @@ static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N, Printer.printInt("dwarfAddressSpace", *DWARFAddressSpace, /* ShouldSkipZero */ false); Printer.printMetadata("annotations", N->getRawAnnotations()); + if (auto PtrAuthData = N->getPtrAuthData()) { + Printer.printInt("ptrAuthKey", PtrAuthData->key()); + Printer.printBool("ptrAuthIsAddressDiscriminated", + PtrAuthData->isAddressDiscriminated()); + Printer.printInt("ptrAuthExtraDiscriminator", + PtrAuthData->extraDiscriminator()); + Printer.printBool("ptrAuthIsaPointer", PtrAuthData->isaPointer()); + Printer.printBool("ptrAuthAuthenticatesNullValues", + PtrAuthData->authenticatesNullValues()); + } Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index c673abd8bc30..f484680bd6c9 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -296,7 +296,20 @@ DIStringType *DIBuilder::createStringType(StringRef Name, DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) { return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, 0, - 0, 0, std::nullopt, DINode::FlagZero); + 0, 0, std::nullopt, std::nullopt, DINode::FlagZero); +} + +DIDerivedType *DIBuilder::createPtrAuthQualifiedType( + DIType *FromTy, unsigned Key, bool IsAddressDiscriminated, + unsigned ExtraDiscriminator, bool IsaPointer, + bool AuthenticatesNullValues) { + return DIDerivedType::get(VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, "", + nullptr, 0, nullptr, FromTy, 0, 0, 0, std::nullopt, + std::optional( + std::in_place, Key, IsAddressDiscriminated, + ExtraDiscriminator, IsaPointer, + AuthenticatesNullValues), + DINode::FlagZero); } DIDerivedType * @@ -307,8 +320,8 @@ DIBuilder::createPointerType(DIType *PointeeTy, uint64_t SizeInBits, // FIXME: Why is there a name here? return DIDerivedType::get(VMContext, dwarf::DW_TAG_pointer_type, Name, nullptr, 0, nullptr, PointeeTy, SizeInBits, - AlignInBits, 0, DWARFAddressSpace, DINode::FlagZero, - nullptr, Annotations); + AlignInBits, 0, DWARFAddressSpace, std::nullopt, + DINode::FlagZero, nullptr, Annotations); } DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy, @@ -318,7 +331,8 @@ DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy, DINode::DIFlags Flags) { return DIDerivedType::get(VMContext, dwarf::DW_TAG_ptr_to_member_type, "", nullptr, 0, nullptr, PointeeTy, SizeInBits, - AlignInBits, 0, std::nullopt, Flags, Base); + AlignInBits, 0, std::nullopt, std::nullopt, Flags, + Base); } DIDerivedType * @@ -327,7 +341,7 @@ DIBuilder::createReferenceType(unsigned Tag, DIType *RTy, uint64_t SizeInBits, std::optional DWARFAddressSpace) { assert(RTy && "Unable to create reference type"); return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, RTy, - SizeInBits, AlignInBits, 0, DWARFAddressSpace, + SizeInBits, AlignInBits, 0, DWARFAddressSpace, {}, DINode::FlagZero); } @@ -338,15 +352,16 @@ DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name, DINodeArray Annotations) { return DIDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File, LineNo, getNonCompileUnitScope(Context), Ty, 0, - AlignInBits, 0, std::nullopt, Flags, nullptr, - Annotations); + AlignInBits, 0, std::nullopt, std::nullopt, Flags, + nullptr, Annotations); } DIDerivedType *DIBuilder::createFriend(DIType *Ty, DIType *FriendTy) { assert(Ty && "Invalid type!"); assert(FriendTy && "Invalid friend type!"); return DIDerivedType::get(VMContext, dwarf::DW_TAG_friend, "", nullptr, 0, Ty, - FriendTy, 0, 0, 0, std::nullopt, DINode::FlagZero); + FriendTy, 0, 0, 0, std::nullopt, std::nullopt, + DINode::FlagZero); } DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy, @@ -358,7 +373,7 @@ DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy, ConstantInt::get(IntegerType::get(VMContext, 32), VBPtrOffset)); return DIDerivedType::get(VMContext, dwarf::DW_TAG_inheritance, "", nullptr, 0, Ty, BaseTy, 0, 0, BaseOffset, std::nullopt, - Flags, ExtraData); + std::nullopt, Flags, ExtraData); } DIDerivedType *DIBuilder::createMemberType( @@ -368,7 +383,7 @@ DIDerivedType *DIBuilder::createMemberType( return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, getNonCompileUnitScope(Scope), Ty, SizeInBits, AlignInBits, OffsetInBits, std::nullopt, - Flags, nullptr, Annotations); + std::nullopt, Flags, nullptr, Annotations); } static ConstantAsMetadata *getConstantOrNull(Constant *C) { @@ -381,10 +396,10 @@ DIDerivedType *DIBuilder::createVariantMemberType( DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Constant *Discriminant, DINode::DIFlags Flags, DIType *Ty) { - return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, - LineNumber, getNonCompileUnitScope(Scope), Ty, - SizeInBits, AlignInBits, OffsetInBits, std::nullopt, - Flags, getConstantOrNull(Discriminant)); + return DIDerivedType::get( + VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, + getNonCompileUnitScope(Scope), Ty, SizeInBits, AlignInBits, OffsetInBits, + std::nullopt, std::nullopt, Flags, getConstantOrNull(Discriminant)); } DIDerivedType *DIBuilder::createBitFieldMemberType( @@ -395,7 +410,7 @@ DIDerivedType *DIBuilder::createBitFieldMemberType( return DIDerivedType::get( VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, getNonCompileUnitScope(Scope), Ty, SizeInBits, /*AlignInBits=*/0, - OffsetInBits, std::nullopt, Flags, + OffsetInBits, std::nullopt, std::nullopt, Flags, ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(VMContext, 64), StorageOffsetInBits)), Annotations); @@ -409,7 +424,8 @@ DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, Flags |= DINode::FlagStaticMember; return DIDerivedType::get(VMContext, Tag, Name, File, LineNumber, getNonCompileUnitScope(Scope), Ty, 0, AlignInBits, - 0, std::nullopt, Flags, getConstantOrNull(Val)); + 0, std::nullopt, std::nullopt, Flags, + getConstantOrNull(Val)); } DIDerivedType * @@ -420,7 +436,7 @@ DIBuilder::createObjCIVar(StringRef Name, DIFile *File, unsigned LineNumber, return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, getNonCompileUnitScope(File), Ty, SizeInBits, AlignInBits, OffsetInBits, std::nullopt, - Flags, PropertyNode); + std::nullopt, Flags, PropertyNode); } DIObjCProperty * @@ -555,10 +571,10 @@ DIDerivedType *DIBuilder::createSetType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, uint64_t SizeInBits, uint32_t AlignInBits, DIType *Ty) { - auto *R = - DIDerivedType::get(VMContext, dwarf::DW_TAG_set_type, Name, File, LineNo, - getNonCompileUnitScope(Scope), Ty, SizeInBits, - AlignInBits, 0, std::nullopt, DINode::FlagZero); + auto *R = DIDerivedType::get(VMContext, dwarf::DW_TAG_set_type, Name, File, + LineNo, getNonCompileUnitScope(Scope), Ty, + SizeInBits, AlignInBits, 0, std::nullopt, + std::nullopt, DINode::FlagZero); trackIfUnresolved(R); return R; } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index efde8bcc10e3..173696146299 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1336,9 +1336,9 @@ LLVMMetadataRef LLVMDIBuilderCreatePointerType( LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy, uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace, const char *Name, size_t NameLen) { - return wrap(unwrap(Builder)->createPointerType(unwrapDI(PointeeTy), - SizeInBits, AlignInBits, - AddressSpace, {Name, NameLen})); + return wrap(unwrap(Builder)->createPointerType( + unwrapDI(PointeeTy), SizeInBits, AlignInBits, AddressSpace, + {Name, NameLen})); } LLVMMetadataRef LLVMDIBuilderCreateStructType( diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index f37add2120f1..6e9cc51afcc1 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -34,6 +34,10 @@ cl::opt EnableFSDiscriminator( cl::desc("Enable adding flow sensitive discriminators")); } // namespace llvm +uint32_t DIType::getAlignInBits() const { + return (getTag() == dwarf::DW_TAG_LLVM_ptrauth_type ? 0 : SubclassData32); +} + const DIExpression::FragmentInfo DebugVariable::DefaultFragment = { std::numeric_limits::max(), std::numeric_limits::min()}; @@ -731,26 +735,32 @@ Constant *DIDerivedType::getDiscriminantValue() const { return nullptr; } -DIDerivedType * -DIDerivedType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, - Metadata *File, unsigned Line, Metadata *Scope, - Metadata *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, - Metadata *ExtraData, Metadata *Annotations, - StorageType Storage, bool ShouldCreate) { +DIDerivedType *DIDerivedType::getImpl( + LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, + unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData, + Metadata *Annotations, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIDerivedType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, - ExtraData, Annotations)); + AlignInBits, OffsetInBits, DWARFAddressSpace, + PtrAuthData, Flags, ExtraData, Annotations)); Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData, Annotations}; DEFINE_GETIMPL_STORE(DIDerivedType, (Tag, Line, SizeInBits, AlignInBits, OffsetInBits, - DWARFAddressSpace, Flags), + DWARFAddressSpace, PtrAuthData, Flags), Ops); } +std::optional +DIDerivedType::getPtrAuthData() const { + return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type + ? std::optional(PtrAuthData(SubclassData32)) + : std::nullopt; +} + DICompositeType *DICompositeType::getImpl( LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index b1dcb262fb65..00af694e553f 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -540,6 +540,7 @@ template <> struct MDNodeKeyImpl { uint64_t OffsetInBits; uint32_t AlignInBits; std::optional DWARFAddressSpace; + std::optional PtrAuthData; unsigned Flags; Metadata *ExtraData; Metadata *Annotations; @@ -547,18 +548,21 @@ template <> struct MDNodeKeyImpl { MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, unsigned Flags, - Metadata *ExtraData, Metadata *Annotations) + std::optional DWARFAddressSpace, + std::optional PtrAuthData, + unsigned Flags, Metadata *ExtraData, Metadata *Annotations) : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace), - Flags(Flags), ExtraData(ExtraData), Annotations(Annotations) {} + PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData), + Annotations(Annotations) {} MDNodeKeyImpl(const DIDerivedType *N) : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()), - DWARFAddressSpace(N->getDWARFAddressSpace()), Flags(N->getFlags()), + DWARFAddressSpace(N->getDWARFAddressSpace()), + PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()), ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {} bool isKeyOf(const DIDerivedType *RHS) const { @@ -569,7 +573,8 @@ template <> struct MDNodeKeyImpl { AlignInBits == RHS->getAlignInBits() && OffsetInBits == RHS->getOffsetInBits() && DWARFAddressSpace == RHS->getDWARFAddressSpace() && - Flags == RHS->getFlags() && ExtraData == RHS->getRawExtraData() && + PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() && + ExtraData == RHS->getRawExtraData() && Annotations == RHS->getRawAnnotations(); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 62dde2e6ad42..a923f5e2a34e 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1235,6 +1235,7 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) { N.getTag() == dwarf::DW_TAG_volatile_type || N.getTag() == dwarf::DW_TAG_restrict_type || N.getTag() == dwarf::DW_TAG_atomic_type || + N.getTag() == dwarf::DW_TAG_LLVM_ptrauth_type || N.getTag() == dwarf::DW_TAG_member || (N.getTag() == dwarf::DW_TAG_variable && N.isStaticMember()) || N.getTag() == dwarf::DW_TAG_inheritance || diff --git a/llvm/test/Assembler/debug-info.ll b/llvm/test/Assembler/debug-info.ll index 419623a2cb7d..06144b261373 100644 --- a/llvm/test/Assembler/debug-info.ll +++ b/llvm/test/Assembler/debug-info.ll @@ -1,8 +1,8 @@ ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s ; RUN: verify-uselistorder %s -; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39} -!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42} +; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43} +!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46} ; CHECK: !0 = !DISubrange(count: 3, lowerBound: 0) ; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4) @@ -99,3 +99,15 @@ ; CHECK-NEXT: !39 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagLittleEndian) !41 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagBigEndian) !42 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagLittleEndian) + +; CHECK: !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !13, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: false, ptrAuthAuthenticatesNullValues: false) +!43 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !15, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234) + +; CHECK: !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !13, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: false) +!44 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !15, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true) + +; CHECK: !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !13, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: false, ptrAuthAuthenticatesNullValues: true) +!45 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !15, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthAuthenticatesNullValues: true) + +; CHECK: !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !13, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: true) +!46 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !15, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: true) diff --git a/llvm/test/DebugInfo/AArch64/ptrauth.ll b/llvm/test/DebugInfo/AArch64/ptrauth.ll new file mode 100644 index 000000000000..5d9099f05704 --- /dev/null +++ b/llvm/test/DebugInfo/AArch64/ptrauth.ll @@ -0,0 +1,70 @@ +; RUN: llc %s -filetype=obj -mtriple arm64e-apple-darwin -o - \ +; RUN: | llvm-dwarfdump - | FileCheck %s + +; CHECK: DW_AT_type (0x{{0+}}[[TY:.*]] "void *__ptrauth(4, 0, 0x04d2)") +; CHECK: 0x{{0+}}[[TY]]: DW_TAG_LLVM_ptrauth_type +; CHECK-NEXT: DW_AT_type {{.*}}"void *" +; CHECK-NEXT: DW_AT_LLVM_ptrauth_key (0x04) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_extra_discriminator (0x04d2) + +; CHECK: DW_AT_type (0x{{0+}}[[TY:.*]] "void *__ptrauth(4, 1, 0x04d3)") +; CHECK: 0x{{0+}}[[TY]]: DW_TAG_LLVM_ptrauth_type +; CHECK-NEXT: DW_AT_type {{.*}}"void *" +; CHECK-NEXT: DW_AT_LLVM_ptrauth_key (0x04) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_address_discriminated (true) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_extra_discriminator (0x04d3) + +; CHECK: DW_AT_type (0x{{0+}}[[TY:.*]] "void *__ptrauth(4, 1, 0x04d4, "isa-pointer")") +; CHECK: 0x{{0+}}[[TY]]: DW_TAG_LLVM_ptrauth_type +; CHECK-NEXT: DW_AT_type {{.*}}"void *" +; CHECK-NEXT: DW_AT_LLVM_ptrauth_key (0x04) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_address_discriminated (true) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_extra_discriminator (0x04d4) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_isa_pointer (true) + +; CHECK: DW_AT_type (0x{{0+}}[[TY:.*]] "void *__ptrauth(4, 1, 0x04d5, "authenticates-null-values")") +; CHECK: 0x{{0+}}[[TY]]: DW_TAG_LLVM_ptrauth_type +; CHECK-NEXT: DW_AT_type {{.*}}"void *" +; CHECK-NEXT: DW_AT_LLVM_ptrauth_key (0x04) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_address_discriminated (true) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_extra_discriminator (0x04d5) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_authenticates_null_values (true) + +; CHECK: DW_AT_type (0x{{0+}}[[TY:.*]] "void *__ptrauth(4, 1, 0x04d6, "isa-pointer,authenticates-null-values")") +; CHECK: 0x{{0+}}[[TY]]: DW_TAG_LLVM_ptrauth_type +; CHECK-NEXT: DW_AT_type {{.*}}"void *" +; CHECK-NEXT: DW_AT_LLVM_ptrauth_key (0x04) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_address_discriminated (true) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_extra_discriminator (0x04d6) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_isa_pointer (true) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_authenticates_null_values (true) + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + +@p = global ptr null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!10} +!llvm.module.flags = !{!19, !20} + +!0 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression()) +!1 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) +!2 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) +!3 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression()) +!4 = !DIGlobalVariableExpression(var: !9, expr: !DIExpression()) +!5 = distinct !DIGlobalVariable(name: "p1", scope: !10, file: !11, line: 1, type: !14, isLocal: false, isDefinition: true) +!6 = distinct !DIGlobalVariable(name: "p2", scope: !10, file: !11, line: 1, type: !15, isLocal: false, isDefinition: true) +!7 = distinct !DIGlobalVariable(name: "p3", scope: !10, file: !11, line: 1, type: !16, isLocal: false, isDefinition: true) +!8 = distinct !DIGlobalVariable(name: "p4", scope: !10, file: !11, line: 1, type: !17, isLocal: false, isDefinition: true) +!9 = distinct !DIGlobalVariable(name: "p5", scope: !10, file: !11, line: 1, type: !18, isLocal: false, isDefinition: true) +!10 = distinct !DICompileUnit(language: DW_LANG_C99, file: !11, emissionKind: FullDebug, globals: !13) +!11 = !DIFile(filename: "/tmp/p.c", directory: "/") +!12 = !{} +!13 = !{!0,!1,!2,!3,!4} +!14 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !21, ptrAuthKey: 4, ptrAuthIsAddressDiscriminated: false, ptrAuthExtraDiscriminator: 1234) +!15 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !21, ptrAuthKey: 4, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1235) +!16 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !21, ptrAuthKey: 4, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1236, ptrAuthIsaPointer: true) +!17 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !21, ptrAuthKey: 4, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1237, ptrAuthAuthenticatesNullValues: true) +!18 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !21, ptrAuthKey: 4, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1238, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: true) +!19 = !{i32 2, !"Dwarf Version", i32 4} +!20 = !{i32 2, !"Debug Info Version", i32 3} +!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null) diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index ac27869b8c21..4c2e5f77a540 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -106,7 +106,7 @@ protected: DIType *getDerivedType() { return DIDerivedType::getDistinct( Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, - getBasicType("basictype"), 1, 2, 0, std::nullopt, DINode::FlagZero); + getBasicType("basictype"), 1, 2, 0, std::nullopt, {}, DINode::FlagZero); } Constant *getConstant() { return ConstantInt::get(Type::getInt32Ty(Context), Counter++); @@ -461,7 +461,7 @@ TEST_F(MDNodeTest, PrintTree) { auto *StructTy = cast(getCompositeType()); DIType *PointerTy = DIDerivedType::getDistinct( Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, StructTy, - 1, 2, 0, std::nullopt, DINode::FlagZero); + 1, 2, 0, std::nullopt, {}, DINode::FlagZero); StructTy->replaceElements(MDTuple::get(Context, PointerTy)); auto *Var = DILocalVariable::get(Context, Scope, "foo", File, @@ -1864,13 +1864,17 @@ TEST_F(DIDerivedTypeTest, get) { DIType *BaseType = getBasicType("basic"); MDTuple *ExtraData = getTuple(); unsigned DWARFAddressSpace = 8; + DIDerivedType::PtrAuthData PtrAuthData(1, false, 1234, true, true); + DIDerivedType::PtrAuthData PtrAuthData2(1, false, 1234, true, false); DINode::DIFlags Flags5 = static_cast(5); DINode::DIFlags Flags4 = static_cast(4); - auto *N = - DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, - 1, Scope, BaseType, 2, 3, 4, DWARFAddressSpace, Flags5, - ExtraData); + auto *N = DIDerivedType::get( + Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, + BaseType, 2, 3, 4, DWARFAddressSpace, std::nullopt, Flags5, ExtraData); + auto *N1 = DIDerivedType::get(Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", + File, 1, Scope, N, 2, 3, 4, DWARFAddressSpace, + PtrAuthData, Flags5, ExtraData); EXPECT_EQ(dwarf::DW_TAG_pointer_type, N->getTag()); EXPECT_EQ("something", N->getName()); EXPECT_EQ(File, N->getFile()); @@ -1881,53 +1885,73 @@ TEST_F(DIDerivedTypeTest, get) { EXPECT_EQ(3u, N->getAlignInBits()); EXPECT_EQ(4u, N->getOffsetInBits()); EXPECT_EQ(DWARFAddressSpace, *N->getDWARFAddressSpace()); + EXPECT_EQ(std::nullopt, N->getPtrAuthData()); + EXPECT_EQ(PtrAuthData, N1->getPtrAuthData()); + EXPECT_NE(PtrAuthData2, N1->getPtrAuthData()); EXPECT_EQ(5u, N->getFlags()); EXPECT_EQ(ExtraData, N->getExtraData()); EXPECT_EQ(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags5, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_reference_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags5, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "else", - File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags5, ExtraData)); + File, 1, Scope, BaseType, 2, 3, 4, + DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", getFile(), 1, Scope, BaseType, 2, - 3, 4, DWARFAddressSpace, Flags5, ExtraData)); + 3, 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 2, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags5, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, getSubprogram(), - BaseType, 2, 3, 4, DWARFAddressSpace, Flags5, - ExtraData)); + BaseType, 2, 3, 4, DWARFAddressSpace, + std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get( Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, getBasicType("basic2"), 2, 3, 4, DWARFAddressSpace, - Flags5, ExtraData)); + std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 3, 3, - 4, DWARFAddressSpace, Flags5, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 2, - 4, DWARFAddressSpace, Flags5, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 5, DWARFAddressSpace, Flags5, ExtraData)); + 5, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace + 1, Flags5, ExtraData)); + 4, DWARFAddressSpace + 1, std::nullopt, + Flags5, ExtraData)); + EXPECT_NE(N1, + DIDerivedType::get(Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", + File, 1, Scope, N, 2, 3, 4, DWARFAddressSpace, + std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags4, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags4, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags5, getTuple())); + 4, DWARFAddressSpace, std::nullopt, Flags5, + getTuple())); TempDIDerivedType Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); + TempDIDerivedType Temp1 = N1->clone(); + EXPECT_EQ(N1, MDNode::replaceWithUniqued(std::move(Temp1))); } TEST_F(DIDerivedTypeTest, getWithLargeValues) { @@ -1937,14 +1961,23 @@ TEST_F(DIDerivedTypeTest, getWithLargeValues) { MDTuple *ExtraData = getTuple(); DINode::DIFlags Flags = static_cast(5); - auto *N = DIDerivedType::get( - Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, - BaseType, UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, - Flags, ExtraData); + auto *N = DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", + File, 1, Scope, BaseType, UINT64_MAX, + UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, + std::nullopt, Flags, ExtraData); EXPECT_EQ(UINT64_MAX, N->getSizeInBits()); EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits()); EXPECT_EQ(UINT64_MAX - 2, N->getOffsetInBits()); EXPECT_EQ(UINT32_MAX - 3, *N->getDWARFAddressSpace()); + + auto *N1 = DIDerivedType::get( + Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", File, 1, Scope, N, + UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, + DIDerivedType::PtrAuthData(7, true, 0xffff, true, false), Flags, + ExtraData); + EXPECT_EQ(7U, N1->getPtrAuthData()->key()); + EXPECT_EQ(true, N1->getPtrAuthData()->isAddressDiscriminated()); + EXPECT_EQ(0xffffU, N1->getPtrAuthData()->extraDiscriminator()); } typedef MetadataTest DICompositeTypeTest; @@ -4289,7 +4322,7 @@ TEST_F(MDTupleAllocationTest, Tracking2) { #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) && !defined(GTEST_HAS_SEH) typedef MetadataTest MDTupleAllocationDeathTest; TEST_F(MDTupleAllocationDeathTest, ResizeRejected) { - MDTuple *A = MDTuple::get(Context, None); + MDTuple *A = MDTuple::get(Context, std::nullopt); auto *Value1 = getConstantAsMetadata(); EXPECT_DEATH(A->push_back(Value1), "Resizing is not supported for uniqued nodes"); diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp index e7e314f739fa..1248de3db070 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -163,7 +163,8 @@ llvm::DIDerivedType *DebugTranslation::translateImpl(DIDerivedTypeAttr attr) { /*File=*/nullptr, /*Line=*/0, /*Scope=*/nullptr, translate(attr.getBaseType()), attr.getSizeInBits(), attr.getAlignInBits(), attr.getOffsetInBits(), - /*DWARFAddressSpace=*/std::nullopt, /*Flags=*/llvm::DINode::FlagZero); + /*DWARFAddressSpace=*/std::nullopt, /*PtrAuthData=*/std::nullopt, + /*Flags=*/llvm::DINode::FlagZero); } llvm::DIFile *DebugTranslation::translateImpl(DIFileAttr attr) { -- GitLab From ff60a84f04b4d8af63d581d4f9dd7ab0196a200e Mon Sep 17 00:00:00 2001 From: Malay Sanghi Date: Tue, 19 Mar 2024 14:15:29 +0800 Subject: [PATCH 020/307] Convert copy to r-value reference. (#85606) That seems to be the intention based on calling code. --- llvm/include/llvm/CodeGen/MachinePassManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h index b1166e3a3fd5..3faffe5c4cab 100644 --- a/llvm/include/llvm/CodeGen/MachinePassManager.h +++ b/llvm/include/llvm/CodeGen/MachinePassManager.h @@ -56,7 +56,7 @@ struct MachinePassConcept }; template struct MachinePassModel : MachinePassConcept { - explicit MachinePassModel(PassT Pass) : Pass(std::move(Pass)) {} + explicit MachinePassModel(PassT &&Pass) : Pass(std::move(Pass)) {} // We have to explicitly define all the special member functions because MSVC // refuses to generate them. MachinePassModel(const MachinePassModel &Arg) : Pass(Arg.Pass) {} -- GitLab From b1752ddf0a97969cdd931e6431c953cfd4079e50 Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Tue, 19 Mar 2024 15:38:16 +0900 Subject: [PATCH 021/307] [mlir][sparse] Fix memory leaks (part 4) (#85729) This commit fixes memory leaks in sparse tensor integration tests by adding `bufferization.dealloc_tensor` ops. Note: Buffer deallocation will be automated in the future with the ownership-based buffer deallocation pass, making `dealloc_tensor` obsolete (only codegen path, not when using the runtime library). This commit fixes the remaining memory leaks in the MLIR test suite. `check-mlir` now passes when built with ASAN. --- .../Dialect/SparseTensor/CPU/reshape_dot.mlir | 20 +++++++++++++-- .../SparseTensor/CPU/sparse_block_matmul.mlir | 8 ++++++ .../Dialect/SparseTensor/CPU/sparse_pack.mlir | 25 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/mlir/test/Integration/Dialect/SparseTensor/CPU/reshape_dot.mlir b/mlir/test/Integration/Dialect/SparseTensor/CPU/reshape_dot.mlir index ebf9f4392d85..f7975e0738fa 100644 --- a/mlir/test/Integration/Dialect/SparseTensor/CPU/reshape_dot.mlir +++ b/mlir/test/Integration/Dialect/SparseTensor/CPU/reshape_dot.mlir @@ -35,8 +35,8 @@ #COO_3D = #sparse_tensor.encoding<{ map = (d0, d1, d2) -> (d0 : compressed(nonunique), d1 : singleton(nonunique), d2 : singleton), posWidth = 32, crdWidth = 32 }> module { - func.func private @printMemref3dF32(%ptr : tensor) attributes { llvm.emit_c_interface } - func.func private @printMemref2dF32(%ptr : tensor) attributes { llvm.emit_c_interface } + func.func private @printMemref3dF32(%ptr : tensor {bufferization.access = "read"}) attributes { llvm.emit_c_interface } + func.func private @printMemref2dF32(%ptr : tensor {bufferization.access = "read"}) attributes { llvm.emit_c_interface } func.func @test_sparse_rhs(%arg0: tensor<5x6xf32>, %arg1: tensor<6x2x3xf32, #COO_3D>) -> tensor { %collapsed = tensor.collapse_shape %arg1 [[0], [1, 2]] : tensor<6x2x3xf32, #COO_3D> into tensor<6x6xf32, #COO_2D> @@ -46,6 +46,11 @@ module { %2 = linalg.matmul ins(%arg0, %collapsed : tensor<5x6xf32>, tensor<6x6xf32, #COO_2D>) outs(%1 : tensor<5x6xf32>) -> tensor<5x6xf32> %expanded = tensor.expand_shape %2 [[0], [1, 2]] : tensor<5x6xf32> into tensor<5x2x3xf32> %ret1 = tensor.cast %expanded : tensor<5x2x3xf32> to tensor + + // Note: tensor.collapse_shape is a metadata-only operation on dense tensors + // but requires reallocation on sparse tensors. + bufferization.dealloc_tensor %collapsed : tensor<6x6xf32, #COO_2D> + return %ret1 : tensor } @@ -57,6 +62,11 @@ module { %2 = linalg.matmul ins(%arg0, %collapsed : tensor<5x6xf32, #COO_2D>, tensor<6x6xf32, #COO_2D>) outs(%1 : tensor<5x6xf32>) -> tensor<5x6xf32> %expanded = tensor.expand_shape %2 [[0], [1, 2]] : tensor<5x6xf32> into tensor<5x2x3xf32> %ret1 = tensor.cast %expanded : tensor<5x2x3xf32> to tensor + + // Note: tensor.collapse_shape is a metadata-only operation on dense tensors + // but requires reallocation on sparse tensors. + bufferization.dealloc_tensor %collapsed : tensor<6x6xf32, #COO_2D> + return %ret1 : tensor } @@ -80,6 +90,11 @@ module { %2 = linalg.matmul ins(%arg0, %collapsed : tensor<5x6xf32, #COO_2D>, tensor<6x6xf32, #COO_2D>) outs(%1 : tensor<5x6xf32>) -> tensor<5x6xf32> %expanded = tensor.expand_shape %2 [[0], [1, 2]] : tensor<5x6xf32> into tensor<5x2x3xf32> %ret1 = tensor.cast %expanded : tensor<5x2x3xf32> to tensor + + // Note: tensor.collapse_shape is a metadata-only operation on dense tensors + // but requires reallocation on sparse tensors. + bufferization.dealloc_tensor %collapsed : tensor<6x6xf32, #COO_2D> + return %ret1 : tensor } @@ -192,6 +207,7 @@ module { bufferization.dealloc_tensor %so1 : tensor bufferization.dealloc_tensor %so2 : tensor bufferization.dealloc_tensor %so3 : tensor + return } } diff --git a/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_block_matmul.mlir b/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_block_matmul.mlir index 464de9c8a2c3..efef01155cc7 100644 --- a/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_block_matmul.mlir +++ b/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_block_matmul.mlir @@ -161,6 +161,14 @@ module { call @dump_dense_f64(%s24) : (tensor<4x4xf64>) -> () call @dump_dense_f64(%scsr) : (tensor<4x4xf64>) -> () + bufferization.dealloc_tensor %a : tensor<4x8xf64, #BSR> + bufferization.dealloc_tensor %b : tensor<4x8xf64, #NV_24> + bufferization.dealloc_tensor %c : tensor<4x8xf64, #CSR> + bufferization.dealloc_tensor %d : tensor<4x4xf64> + bufferization.dealloc_tensor %s : tensor<4x4xf64> + bufferization.dealloc_tensor %s24 : tensor<4x4xf64> + bufferization.dealloc_tensor %scsr : tensor<4x4xf64> + return } } diff --git a/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_pack.mlir b/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_pack.mlir index 7cde6b93d325..34d450c2403f 100644 --- a/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_pack.mlir +++ b/mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_pack.mlir @@ -279,6 +279,31 @@ module { %si = tensor.extract %li[] : tensor vector.print %si : i64 + // TODO: This check is no longer needed once the codegen path uses the + // buffer deallocation pass. "dealloc_tensor" turn into a no-op in the + // codegen path. + %has_runtime = sparse_tensor.has_runtime_library + scf.if %has_runtime { + // sparse_tensor.assemble copies buffers when running with the runtime + // library. Deallocations are needed not needed when running in codgen + // mode. + bufferization.dealloc_tensor %s4 : tensor<10x10xf64, #SortedCOO> + bufferization.dealloc_tensor %s5 : tensor<10x10xf64, #SortedCOOI32> + bufferization.dealloc_tensor %csr : tensor<2x2xf64, #CSR> + bufferization.dealloc_tensor %bs : tensor<2x10x10xf64, #BCOO> + } + + bufferization.dealloc_tensor %li : tensor + bufferization.dealloc_tensor %od : tensor<3xf64> + bufferization.dealloc_tensor %op : tensor<2xi32> + bufferization.dealloc_tensor %oi : tensor<3x2xi32> + bufferization.dealloc_tensor %d_csr : tensor<4xf64> + bufferization.dealloc_tensor %p_csr : tensor<3xi32> + bufferization.dealloc_tensor %i_csr : tensor<3xi32> + bufferization.dealloc_tensor %bod : tensor<6xf64> + bufferization.dealloc_tensor %bop : tensor<4xindex> + bufferization.dealloc_tensor %boi : tensor<6x2xindex> + return } } -- GitLab From cb2ca23345d3d9bde027a18d301949e8bdf606a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 19 Mar 2024 08:48:57 +0200 Subject: [PATCH 022/307] [llvm-shlib] Fix the version naming style of libLLVM for Windows (#85710) This reverts the changes from 91a384621e5b762d9c173ffd247cfeadd5f436a2 for Windows targets. The changes in that commit don't work as expected for Windows targets (those parts of llvm_add_library don't quite behave the same for Windows), while the previous status quo (producing a library named "libLLVM-.dll") is the defacto standard way of doing versioned library names there, contrary to on Unix. After that commit, the library always ended up named "libLLVM.dll", executables linking against it would reference "libLLVM.dll", and "libLLVM-.dll" was provided as a symlink. Thus revert this bit back to as it were, so that executables actually link against a versioned libLLVM, and no separate symlink is needed. The only thing that might be improved compared to the status quo as it was before these changes, is that the import library is named "lib/libLLVM-.dll.a", while the common style would be to name it plainly "lib/libLLVM.dll.a" (even while it produces references to "libLLVM-.dll", but none of these had that effect for Windows targets. (As a side note, the llvm-shlib library can be built for MinGW, but not currently in MSVC configurations.) --- llvm/tools/llvm-shlib/CMakeLists.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/llvm/tools/llvm-shlib/CMakeLists.txt b/llvm/tools/llvm-shlib/CMakeLists.txt index 0ad350bcbe0d..b20ac318e768 100644 --- a/llvm/tools/llvm-shlib/CMakeLists.txt +++ b/llvm/tools/llvm-shlib/CMakeLists.txt @@ -33,9 +33,13 @@ if(LLVM_BUILD_LLVM_DYLIB) if (LLVM_LINK_LLVM_DYLIB) set(INSTALL_WITH_TOOLCHAIN INSTALL_WITH_TOOLCHAIN) endif() - add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB OUTPUT_NAME LLVM ${INSTALL_WITH_TOOLCHAIN} ${SOURCES}) - # Add symlink for backwards compatibility with old library name - llvm_install_library_symlink(LLVM-${LLVM_VERSION_MAJOR}${LLVM_VERSION_SUFFIX} $ SHARED FULL_DEST COMPONENT LLVM) + if (WIN32) + add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB SONAME ${INSTALL_WITH_TOOLCHAIN} ${SOURCES}) + else() + add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB OUTPUT_NAME LLVM ${INSTALL_WITH_TOOLCHAIN} ${SOURCES}) + # Add symlink for backwards compatibility with old library name + llvm_install_library_symlink(LLVM-${LLVM_VERSION_MAJOR}${LLVM_VERSION_SUFFIX} $ SHARED FULL_DEST COMPONENT LLVM) + endif() list(REMOVE_DUPLICATES LIB_NAMES) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") -- GitLab From f0a5e5055029e9ab1c49a8580f09fa4c0e172ee1 Mon Sep 17 00:00:00 2001 From: Adrian Kuegel Date: Tue, 19 Mar 2024 06:53:14 +0000 Subject: [PATCH 023/307] [llvm][NVPTX] Add missing feature guard. --- llvm/test/CodeGen/NVPTX/dynamic_stackalloc.ll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/CodeGen/NVPTX/dynamic_stackalloc.ll b/llvm/test/CodeGen/NVPTX/dynamic_stackalloc.ll index 2db0c67800a2..09297fb819ce 100644 --- a/llvm/test/CodeGen/NVPTX/dynamic_stackalloc.ll +++ b/llvm/test/CodeGen/NVPTX/dynamic_stackalloc.ll @@ -3,7 +3,7 @@ ; RUN: llc < %s -march=nvptx -mattr=+ptx73 -mcpu=sm_52 | FileCheck %s --check-prefixes=CHECK,CHECK-32 ; RUN: llc < %s -march=nvptx64 -mattr=+ptx73 -mcpu=sm_52 | FileCheck %s --check-prefixes=CHECK,CHECK-64 -; RUN: %if ptxas %{ llc < %s -march=nvptx -mattr=+ptx73 -mcpu=sm_52 | %ptxas-verify %} +; RUN: %if ptxas && !ptxas-12.0 %{ llc < %s -march=nvptx -mattr=+ptx73 -mcpu=sm_52 | %ptxas-verify %} ; RUN: %if ptxas %{ llc < %s -march=nvptx64 -mattr=+ptx73 -mcpu=sm_52 | %ptxas-verify %} ; CHECK-FAILS: in function test_dynamic_stackalloc{{.*}}: Support for dynamic alloca introduced in PTX ISA version 7.3 and requires target sm_52. @@ -41,4 +41,4 @@ define i32 @test_dynamic_stackalloc(i64 %n) { ret i32 %call } -declare i32 @bar(ptr) \ No newline at end of file +declare i32 @bar(ptr) -- GitLab From 110f630105aed0670d82427fea55afbabc4a94c4 Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Tue, 19 Mar 2024 07:04:36 +0000 Subject: [PATCH 024/307] [KnownBits] Remove useless lambdas from unit test --- llvm/unittests/Support/KnownBitsTest.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/llvm/unittests/Support/KnownBitsTest.cpp b/llvm/unittests/Support/KnownBitsTest.cpp index b867b6ca637d..48de0889fdf3 100644 --- a/llvm/unittests/Support/KnownBitsTest.cpp +++ b/llvm/unittests/Support/KnownBitsTest.cpp @@ -412,9 +412,7 @@ TEST(KnownBitsTest, BinaryExhaustive) { }, checkCorrectnessOnlyBinary); testBinaryOpExhaustive( - [](const KnownBits &Known1, const KnownBits &Known2) { - return KnownBits::urem(Known1, Known2); - }, + KnownBits::urem, [](const APInt &N1, const APInt &N2) -> std::optional { if (N2.isZero()) return std::nullopt; @@ -422,9 +420,7 @@ TEST(KnownBitsTest, BinaryExhaustive) { }, checkCorrectnessOnlyBinary); testBinaryOpExhaustive( - [](const KnownBits &Known1, const KnownBits &Known2) { - return KnownBits::srem(Known1, Known2); - }, + KnownBits::srem, [](const APInt &N1, const APInt &N2) -> std::optional { if (N2.isZero()) return std::nullopt; @@ -556,18 +552,14 @@ TEST(KnownBitsTest, BinaryExhaustive) { [](const APInt &N1, const APInt &N2) { return N1 * N2; }, checkCorrectnessOnlyBinary); testBinaryOpExhaustive( - [](const KnownBits &Known1, const KnownBits &Known2) { - return KnownBits::mulhs(Known1, Known2); - }, + KnownBits::mulhs, [](const APInt &N1, const APInt &N2) { unsigned Bits = N1.getBitWidth(); return (N1.sext(2 * Bits) * N2.sext(2 * Bits)).extractBits(Bits, Bits); }, checkCorrectnessOnlyBinary); testBinaryOpExhaustive( - [](const KnownBits &Known1, const KnownBits &Known2) { - return KnownBits::mulhu(Known1, Known2); - }, + KnownBits::mulhu, [](const APInt &N1, const APInt &N2) { unsigned Bits = N1.getBitWidth(); return (N1.zext(2 * Bits) * N2.zext(2 * Bits)).extractBits(Bits, Bits); -- GitLab From eb5623d10147d1069885ccaa57d81fae3260b926 Mon Sep 17 00:00:00 2001 From: Wang Pengcheng Date: Tue, 19 Mar 2024 15:40:55 +0800 Subject: [PATCH 025/307] [MacroFusion] Complete tests and fix indents --- llvm/test/TableGen/MacroFusion.td | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/llvm/test/TableGen/MacroFusion.td b/llvm/test/TableGen/MacroFusion.td index 05c970cbd224..f8d375931ab8 100644 --- a/llvm/test/TableGen/MacroFusion.td +++ b/llvm/test/TableGen/MacroFusion.td @@ -42,8 +42,8 @@ def TestBothFusionPredicate: Fusion<"test-both-fusion-predicate", "HasBothFusion def TestFusion: SimpleFusion<"test-fusion", "HasTestFusion", "Test Fusion", CheckOpcode<[Inst0]>, CheckAll<[ - CheckOpcode<[Inst1]>, - CheckRegOperand<0, X0> + CheckOpcode<[Inst1]>, + CheckRegOperand<0, X0> ]>>; let IsCommutable = 1 in @@ -51,8 +51,8 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta "Test Commutable Fusion", CheckOpcode<[Inst0]>, CheckAll<[ - CheckOpcode<[Inst1]>, - CheckRegOperand<0, X0> + CheckOpcode<[Inst1]>, + CheckRegOperand<0, X0> ]>>; // CHECK-PREDICATOR: #ifdef GET_Test_MACRO_FUSION_PRED_DECL @@ -177,6 +177,8 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta // CHECK-PREDICATOR-NEXT: #endif // Check that we have generated target subfeature. +// CHECK-SUBTARGET: { "test-both-fusion-predicate", "Test BothFusionPredicate", Test::TestBothFusionPredicate +// CHECK-SUBTARGET: { "test-commutable-fusion", "Test Commutable Fusion", Test::TestCommutableFusion // CHECK-SUBTARGET: { "test-fusion", "Test Fusion", Test::TestFusion // Check that we have generated `getMacroFusions()` function. -- GitLab From 59ff3adcc1310e22ab31163767e49b4edb20c6b4 Mon Sep 17 00:00:00 2001 From: martinboehme Date: Tue, 19 Mar 2024 08:44:08 +0100 Subject: [PATCH 026/307] [clang][dataflow][NFC] Rename `ControlFlowContext` to `AdornedCFG`. (#85640) This expresses better what the class actually does, and it reduces the number of `Context`s that we have in the codebase. A deprecated alias `ControlFlowContext` is available from the old header. --- clang/docs/tools/clang-formatted-files.txt | 3 +- .../clang/Analysis/FlowSensitive/AdornedCFG.h | 96 +++++++++++++++++++ .../FlowSensitive/ControlFlowContext.h | 77 +-------------- .../Analysis/FlowSensitive/DataflowAnalysis.h | 10 +- .../FlowSensitive/DataflowAnalysisContext.h | 8 +- .../clang/Analysis/FlowSensitive/Logger.h | 6 +- .../clang/Analysis/FlowSensitive/Transfer.h | 6 +- .../TypeErasedDataflowAnalysis.h | 4 +- ...{ControlFlowContext.cpp => AdornedCFG.cpp} | 21 ++-- .../lib/Analysis/FlowSensitive/CMakeLists.txt | 2 +- .../FlowSensitive/DataflowAnalysisContext.cpp | 10 +- .../lib/Analysis/FlowSensitive/HTMLLogger.cpp | 20 ++-- clang/lib/Analysis/FlowSensitive/Logger.cpp | 8 +- clang/lib/Analysis/FlowSensitive/Transfer.cpp | 19 ++-- .../TypeErasedDataflowAnalysis.cpp | 40 ++++---- .../FlowSensitive/DeterminismTest.cpp | 8 +- .../Analysis/FlowSensitive/LoggerTest.cpp | 2 +- .../Analysis/FlowSensitive/TestingSupport.h | 15 +-- .../TypeErasedDataflowAnalysisTest.cpp | 10 +- 19 files changed, 194 insertions(+), 171 deletions(-) create mode 100644 clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h rename clang/lib/Analysis/FlowSensitive/{ControlFlowContext.cpp => AdornedCFG.cpp} (89%) diff --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt index 40ab76fa26a9..70687c23b15e 100644 --- a/clang/docs/tools/clang-formatted-files.txt +++ b/clang/docs/tools/clang-formatted-files.txt @@ -122,6 +122,7 @@ clang/include/clang/Analysis/MacroExpansionContext.h clang/include/clang/Analysis/Analyses/CalledOnceCheck.h clang/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h +clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h @@ -306,7 +307,7 @@ clang/include/clang-c/Index.h clang/lib/Analysis/CalledOnceCheck.cpp clang/lib/Analysis/CloneDetection.cpp clang/lib/Analysis/CodeInjector.cpp -clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp +clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp clang/lib/Analysis/FlowSensitive/DebugSupport.cpp diff --git a/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h b/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h new file mode 100644 index 000000000000..420f13ce11bf --- /dev/null +++ b/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h @@ -0,0 +1,96 @@ +//===-- AdornedCFG.h ------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines an AdornedCFG class that is used by dataflow analyses that +// run over Control-Flow Graphs (CFGs). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Stmt.h" +#include "clang/Analysis/CFG.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Error.h" +#include +#include + +namespace clang { +namespace dataflow { + +/// Holds CFG with additional information derived from it that is needed to +/// perform dataflow analysis. +class AdornedCFG { +public: + /// Builds an `AdornedCFG` from a `FunctionDecl`. + /// `Func.doesThisDeclarationHaveABody()` must be true, and + /// `Func.isTemplated()` must be false. + static llvm::Expected build(const FunctionDecl &Func); + + /// Builds an `AdornedCFG` from an AST node. `D` is the function in which + /// `S` resides. `D.isTemplated()` must be false. + static llvm::Expected build(const Decl &D, Stmt &S, + ASTContext &C); + + /// Returns the `Decl` containing the statement used to construct the CFG, if + /// available. + const Decl &getDecl() const { return ContainingDecl; } + + /// Returns the CFG that is stored in this context. + const CFG &getCFG() const { return *Cfg; } + + /// Returns a mapping from statements to basic blocks that contain them. + const llvm::DenseMap &getStmtToBlock() const { + return StmtToBlock; + } + + /// Returns whether `B` is reachable from the entry block. + bool isBlockReachable(const CFGBlock &B) const { + return BlockReachable[B.getBlockID()]; + } + + /// Returns whether `B` contains an expression that is consumed in a + /// different block than `B` (i.e. the parent of the expression is in a + /// different block). + /// This happens if there is control flow within a full-expression (triggered + /// by `&&`, `||`, or the conditional operator). Note that the operands of + /// these operators are not the only expressions that can be consumed in a + /// different block. For example, in the function call + /// `f(&i, cond() ? 1 : 0)`, `&i` is in a different block than the `CallExpr`. + bool containsExprConsumedInDifferentBlock(const CFGBlock &B) const { + return ContainsExprConsumedInDifferentBlock.contains(&B); + } + +private: + AdornedCFG( + const Decl &D, std::unique_ptr Cfg, + llvm::DenseMap StmtToBlock, + llvm::BitVector BlockReachable, + llvm::DenseSet ContainsExprConsumedInDifferentBlock) + : ContainingDecl(D), Cfg(std::move(Cfg)), + StmtToBlock(std::move(StmtToBlock)), + BlockReachable(std::move(BlockReachable)), + ContainsExprConsumedInDifferentBlock( + std::move(ContainsExprConsumedInDifferentBlock)) {} + + /// The `Decl` containing the statement used to construct the CFG. + const Decl &ContainingDecl; + std::unique_ptr Cfg; + llvm::DenseMap StmtToBlock; + llvm::BitVector BlockReachable; + llvm::DenseSet ContainsExprConsumedInDifferentBlock; +}; + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H diff --git a/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h b/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h index 9a0a00f3c013..3972962d0b2d 100644 --- a/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h +++ b/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h @@ -6,89 +6,20 @@ // //===----------------------------------------------------------------------===// // -// This file defines a ControlFlowContext class that is used by dataflow -// analyses that run over Control-Flow Graphs (CFGs). +// This file defines a deprecated alias for AdornedCFG. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H -#include "clang/AST/ASTContext.h" -#include "clang/AST/Decl.h" -#include "clang/AST/Stmt.h" -#include "clang/Analysis/CFG.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/Support/Error.h" -#include -#include +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" namespace clang { namespace dataflow { -/// Holds CFG and other derived context that is needed to perform dataflow -/// analysis. -class ControlFlowContext { -public: - /// Builds a ControlFlowContext from a `FunctionDecl`. - /// `Func.doesThisDeclarationHaveABody()` must be true, and - /// `Func.isTemplated()` must be false. - static llvm::Expected build(const FunctionDecl &Func); - - /// Builds a ControlFlowContext from an AST node. `D` is the function in which - /// `S` resides. `D.isTemplated()` must be false. - static llvm::Expected build(const Decl &D, Stmt &S, - ASTContext &C); - - /// Returns the `Decl` containing the statement used to construct the CFG, if - /// available. - const Decl &getDecl() const { return ContainingDecl; } - - /// Returns the CFG that is stored in this context. - const CFG &getCFG() const { return *Cfg; } - - /// Returns a mapping from statements to basic blocks that contain them. - const llvm::DenseMap &getStmtToBlock() const { - return StmtToBlock; - } - - /// Returns whether `B` is reachable from the entry block. - bool isBlockReachable(const CFGBlock &B) const { - return BlockReachable[B.getBlockID()]; - } - - /// Returns whether `B` contains an expression that is consumed in a - /// different block than `B` (i.e. the parent of the expression is in a - /// different block). - /// This happens if there is control flow within a full-expression (triggered - /// by `&&`, `||`, or the conditional operator). Note that the operands of - /// these operators are not the only expressions that can be consumed in a - /// different block. For example, in the function call - /// `f(&i, cond() ? 1 : 0)`, `&i` is in a different block than the `CallExpr`. - bool containsExprConsumedInDifferentBlock(const CFGBlock &B) const { - return ContainsExprConsumedInDifferentBlock.contains(&B); - } - -private: - ControlFlowContext( - const Decl &D, std::unique_ptr Cfg, - llvm::DenseMap StmtToBlock, - llvm::BitVector BlockReachable, - llvm::DenseSet ContainsExprConsumedInDifferentBlock) - : ContainingDecl(D), Cfg(std::move(Cfg)), - StmtToBlock(std::move(StmtToBlock)), - BlockReachable(std::move(BlockReachable)), - ContainsExprConsumedInDifferentBlock( - std::move(ContainsExprConsumedInDifferentBlock)) {} - - /// The `Decl` containing the statement used to construct the CFG. - const Decl &ContainingDecl; - std::unique_ptr Cfg; - llvm::DenseMap StmtToBlock; - llvm::BitVector BlockReachable; - llvm::DenseSet ContainsExprConsumedInDifferentBlock; -}; +// This is a deprecated alias. Use `AdornedCFG` instead. +using ControlFlowContext = AdornedCFG; } // namespace dataflow } // namespace clang diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h index 3c84704d0d6c..67eccdd030dc 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -22,7 +22,7 @@ #include "clang/AST/ASTContext.h" #include "clang/Analysis/CFG.h" -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/DataflowLattice.h" #include "clang/Analysis/FlowSensitive/MatchSwitch.h" @@ -195,8 +195,7 @@ template llvm::Expected>>> runDataflowAnalysis( - const ControlFlowContext &CFCtx, AnalysisT &Analysis, - const Environment &InitEnv, + const AdornedCFG &ACFG, AnalysisT &Analysis, const Environment &InitEnv, std::function &)> PostVisitCFG = nullptr, @@ -218,7 +217,7 @@ runDataflowAnalysis( } auto TypeErasedBlockStates = runTypeErasedDataflowAnalysis( - CFCtx, Analysis, InitEnv, PostVisitCFGClosure, MaxBlockVisits); + ACFG, Analysis, InitEnv, PostVisitCFGClosure, MaxBlockVisits); if (!TypeErasedBlockStates) return TypeErasedBlockStates.takeError(); @@ -280,8 +279,7 @@ llvm::Expected> diagnoseFunction( Diagnoser, std::int64_t MaxSATIterations = 1'000'000'000, std::int32_t MaxBlockVisits = 20'000) { - llvm::Expected Context = - ControlFlowContext::build(FuncDecl); + llvm::Expected Context = AdornedCFG::build(FuncDecl); if (!Context) return Context.takeError(); diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h index 98bdf037880a..909a91059438 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h @@ -18,8 +18,8 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/AST/TypeOrdering.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/Arena.h" -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" #include "clang/Analysis/FlowSensitive/Solver.h" #include "clang/Analysis/FlowSensitive/StorageLocation.h" #include "clang/Analysis/FlowSensitive/Value.h" @@ -183,9 +183,9 @@ public: LLVM_DUMP_METHOD void dumpFlowCondition(Atom Token, llvm::raw_ostream &OS = llvm::dbgs()); - /// Returns the `ControlFlowContext` registered for `F`, if any. Otherwise, + /// Returns the `AdornedCFG` registered for `F`, if any. Otherwise, /// returns null. - const ControlFlowContext *getControlFlowContext(const FunctionDecl *F); + const AdornedCFG *getAdornedCFG(const FunctionDecl *F); const Options &getOptions() { return Opts; } @@ -296,7 +296,7 @@ private: llvm::DenseMap FlowConditionConstraints; const Formula *Invariant = nullptr; - llvm::DenseMap FunctionContexts; + llvm::DenseMap FunctionContexts; // Fields modeled by environments covered by this context. FieldSet ModeledFields; diff --git a/clang/include/clang/Analysis/FlowSensitive/Logger.h b/clang/include/clang/Analysis/FlowSensitive/Logger.h index f4bd39f6ed49..f2e64810d005 100644 --- a/clang/include/clang/Analysis/FlowSensitive/Logger.h +++ b/clang/include/clang/Analysis/FlowSensitive/Logger.h @@ -15,7 +15,7 @@ namespace clang::dataflow { // Forward declarations so we can use Logger anywhere in the framework. -class ControlFlowContext; +class AdornedCFG; class TypeErasedDataflowAnalysis; struct TypeErasedDataflowAnalysisState; @@ -40,8 +40,8 @@ public: /// Called by the framework as we start analyzing a new function or statement. /// Forms a pair with endAnalysis(). - virtual void beginAnalysis(const ControlFlowContext &, - TypeErasedDataflowAnalysis &) {} + virtual void beginAnalysis(const AdornedCFG &, TypeErasedDataflowAnalysis &) { + } virtual void endAnalysis() {} // At any time during the analysis, we're computing the state for some target diff --git a/clang/include/clang/Analysis/FlowSensitive/Transfer.h b/clang/include/clang/Analysis/FlowSensitive/Transfer.h index 7713df747cb7..ed148250d8eb 100644 --- a/clang/include/clang/Analysis/FlowSensitive/Transfer.h +++ b/clang/include/clang/Analysis/FlowSensitive/Transfer.h @@ -29,12 +29,12 @@ public: // `CurState` is the pending state currently associated with this block. These // are supplied separately as the pending state for the current block may not // yet be represented in `BlockToState`. - StmtToEnvMap(const ControlFlowContext &CFCtx, + StmtToEnvMap(const AdornedCFG &ACFG, llvm::ArrayRef> BlockToState, unsigned CurBlockID, const TypeErasedDataflowAnalysisState &CurState) - : CFCtx(CFCtx), BlockToState(BlockToState), CurBlockID(CurBlockID), + : ACFG(ACFG), BlockToState(BlockToState), CurBlockID(CurBlockID), CurState(CurState) {} /// Returns the environment of the basic block that contains `S`. @@ -42,7 +42,7 @@ public: const Environment *getEnvironment(const Stmt &S) const; private: - const ControlFlowContext &CFCtx; + const AdornedCFG &ACFG; llvm::ArrayRef> BlockToState; unsigned CurBlockID; const TypeErasedDataflowAnalysisState &CurState; diff --git a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h index a0ca7440230b..b3722bf3ec80 100644 --- a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h +++ b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h @@ -21,7 +21,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Stmt.h" #include "clang/Analysis/CFG.h" -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/DataflowLattice.h" @@ -146,7 +146,7 @@ struct TypeErasedDataflowAnalysisState { /// from converging. llvm::Expected>> runTypeErasedDataflowAnalysis( - const ControlFlowContext &CFCtx, TypeErasedDataflowAnalysis &Analysis, + const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &Analysis, const Environment &InitEnv, std::function diff --git a/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp similarity index 89% rename from clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp rename to clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp index 7c9f8fbb0a70..3813b8c3ee8a 100644 --- a/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp @@ -1,4 +1,4 @@ -//===- ControlFlowContext.cpp ---------------------------------------------===// +//===- AdornedCFG.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// // -// This file defines a ControlFlowContext class that is used by dataflow -// analyses that run over Control-Flow Graphs (CFGs). +// This file defines an `AdornedCFG` class that is used by dataflow analyses +// that run over Control-Flow Graphs (CFGs). // //===----------------------------------------------------------------------===// -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/Stmt.h" @@ -126,8 +126,7 @@ buildContainsExprConsumedInDifferentBlock( return Result; } -llvm::Expected -ControlFlowContext::build(const FunctionDecl &Func) { +llvm::Expected AdornedCFG::build(const FunctionDecl &Func) { if (!Func.doesThisDeclarationHaveABody()) return llvm::createStringError( std::make_error_code(std::errc::invalid_argument), @@ -136,8 +135,8 @@ ControlFlowContext::build(const FunctionDecl &Func) { return build(Func, *Func.getBody(), Func.getASTContext()); } -llvm::Expected -ControlFlowContext::build(const Decl &D, Stmt &S, ASTContext &C) { +llvm::Expected AdornedCFG::build(const Decl &D, Stmt &S, + ASTContext &C) { if (D.isTemplated()) return llvm::createStringError( std::make_error_code(std::errc::invalid_argument), @@ -175,9 +174,9 @@ ControlFlowContext::build(const Decl &D, Stmt &S, ASTContext &C) { llvm::DenseSet ContainsExprConsumedInDifferentBlock = buildContainsExprConsumedInDifferentBlock(*Cfg, StmtToBlock); - return ControlFlowContext(D, std::move(Cfg), std::move(StmtToBlock), - std::move(BlockReachable), - std::move(ContainsExprConsumedInDifferentBlock)); + return AdornedCFG(D, std::move(Cfg), std::move(StmtToBlock), + std::move(BlockReachable), + std::move(ContainsExprConsumedInDifferentBlock)); } } // namespace dataflow diff --git a/clang/lib/Analysis/FlowSensitive/CMakeLists.txt b/clang/lib/Analysis/FlowSensitive/CMakeLists.txt index 5af4ecfc9efa..a3b5d9adc24b 100644 --- a/clang/lib/Analysis/FlowSensitive/CMakeLists.txt +++ b/clang/lib/Analysis/FlowSensitive/CMakeLists.txt @@ -1,6 +1,6 @@ add_clang_library(clangAnalysisFlowSensitive + AdornedCFG.cpp Arena.cpp - ControlFlowContext.cpp DataflowAnalysisContext.cpp DataflowEnvironment.cpp Formula.cpp diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp index f4c4af022f51..d520539dd253 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp @@ -288,8 +288,8 @@ void DataflowAnalysisContext::dumpFlowCondition(Atom Token, } } -const ControlFlowContext * -DataflowAnalysisContext::getControlFlowContext(const FunctionDecl *F) { +const AdornedCFG * +DataflowAnalysisContext::getAdornedCFG(const FunctionDecl *F) { // Canonicalize the key: F = F->getDefinition(); if (F == nullptr) @@ -299,10 +299,10 @@ DataflowAnalysisContext::getControlFlowContext(const FunctionDecl *F) { return &It->second; if (F->doesThisDeclarationHaveABody()) { - auto CFCtx = ControlFlowContext::build(*F); + auto ACFG = AdornedCFG::build(*F); // FIXME: Handle errors. - assert(CFCtx); - auto Result = FunctionContexts.insert({F, std::move(*CFCtx)}); + assert(ACFG); + auto Result = FunctionContexts.insert({F, std::move(*ACFG)}); return &Result.first->second; } diff --git a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp index 6afd66d9dc6a..397a8d87e114 100644 --- a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp +++ b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp @@ -54,7 +54,7 @@ // //===----------------------------------------------------------------------===// -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/DebugSupport.h" #include "clang/Analysis/FlowSensitive/Logger.h" #include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h" @@ -162,7 +162,7 @@ class HTMLLogger : public Logger { llvm::raw_string_ostream JStringStream{JSON}; llvm::json::OStream JOS{JStringStream, /*Indent=*/2}; - const ControlFlowContext *CFC; + const AdornedCFG *ACFG; // Timeline of iterations of CFG block visitation. std::vector Iters; // Indexes in `Iters` of the iterations for each block. @@ -176,15 +176,15 @@ class HTMLLogger : public Logger { public: explicit HTMLLogger(StreamFactory Streams) : Streams(std::move(Streams)) {} - void beginAnalysis(const ControlFlowContext &CFC, + void beginAnalysis(const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &A) override { OS = Streams(); - this->CFC = &CFC; + this->ACFG = &ACFG; *OS << llvm::StringRef(HTMLLogger_html).split("").first; - BlockConverged.resize(CFC.getCFG().getNumBlockIDs()); + BlockConverged.resize(ACFG.getCFG().getNumBlockIDs()); - const auto &D = CFC.getDecl(); + const auto &D = ACFG.getDecl(); const auto &SM = A.getASTContext().getSourceManager(); *OS << ""; if (const auto *ND = dyn_cast<NamedDecl>(&D)) @@ -345,7 +345,7 @@ private: // tokens are associated with, and even which BB element (so that clicking // can select the right element). void writeCode() { - const auto &AST = CFC->getDecl().getASTContext(); + const auto &AST = ACFG->getDecl().getASTContext(); bool Invalid = false; // Extract the source code from the original file. @@ -353,7 +353,7 @@ private: // indentation to worry about), but we need the boundaries of particular // AST nodes and the printer doesn't provide this. auto Range = clang::Lexer::makeFileCharRange( - CharSourceRange::getTokenRange(CFC->getDecl().getSourceRange()), + CharSourceRange::getTokenRange(ACFG->getDecl().getSourceRange()), AST.getSourceManager(), AST.getLangOpts()); if (Range.isInvalid()) return; @@ -419,7 +419,7 @@ private: // Construct one TokenInfo per character in a flat array. // This is inefficient (chars in a token all have the same info) but simple. std::vector<TokenInfo> State(Code.size()); - for (const auto *Block : CFC->getCFG()) { + for (const auto *Block : ACFG->getCFG()) { unsigned EltIndex = 0; for (const auto& Elt : *Block) { ++EltIndex; @@ -480,7 +480,7 @@ private: // out to `dot` to turn it into an SVG. void writeCFG() { *OS << "<template data-copy='cfg'>\n"; - if (auto SVG = renderSVG(buildCFGDot(CFC->getCFG()))) + if (auto SVG = renderSVG(buildCFGDot(ACFG->getCFG()))) *OS << *SVG; else *OS << "Can't draw CFG: " << toString(SVG.takeError()); diff --git a/clang/lib/Analysis/FlowSensitive/Logger.cpp b/clang/lib/Analysis/FlowSensitive/Logger.cpp index 8c401df62e44..8f40768171c9 100644 --- a/clang/lib/Analysis/FlowSensitive/Logger.cpp +++ b/clang/lib/Analysis/FlowSensitive/Logger.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/FlowSensitive/Logger.h" -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h" #include "llvm/Support/WithColor.h" @@ -33,17 +33,17 @@ struct TextualLogger final : Logger { TextualLogger(llvm::raw_ostream &OS) : OS(OS), ShowColors(llvm::WithColor::defaultAutoDetectFunction()(OS)) {} - virtual void beginAnalysis(const ControlFlowContext &CFG, + virtual void beginAnalysis(const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &Analysis) override { { llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, /*Bold=*/true); OS << "=== Beginning data flow analysis ===\n"; } - auto &D = CFG.getDecl(); + auto &D = ACFG.getDecl(); D.print(OS); OS << "\n"; D.dump(OS); - CurrentCFG = &CFG.getCFG(); + CurrentCFG = &ACFG.getCFG(); CurrentCFG->print(OS, Analysis.getASTContext().getLangOpts(), ShowColors); CurrentAnalysis = &Analysis; } diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 8b44bcb4e3ca..19d6810cc98d 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -20,7 +20,7 @@ #include "clang/AST/OperationKinds.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtVisitor.h" -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/NoopAnalysis.h" #include "clang/Analysis/FlowSensitive/RecordOps.h" @@ -38,9 +38,9 @@ namespace clang { namespace dataflow { const Environment *StmtToEnvMap::getEnvironment(const Stmt &S) const { - auto BlockIt = CFCtx.getStmtToBlock().find(&ignoreCFGOmittedNodes(S)); - assert(BlockIt != CFCtx.getStmtToBlock().end()); - if (!CFCtx.isBlockReachable(*BlockIt->getSecond())) + auto BlockIt = ACFG.getStmtToBlock().find(&ignoreCFGOmittedNodes(S)); + assert(BlockIt != ACFG.getStmtToBlock().end()); + if (!ACFG.isBlockReachable(*BlockIt->getSecond())) return nullptr; if (BlockIt->getSecond()->getBlockID() == CurBlockID) return &CurState.Env; @@ -855,27 +855,26 @@ private: Env.canDescend(Options.ContextSensitiveOpts->Depth, F))) return; - const ControlFlowContext *CFCtx = - Env.getDataflowAnalysisContext().getControlFlowContext(F); - if (!CFCtx) + const AdornedCFG *ACFG = Env.getDataflowAnalysisContext().getAdornedCFG(F); + if (!ACFG) return; // FIXME: We don't support context-sensitive analysis of recursion, so // we should return early here if `F` is the same as the `FunctionDecl` // holding `S` itself. - auto ExitBlock = CFCtx->getCFG().getExit().getBlockID(); + auto ExitBlock = ACFG->getCFG().getExit().getBlockID(); auto CalleeEnv = Env.pushCall(S); // FIXME: Use the same analysis as the caller for the callee. Note, // though, that doing so would require support for changing the analysis's // ASTContext. - auto Analysis = NoopAnalysis(CFCtx->getDecl().getASTContext(), + auto Analysis = NoopAnalysis(ACFG->getDecl().getASTContext(), DataflowAnalysisOptions{Options}); auto BlockToOutputState = - dataflow::runDataflowAnalysis(*CFCtx, Analysis, CalleeEnv); + dataflow::runDataflowAnalysis(*ACFG, Analysis, CalleeEnv); assert(BlockToOutputState); assert(ExitBlock < BlockToOutputState->size()); diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 939247c047c6..721a11c20985 100644 --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -150,20 +150,19 @@ private: /// Holds data structures required for running dataflow analysis. struct AnalysisContext { - AnalysisContext(const ControlFlowContext &CFCtx, - TypeErasedDataflowAnalysis &Analysis, + AnalysisContext(const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &Analysis, const Environment &InitEnv, llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>> BlockStates) - : CFCtx(CFCtx), Analysis(Analysis), InitEnv(InitEnv), + : ACFG(ACFG), Analysis(Analysis), InitEnv(InitEnv), Log(*InitEnv.getDataflowAnalysisContext().getOptions().Log), BlockStates(BlockStates) { - Log.beginAnalysis(CFCtx, Analysis); + Log.beginAnalysis(ACFG, Analysis); } ~AnalysisContext() { Log.endAnalysis(); } /// Contains the CFG being analyzed. - const ControlFlowContext &CFCtx; + const AdornedCFG &ACFG; /// The analysis to be run. TypeErasedDataflowAnalysis &Analysis; /// Initial state to start the analysis. @@ -176,19 +175,19 @@ struct AnalysisContext { class PrettyStackTraceAnalysis : public llvm::PrettyStackTraceEntry { public: - PrettyStackTraceAnalysis(const ControlFlowContext &CFCtx, const char *Message) - : CFCtx(CFCtx), Message(Message) {} + PrettyStackTraceAnalysis(const AdornedCFG &ACFG, const char *Message) + : ACFG(ACFG), Message(Message) {} void print(raw_ostream &OS) const override { OS << Message << "\n"; OS << "Decl:\n"; - CFCtx.getDecl().dump(OS); + ACFG.getDecl().dump(OS); OS << "CFG:\n"; - CFCtx.getCFG().print(OS, LangOptions(), false); + ACFG.getCFG().print(OS, LangOptions(), false); } private: - const ControlFlowContext &CFCtx; + const AdornedCFG &ACFG; const char *Message; }; @@ -303,7 +302,7 @@ computeBlockInputState(const CFGBlock &Block, AnalysisContext &AC) { // See `NoreturnDestructorTest` for concrete examples. if (Block.succ_begin()->getReachableBlock() != nullptr && Block.succ_begin()->getReachableBlock()->hasNoReturnElement()) { - auto &StmtToBlock = AC.CFCtx.getStmtToBlock(); + auto &StmtToBlock = AC.ACFG.getStmtToBlock(); auto StmtBlock = StmtToBlock.find(Block.getTerminatorStmt()); assert(StmtBlock != StmtToBlock.end()); llvm::erase(Preds, StmtBlock->getSecond()); @@ -319,7 +318,7 @@ computeBlockInputState(const CFGBlock &Block, AnalysisContext &AC) { // all predecessors have expression state consumed in a different block. Environment::ExprJoinBehavior JoinBehavior = Environment::DiscardExprState; for (const CFGBlock *Pred : Preds) { - if (Pred && AC.CFCtx.containsExprConsumedInDifferentBlock(*Pred)) { + if (Pred && AC.ACFG.containsExprConsumedInDifferentBlock(*Pred)) { JoinBehavior = Environment::KeepExprState; break; } @@ -368,7 +367,7 @@ builtinTransferStatement(unsigned CurBlockID, const CFGStmt &Elt, AnalysisContext &AC) { const Stmt *S = Elt.getStmt(); assert(S != nullptr); - transfer(StmtToEnvMap(AC.CFCtx, AC.BlockStates, CurBlockID, InputState), *S, + transfer(StmtToEnvMap(AC.ACFG, AC.BlockStates, CurBlockID, InputState), *S, InputState.Env); } @@ -511,9 +510,8 @@ transferCFGBlock(const CFGBlock &Block, AnalysisContext &AC, // takes a `CFGElement` as input, but some expressions only show up as a // terminator condition, but not as a `CFGElement`. The condition of an if // statement is one such example. - transfer( - StmtToEnvMap(AC.CFCtx, AC.BlockStates, Block.getBlockID(), State), - *TerminatorCond, State.Env); + transfer(StmtToEnvMap(AC.ACFG, AC.BlockStates, Block.getBlockID(), State), + *TerminatorCond, State.Env); // If the transfer function didn't produce a value, create an atom so that // we have *some* value for the condition expression. This ensures that @@ -528,13 +526,13 @@ transferCFGBlock(const CFGBlock &Block, AnalysisContext &AC, llvm::Expected<std::vector<std::optional<TypeErasedDataflowAnalysisState>>> runTypeErasedDataflowAnalysis( - const ControlFlowContext &CFCtx, TypeErasedDataflowAnalysis &Analysis, + const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &Analysis, const Environment &InitEnv, std::function<void(const CFGElement &, const TypeErasedDataflowAnalysisState &)> PostVisitCFG, std::int32_t MaxBlockVisits) { - PrettyStackTraceAnalysis CrashInfo(CFCtx, "runTypeErasedDataflowAnalysis"); + PrettyStackTraceAnalysis CrashInfo(ACFG, "runTypeErasedDataflowAnalysis"); std::optional<Environment> MaybeStartingEnv; if (InitEnv.callStackSize() == 1) { @@ -544,7 +542,7 @@ runTypeErasedDataflowAnalysis( const Environment &StartingEnv = MaybeStartingEnv ? *MaybeStartingEnv : InitEnv; - const clang::CFG &CFG = CFCtx.getCFG(); + const clang::CFG &CFG = ACFG.getCFG(); PostOrderCFGView POV(&CFG); ForwardDataflowWorklist Worklist(CFG, &POV); @@ -557,7 +555,7 @@ runTypeErasedDataflowAnalysis( StartingEnv.fork()}; Worklist.enqueueSuccessors(&Entry); - AnalysisContext AC(CFCtx, Analysis, StartingEnv, BlockStates); + AnalysisContext AC(ACFG, Analysis, StartingEnv, BlockStates); std::int32_t BlockVisits = 0; while (const CFGBlock *Block = Worklist.dequeue()) { LLVM_DEBUG(llvm::dbgs() @@ -615,7 +613,7 @@ runTypeErasedDataflowAnalysis( // state set to `std::nullopt` at this point) to also analyze dead code. if (PostVisitCFG) { - for (const CFGBlock *Block : CFCtx.getCFG()) { + for (const CFGBlock *Block : ACFG.getCFG()) { // Skip blocks that were not evaluated. if (!BlockStates[Block->getBlockID()]) continue; diff --git a/clang/unittests/Analysis/FlowSensitive/DeterminismTest.cpp b/clang/unittests/Analysis/FlowSensitive/DeterminismTest.cpp index 5ba26a083203..e794bd4943f2 100644 --- a/clang/unittests/Analysis/FlowSensitive/DeterminismTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/DeterminismTest.cpp @@ -8,7 +8,7 @@ #include "TestingSupport.h" #include "clang/AST/Decl.h" -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/DataflowAnalysis.h" #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" @@ -34,14 +34,14 @@ std::string analyzeAndPrintExitCondition(llvm::StringRef Code) { const auto *Target = cast<FunctionDecl>(test::findValueDecl(AST.context(), "target")); Environment InitEnv(DACtx, *Target); - auto CFCtx = cantFail(ControlFlowContext::build(*Target)); + auto ACFG = cantFail(AdornedCFG::build(*Target)); NoopAnalysis Analysis(AST.context(), DataflowAnalysisOptions{}); - auto Result = runDataflowAnalysis(CFCtx, Analysis, InitEnv); + auto Result = runDataflowAnalysis(ACFG, Analysis, InitEnv); EXPECT_FALSE(!Result) << Result.takeError(); - Atom FinalFC = (*Result)[CFCtx.getCFG().getExit().getBlockID()] + Atom FinalFC = (*Result)[ACFG.getCFG().getExit().getBlockID()] ->Env.getFlowConditionToken(); std::string Textual; llvm::raw_string_ostream OS(Textual); diff --git a/clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp b/clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp index 57920c49a7d3..88630119ba8a 100644 --- a/clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp @@ -57,7 +57,7 @@ public: private: llvm::raw_string_ostream OS; - void beginAnalysis(const ControlFlowContext &, + void beginAnalysis(const AdornedCFG &, TypeErasedDataflowAnalysis &) override { logText("beginAnalysis()"); } diff --git a/clang/unittests/Analysis/FlowSensitive/TestingSupport.h b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h index b7cf6cc966ed..e3c7ff685f57 100644 --- a/clang/unittests/Analysis/FlowSensitive/TestingSupport.h +++ b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h @@ -28,7 +28,7 @@ #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/ASTMatchers/ASTMatchersInternal.h" #include "clang/Analysis/CFG.h" -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/DataflowAnalysis.h" #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" @@ -100,7 +100,7 @@ struct AnalysisOutputs { const FunctionDecl *Target; /// Contains the control flow graph built from the body of the `Target` /// function and is analyzed. - const ControlFlowContext &CFCtx; + const AdornedCFG &ACFG; /// The analysis to be run. TypeErasedDataflowAnalysis &Analysis; /// Initial state to start the analysis. @@ -261,9 +261,10 @@ checkDataflow(AnalysisInputs<AnalysisT> AI, llvm::errc::invalid_argument, "Could not find the target function."); // Build the control flow graph for the target function. - auto MaybeCFCtx = ControlFlowContext::build(*Target); - if (!MaybeCFCtx) return MaybeCFCtx.takeError(); - auto &CFCtx = *MaybeCFCtx; + auto MaybeACFG = AdornedCFG::build(*Target); + if (!MaybeACFG) + return MaybeACFG.takeError(); + auto &ACFG = *MaybeACFG; // Initialize states for running dataflow analysis. DataflowAnalysisContext DACtx(AI.SolverFactory(), @@ -271,7 +272,7 @@ checkDataflow(AnalysisInputs<AnalysisT> AI, Environment InitEnv(DACtx, *Target); auto Analysis = AI.MakeAnalysis(Context, InitEnv); - AnalysisOutputs AO{AnnotatedCode, Context, Target, CFCtx, + AnalysisOutputs AO{AnnotatedCode, Context, Target, ACFG, Analysis, InitEnv, {}}; // Additional test setup. @@ -283,7 +284,7 @@ checkDataflow(AnalysisInputs<AnalysisT> AI, // the post-analysis states for the CFG blocks that have been evaluated. llvm::Expected<std::vector<std::optional<TypeErasedDataflowAnalysisState>>> MaybeBlockStates = - runTypeErasedDataflowAnalysis(CFCtx, Analysis, InitEnv, + runTypeErasedDataflowAnalysis(ACFG, Analysis, InitEnv, TypeErasedPostVisitCFG, MaxBlockVisitsInAnalysis); if (!MaybeBlockStates) return MaybeBlockStates.takeError(); diff --git a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp index 9d05a0d6ca40..bea00ab1a1f0 100644 --- a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp @@ -66,20 +66,20 @@ protected: AST->getASTContext())); assert(Func != nullptr); - CFCtx = std::make_unique<ControlFlowContext>( - llvm::cantFail(ControlFlowContext::build(*Func))); + ACFG = + std::make_unique<AdornedCFG>(llvm::cantFail(AdornedCFG::build(*Func))); AnalysisT Analysis = MakeAnalysis(AST->getASTContext()); DACtx = std::make_unique<DataflowAnalysisContext>( std::make_unique<WatchedLiteralsSolver>()); Environment Env(*DACtx, *Func); - return runDataflowAnalysis(*CFCtx, Analysis, Env); + return runDataflowAnalysis(*ACFG, Analysis, Env); } /// Returns the `CFGBlock` containing `S` (and asserts that it exists). const CFGBlock *blockForStmt(const Stmt &S) { - const CFGBlock *Block = CFCtx->getStmtToBlock().lookup(&S); + const CFGBlock *Block = ACFG->getStmtToBlock().lookup(&S); assert(Block != nullptr); return Block; } @@ -105,7 +105,7 @@ protected: } std::unique_ptr<ASTUnit> AST; - std::unique_ptr<ControlFlowContext> CFCtx; + std::unique_ptr<AdornedCFG> ACFG; std::unique_ptr<DataflowAnalysisContext> DACtx; }; -- GitLab From eac68447adac3852524c66acac7ab64d90205f47 Mon Sep 17 00:00:00 2001 From: LLVM GN Syncbot <llvmgnsyncbot@gmail.com> Date: Tue, 19 Mar 2024 07:48:14 +0000 Subject: [PATCH 027/307] [gn build] Port 59ff3adcc131 --- .../gn/secondary/clang/lib/Analysis/FlowSensitive/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/utils/gn/secondary/clang/lib/Analysis/FlowSensitive/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Analysis/FlowSensitive/BUILD.gn index e69567c2d9c6..04f20211b3c7 100644 --- a/llvm/utils/gn/secondary/clang/lib/Analysis/FlowSensitive/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Analysis/FlowSensitive/BUILD.gn @@ -23,8 +23,8 @@ static_library("FlowSensitive") { target_gen_dir, ] sources = [ + "AdornedCFG.cpp", "Arena.cpp", - "ControlFlowContext.cpp", "DataflowAnalysisContext.cpp", "DataflowEnvironment.cpp", "DebugSupport.cpp", -- GitLab From b788e4655c4e06f6821bc220e5745d6a4f9d4d09 Mon Sep 17 00:00:00 2001 From: martinboehme <mboehme@google.com> Date: Tue, 19 Mar 2024 09:22:35 +0100 Subject: [PATCH 028/307] [clang][dataflow] Model assignment to derived class from base. (#85064) This is a relatively rare case, but - It's still nice to get this right, - We can remove the special case for this in `VisitCXXOperatorCallExpr()` (that simply bails out), and - With this in place, I can avoid having to add a similar special case in an upcoming patch. --- .../clang/Analysis/FlowSensitive/RecordOps.h | 6 +- .../lib/Analysis/FlowSensitive/RecordOps.cpp | 94 +++++++++++-------- clang/lib/Analysis/FlowSensitive/Transfer.cpp | 9 -- .../Analysis/FlowSensitive/RecordOpsTest.cpp | 46 ++++++++- .../Analysis/FlowSensitive/TransferTest.cpp | 25 ++++- 5 files changed, 126 insertions(+), 54 deletions(-) diff --git a/clang/include/clang/Analysis/FlowSensitive/RecordOps.h b/clang/include/clang/Analysis/FlowSensitive/RecordOps.h index 783e53e980aa..8fad45fc11d8 100644 --- a/clang/include/clang/Analysis/FlowSensitive/RecordOps.h +++ b/clang/include/clang/Analysis/FlowSensitive/RecordOps.h @@ -31,7 +31,11 @@ namespace dataflow { /// /// Requirements: /// -/// `Src` and `Dst` must have the same canonical unqualified type. +/// Either: +/// - `Src` and `Dest` must have the same canonical unqualified type, or +/// - The type of `Src` must be derived from `Dest`, or +/// - The type of `Dest` must be derived from `Src` (in this case, any fields +/// that are only present in `Dest` are not overwritten). void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst, Environment &Env); diff --git a/clang/lib/Analysis/FlowSensitive/RecordOps.cpp b/clang/lib/Analysis/FlowSensitive/RecordOps.cpp index da4dd6dc0785..2f0b0e5c5640 100644 --- a/clang/lib/Analysis/FlowSensitive/RecordOps.cpp +++ b/clang/lib/Analysis/FlowSensitive/RecordOps.cpp @@ -14,18 +14,52 @@ #define DEBUG_TYPE "dataflow" -void clang::dataflow::copyRecord(RecordStorageLocation &Src, - RecordStorageLocation &Dst, Environment &Env) { +namespace clang::dataflow { + +static void copyField(const ValueDecl &Field, StorageLocation *SrcFieldLoc, + StorageLocation *DstFieldLoc, RecordStorageLocation &Dst, + Environment &Env) { + assert(Field.getType()->isReferenceType() || + (SrcFieldLoc != nullptr && DstFieldLoc != nullptr)); + + if (Field.getType()->isRecordType()) { + copyRecord(cast<RecordStorageLocation>(*SrcFieldLoc), + cast<RecordStorageLocation>(*DstFieldLoc), Env); + } else if (Field.getType()->isReferenceType()) { + Dst.setChild(Field, SrcFieldLoc); + } else { + if (Value *Val = Env.getValue(*SrcFieldLoc)) + Env.setValue(*DstFieldLoc, *Val); + else + Env.clearValue(*DstFieldLoc); + } +} + +static void copySyntheticField(QualType FieldType, StorageLocation &SrcFieldLoc, + StorageLocation &DstFieldLoc, Environment &Env) { + if (FieldType->isRecordType()) { + copyRecord(cast<RecordStorageLocation>(SrcFieldLoc), + cast<RecordStorageLocation>(DstFieldLoc), Env); + } else { + if (Value *Val = Env.getValue(SrcFieldLoc)) + Env.setValue(DstFieldLoc, *Val); + else + Env.clearValue(DstFieldLoc); + } +} + +void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst, + Environment &Env) { auto SrcType = Src.getType().getCanonicalType().getUnqualifiedType(); auto DstType = Dst.getType().getCanonicalType().getUnqualifiedType(); auto SrcDecl = SrcType->getAsCXXRecordDecl(); auto DstDecl = DstType->getAsCXXRecordDecl(); - bool compatibleTypes = + [[maybe_unused]] bool compatibleTypes = SrcType == DstType || - (SrcDecl && DstDecl && SrcDecl->isDerivedFrom(DstDecl)); - (void)compatibleTypes; + (SrcDecl != nullptr && DstDecl != nullptr && + (SrcDecl->isDerivedFrom(DstDecl) || DstDecl->isDerivedFrom(SrcDecl))); LLVM_DEBUG({ if (!compatibleTypes) { @@ -35,45 +69,27 @@ void clang::dataflow::copyRecord(RecordStorageLocation &Src, }); assert(compatibleTypes); - for (auto [Field, DstFieldLoc] : Dst.children()) { - StorageLocation *SrcFieldLoc = Src.getChild(*Field); - - assert(Field->getType()->isReferenceType() || - (SrcFieldLoc != nullptr && DstFieldLoc != nullptr)); - - if (Field->getType()->isRecordType()) { - copyRecord(cast<RecordStorageLocation>(*SrcFieldLoc), - cast<RecordStorageLocation>(*DstFieldLoc), Env); - } else if (Field->getType()->isReferenceType()) { - Dst.setChild(*Field, SrcFieldLoc); - } else { - if (Value *Val = Env.getValue(*SrcFieldLoc)) - Env.setValue(*DstFieldLoc, *Val); - else - Env.clearValue(*DstFieldLoc); - } - } - - for (const auto &[Name, SynthFieldLoc] : Src.synthetic_fields()) { - if (SynthFieldLoc->getType()->isRecordType()) { - copyRecord(*cast<RecordStorageLocation>(SynthFieldLoc), - cast<RecordStorageLocation>(Dst.getSyntheticField(Name)), Env); - } else { - if (Value *Val = Env.getValue(*SynthFieldLoc)) - Env.setValue(Dst.getSyntheticField(Name), *Val); - else - Env.clearValue(Dst.getSyntheticField(Name)); - } + if (SrcType == DstType || (SrcDecl != nullptr && DstDecl != nullptr && + SrcDecl->isDerivedFrom(DstDecl))) { + for (auto [Field, DstFieldLoc] : Dst.children()) + copyField(*Field, Src.getChild(*Field), DstFieldLoc, Dst, Env); + for (const auto &[Name, DstFieldLoc] : Dst.synthetic_fields()) + copySyntheticField(DstFieldLoc->getType(), Src.getSyntheticField(Name), + *DstFieldLoc, Env); + } else { + for (auto [Field, SrcFieldLoc] : Src.children()) + copyField(*Field, SrcFieldLoc, Dst.getChild(*Field), Dst, Env); + for (const auto &[Name, SrcFieldLoc] : Src.synthetic_fields()) + copySyntheticField(SrcFieldLoc->getType(), *SrcFieldLoc, + Dst.getSyntheticField(Name), Env); } RecordValue *DstVal = &Env.create<RecordValue>(Dst); Env.setValue(Dst, *DstVal); } -bool clang::dataflow::recordsEqual(const RecordStorageLocation &Loc1, - const Environment &Env1, - const RecordStorageLocation &Loc2, - const Environment &Env2) { +bool recordsEqual(const RecordStorageLocation &Loc1, const Environment &Env1, + const RecordStorageLocation &Loc2, const Environment &Env2) { LLVM_DEBUG({ if (Loc2.getType().getCanonicalType().getUnqualifiedType() != Loc1.getType().getCanonicalType().getUnqualifiedType()) { @@ -116,3 +132,5 @@ bool clang::dataflow::recordsEqual(const RecordStorageLocation &Loc1, return true; } + +} // namespace clang::dataflow diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 19d6810cc98d..960e9688ffb7 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -544,15 +544,6 @@ public: if (LocSrc == nullptr || LocDst == nullptr) return; - // The assignment operators are different from the type of the destination - // in this model (i.e. in one of their base classes). This must be very - // rare and we just bail. - if (Method->getFunctionObjectParameterType() - .getCanonicalType() - .getUnqualifiedType() != - LocDst->getType().getCanonicalType().getUnqualifiedType()) - return; - copyRecord(*LocSrc, *LocDst, Env); // If the expr is a glvalue, we can reasonably assume the operator is diff --git a/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp b/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp index cd6a37d370e8..55baa4e2a537 100644 --- a/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp @@ -198,7 +198,7 @@ TEST(RecordOpsTest, RecordsEqual) { }); } -TEST(TransferTest, CopyRecordFromDerivedToBase) { +TEST(TransferTest, CopyRecordBetweenDerivedAndBase) { std::string Code = R"( struct A { int i; @@ -212,8 +212,23 @@ TEST(TransferTest, CopyRecordFromDerivedToBase) { // [[p]] } )"; + auto SyntheticFieldCallback = [](QualType Ty) -> llvm::StringMap<QualType> { + CXXRecordDecl *ADecl = nullptr; + if (Ty.getAsString() == "A") + ADecl = Ty->getAsCXXRecordDecl(); + else if (Ty.getAsString() == "B") + ADecl = Ty->getAsCXXRecordDecl() + ->bases_begin() + ->getType() + ->getAsCXXRecordDecl(); + else + return {}; + QualType IntTy = getFieldNamed(ADecl, "i")->getType(); + return {{"synth_int", IntTy}}; + }; + // Test copying derived to base class. runDataflow( - Code, /*SyntheticFieldCallback=*/{}, + Code, SyntheticFieldCallback, [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, ASTContext &ASTCtx) { Environment Env = getEnvironmentAtAnnotation(Results, "p").fork(); @@ -224,11 +239,38 @@ TEST(TransferTest, CopyRecordFromDerivedToBase) { EXPECT_NE(Env.getValue(*A.getChild(*IDecl)), Env.getValue(*B.getChild(*IDecl))); + EXPECT_NE(Env.getValue(A.getSyntheticField("synth_int")), + Env.getValue(B.getSyntheticField("synth_int"))); copyRecord(B, A, Env); EXPECT_EQ(Env.getValue(*A.getChild(*IDecl)), Env.getValue(*B.getChild(*IDecl))); + EXPECT_EQ(Env.getValue(A.getSyntheticField("synth_int")), + Env.getValue(B.getSyntheticField("synth_int"))); + }); + // Test copying base to derived class. + runDataflow( + Code, SyntheticFieldCallback, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, + ASTContext &ASTCtx) { + Environment Env = getEnvironmentAtAnnotation(Results, "p").fork(); + + const ValueDecl *IDecl = findValueDecl(ASTCtx, "i"); + auto &A = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "a"); + auto &B = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "b"); + + EXPECT_NE(Env.getValue(*A.getChild(*IDecl)), + Env.getValue(*B.getChild(*IDecl))); + EXPECT_NE(Env.getValue(A.getSyntheticField("synth_int")), + Env.getValue(B.getSyntheticField("synth_int"))); + + copyRecord(A, B, Env); + + EXPECT_EQ(Env.getValue(*A.getChild(*IDecl)), + Env.getValue(*B.getChild(*IDecl))); + EXPECT_EQ(Env.getValue(A.getSyntheticField("synth_int")), + Env.getValue(B.getSyntheticField("synth_int"))); }); } diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 86c7f32f0104..a243535d3872 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -2313,8 +2313,6 @@ TEST(TransferTest, AssignmentOperator_ArgByValue) { } TEST(TransferTest, AssignmentOperatorFromBase) { - // This is a crash repro. We don't model the copy this case, so no - // expectations on the copied field of the base class are checked. std::string Code = R"( struct Base { int base; @@ -2326,14 +2324,33 @@ TEST(TransferTest, AssignmentOperatorFromBase) { void target(Base B, Derived D) { D.base = 1; D.derived = 1; + // [[before]] D = B; - // [[p]] + // [[after]] } )"; runDataflow( Code, [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results, - ASTContext &ASTCtx) {}); + ASTContext &ASTCtx) { + const Environment &EnvBefore = + getEnvironmentAtAnnotation(Results, "before"); + const Environment &EnvAfter = + getEnvironmentAtAnnotation(Results, "after"); + + auto &BLoc = + getLocForDecl<RecordStorageLocation>(ASTCtx, EnvBefore, "B"); + auto &DLoc = + getLocForDecl<RecordStorageLocation>(ASTCtx, EnvBefore, "D"); + + EXPECT_NE(getFieldValue(&BLoc, "base", ASTCtx, EnvBefore), + getFieldValue(&DLoc, "base", ASTCtx, EnvBefore)); + EXPECT_EQ(getFieldValue(&BLoc, "base", ASTCtx, EnvAfter), + getFieldValue(&DLoc, "base", ASTCtx, EnvAfter)); + + EXPECT_EQ(getFieldValue(&DLoc, "derived", ASTCtx, EnvBefore), + getFieldValue(&DLoc, "derived", ASTCtx, EnvAfter)); + }); } TEST(TransferTest, AssignmentOperatorFromCallResult) { -- GitLab From 5e486d17d4793e5114245b9a04a566ef45ffb21b Mon Sep 17 00:00:00 2001 From: Wang Pengcheng <wangpengcheng.pp@bytedance.com> Date: Tue, 19 Mar 2024 16:27:15 +0800 Subject: [PATCH 029/307] [TableGen][NFC] Move MacroFusion classes to TargetMacroFusion.td To make structure clear. Reviewers: dtcxzyw, arsenm Reviewed By: arsenm Pull Request: https://github.com/llvm/llvm-project/pull/85748 --- llvm/include/llvm/Target/Target.td | 5 + llvm/include/llvm/Target/TargetMacroFusion.td | 136 ++++++++++++++++++ llvm/include/llvm/Target/TargetSchedule.td | 127 ---------------- 3 files changed, 141 insertions(+), 127 deletions(-) create mode 100644 llvm/include/llvm/Target/TargetMacroFusion.td diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td index 4f0c10049ee7..1e40cc49040d 100644 --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -1877,3 +1877,8 @@ include "llvm/Target/GlobalISel/SelectionDAGCompat.td" // Pull in the common support for Pfm Counters generation. // include "llvm/Target/TargetPfmCounters.td" + +//===----------------------------------------------------------------------===// +// Pull in the common support for macro fusion. +// +include "llvm/Target/TargetMacroFusion.td" diff --git a/llvm/include/llvm/Target/TargetMacroFusion.td b/llvm/include/llvm/Target/TargetMacroFusion.td new file mode 100644 index 000000000000..766ba0afbf99 --- /dev/null +++ b/llvm/include/llvm/Target/TargetMacroFusion.td @@ -0,0 +1,136 @@ +//===-- TargetMacroFusion.td - Target Macro Fusion ---------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the TableGen-based macro fusion classes. + +// The target instruction that FusionPredicate will be evaluated on. +class FusionTarget; +def first_fusion_target : FusionTarget; +def second_fusion_target : FusionTarget; +def both_fusion_target : FusionTarget; + +// Base class of FusionPredicate, etc. The avaliable variables are: +// * const TargetInstrInfo &TII +// * const TargetSubtargetInfo &STI +// * const MachineRegisterInfo &MRI +// * const MachineInstr *FirstMI +// * const MachineInstr &SecondMI +class FusionPredicate<FusionTarget target> { + FusionTarget Target = target; +} +class FirstFusionPredicate: FusionPredicate<first_fusion_target>; +class SecondFusionPredicate: FusionPredicate<second_fusion_target>; +class BothFusionPredicate: FusionPredicate<both_fusion_target>; + +// FusionPredicate with raw code predicate. +class FusionPredicateWithCode<code pred> : FusionPredicate<both_fusion_target> { + code Predicate = pred; +} + +// FusionPredicate with MCInstPredicate. +class FusionPredicateWithMCInstPredicate<FusionTarget target, MCInstPredicate pred> + : FusionPredicate<target> { + MCInstPredicate Predicate = pred; +} +class FirstFusionPredicateWithMCInstPredicate<MCInstPredicate pred> + : FusionPredicateWithMCInstPredicate<first_fusion_target, pred>; +class SecondFusionPredicateWithMCInstPredicate<MCInstPredicate pred> + : FusionPredicateWithMCInstPredicate<second_fusion_target, pred>; +// The pred will be applied on both firstMI and secondMI. +class BothFusionPredicateWithMCInstPredicate<MCInstPredicate pred> + : FusionPredicateWithMCInstPredicate<both_fusion_target, pred>; + +// Tie firstOpIdx and secondOpIdx. The operand of `FirstMI` at position +// `firstOpIdx` should be the same as the operand of `SecondMI` at position +// `secondOpIdx`. +// If the fusion has `IsCommutable` being true and the operand at `secondOpIdx` +// has commutable operand, then the commutable operand will be checked too. +class TieReg<int firstOpIdx, int secondOpIdx> : BothFusionPredicate { + int FirstOpIdx = firstOpIdx; + int SecondOpIdx = secondOpIdx; +} + +// The operand of `SecondMI` at position `firstOpIdx` should be the same as the +// operand at position `secondOpIdx`. +// If the fusion has `IsCommutable` being true and the operand at `secondOpIdx` +// has commutable operand, then the commutable operand will be checked too. +class SameReg<int firstOpIdx, int secondOpIdx> : SecondFusionPredicate { + int FirstOpIdx = firstOpIdx; + int SecondOpIdx = secondOpIdx; +} + +// A predicate for wildcard. The generated code will be like: +// ``` +// if (!FirstMI) +// return ReturnValue; +// ``` +class WildcardPred<bit ret> : FirstFusionPredicate { + bit ReturnValue = ret; +} +def WildcardFalse : WildcardPred<0>; +def WildcardTrue : WildcardPred<1>; + +// Indicates that the destination register of `FirstMI` should have one use if +// it is a virtual register. +class OneUsePred : FirstFusionPredicate; +def OneUse : OneUsePred; + +// Handled by MacroFusionPredicatorEmitter backend. +// The generated predicator will be like: +// ``` +// bool isNAME(const TargetInstrInfo &TII, +// const TargetSubtargetInfo &STI, +// const MachineInstr *FirstMI, +// const MachineInstr &SecondMI) { +// auto &MRI = SecondMI.getMF()->getRegInfo(); +// /* Predicates */ +// return true; +// } +// ``` +// +// `IsCommutable` means whether we should handle commutable operands. +class Fusion<string name, string fieldName, string desc, list<FusionPredicate> predicates> + : SubtargetFeature<name, fieldName, "true", desc> { + list<FusionPredicate> Predicates = predicates; + bit IsCommutable = 0; +} + +// The generated predicator will be like: +// ``` +// bool isNAME(const TargetInstrInfo &TII, +// const TargetSubtargetInfo &STI, +// const MachineInstr *FirstMI, +// const MachineInstr &SecondMI) { +// auto &MRI = SecondMI.getMF()->getRegInfo(); +// /* Prolog */ +// /* Predicate for `SecondMI` */ +// /* Wildcard */ +// /* Predicate for `FirstMI` */ +// /* Check same registers */ +// /* Check One Use */ +// /* Tie registers */ +// /* Epilog */ +// return true; +// } +// ``` +class SimpleFusion<string name, string fieldName, string desc, + MCInstPredicate firstPred, MCInstPredicate secondPred, + list<FusionPredicate> prolog = [], + list<FusionPredicate> epilog = []> + : Fusion<name, fieldName, desc, + !listconcat( + prolog, + [ + SecondFusionPredicateWithMCInstPredicate<secondPred>, + WildcardTrue, + FirstFusionPredicateWithMCInstPredicate<firstPred>, + SameReg<0, 1>, + OneUse, + TieReg<0, 1>, + ], + epilog)>; diff --git a/llvm/include/llvm/Target/TargetSchedule.td b/llvm/include/llvm/Target/TargetSchedule.td index d8158eb01ad4..2562ed090130 100644 --- a/llvm/include/llvm/Target/TargetSchedule.td +++ b/llvm/include/llvm/Target/TargetSchedule.td @@ -581,130 +581,3 @@ class MemoryQueue<ProcResourceKind PR> { class LoadQueue<ProcResourceKind LDQueue> : MemoryQueue<LDQueue>; class StoreQueue<ProcResourceKind STQueue> : MemoryQueue<STQueue>; - -// The target instruction that FusionPredicate will be evaluated on. -class FusionTarget; -def first_fusion_target : FusionTarget; -def second_fusion_target : FusionTarget; -def both_fusion_target : FusionTarget; - -// Base class of FusionPredicate, etc. The avaliable variables are: -// * const TargetInstrInfo &TII -// * const TargetSubtargetInfo &STI -// * const MachineRegisterInfo &MRI -// * const MachineInstr *FirstMI -// * const MachineInstr &SecondMI -class FusionPredicate<FusionTarget target> { - FusionTarget Target = target; -} -class FirstFusionPredicate: FusionPredicate<first_fusion_target>; -class SecondFusionPredicate: FusionPredicate<second_fusion_target>; -class BothFusionPredicate: FusionPredicate<both_fusion_target>; - -// FusionPredicate with raw code predicate. -class FusionPredicateWithCode<code pred> : FusionPredicate<both_fusion_target> { - code Predicate = pred; -} - -// FusionPredicate with MCInstPredicate. -class FusionPredicateWithMCInstPredicate<FusionTarget target, MCInstPredicate pred> - : FusionPredicate<target> { - MCInstPredicate Predicate = pred; -} -class FirstFusionPredicateWithMCInstPredicate<MCInstPredicate pred> - : FusionPredicateWithMCInstPredicate<first_fusion_target, pred>; -class SecondFusionPredicateWithMCInstPredicate<MCInstPredicate pred> - : FusionPredicateWithMCInstPredicate<second_fusion_target, pred>; -// The pred will be applied on both firstMI and secondMI. -class BothFusionPredicateWithMCInstPredicate<MCInstPredicate pred> - : FusionPredicateWithMCInstPredicate<both_fusion_target, pred>; - -// Tie firstOpIdx and secondOpIdx. The operand of `FirstMI` at position -// `firstOpIdx` should be the same as the operand of `SecondMI` at position -// `secondOpIdx`. -// If the fusion has `IsCommutable` being true and the operand at `secondOpIdx` -// has commutable operand, then the commutable operand will be checked too. -class TieReg<int firstOpIdx, int secondOpIdx> : BothFusionPredicate { - int FirstOpIdx = firstOpIdx; - int SecondOpIdx = secondOpIdx; -} - -// The operand of `SecondMI` at position `firstOpIdx` should be the same as the -// operand at position `secondOpIdx`. -// If the fusion has `IsCommutable` being true and the operand at `secondOpIdx` -// has commutable operand, then the commutable operand will be checked too. -class SameReg<int firstOpIdx, int secondOpIdx> : SecondFusionPredicate { - int FirstOpIdx = firstOpIdx; - int SecondOpIdx = secondOpIdx; -} - -// A predicate for wildcard. The generated code will be like: -// ``` -// if (!FirstMI) -// return ReturnValue; -// ``` -class WildcardPred<bit ret> : FirstFusionPredicate { - bit ReturnValue = ret; -} -def WildcardFalse : WildcardPred<0>; -def WildcardTrue : WildcardPred<1>; - -// Indicates that the destination register of `FirstMI` should have one use if -// it is a virtual register. -class OneUsePred : FirstFusionPredicate; -def OneUse : OneUsePred; - -// Handled by MacroFusionPredicatorEmitter backend. -// The generated predicator will be like: -// ``` -// bool isNAME(const TargetInstrInfo &TII, -// const TargetSubtargetInfo &STI, -// const MachineInstr *FirstMI, -// const MachineInstr &SecondMI) { -// auto &MRI = SecondMI.getMF()->getRegInfo(); -// /* Predicates */ -// return true; -// } -// ``` -// -// `IsCommutable` means whether we should handle commutable operands. -class Fusion<string name, string fieldName, string desc, list<FusionPredicate> predicates> - : SubtargetFeature<name, fieldName, "true", desc> { - list<FusionPredicate> Predicates = predicates; - bit IsCommutable = 0; -} - -// The generated predicator will be like: -// ``` -// bool isNAME(const TargetInstrInfo &TII, -// const TargetSubtargetInfo &STI, -// const MachineInstr *FirstMI, -// const MachineInstr &SecondMI) { -// auto &MRI = SecondMI.getMF()->getRegInfo(); -// /* Prolog */ -// /* Predicate for `SecondMI` */ -// /* Wildcard */ -// /* Predicate for `FirstMI` */ -// /* Check same registers */ -// /* Check One Use */ -// /* Tie registers */ -// /* Epilog */ -// return true; -// } -// ``` -class SimpleFusion<string name, string fieldName, string desc, - MCInstPredicate firstPred, MCInstPredicate secondPred, - list<FusionPredicate> prolog = [], - list<FusionPredicate> epilog = []> - : Fusion<name, fieldName, desc, - !listconcat( - prolog, - [ - SecondFusionPredicateWithMCInstPredicate<secondPred>, - WildcardTrue, - FirstFusionPredicateWithMCInstPredicate<firstPred>, - SameReg<0, 1>, - OneUse, - TieReg<0, 1>, - ], - epilog)>; -- GitLab From 703920d4138d02bde4f4bf70ba809b63bef25c37 Mon Sep 17 00:00:00 2001 From: Shourya Goel <shouryagoel10000@gmail.com> Date: Tue, 19 Mar 2024 13:59:55 +0530 Subject: [PATCH 030/307] [DAG] Matched FixedWidth pattern for ISD::AVGFLOORU (#84903) Fixes: #84749 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 21 +++++++++++++++++++ llvm/test/CodeGen/AArch64/hadd-combine.ll | 12 +++++++++++ 2 files changed, 33 insertions(+) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 351041780b85..d6d0bf02c639 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2820,6 +2820,23 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) { return SDValue(); } +// Attempt to form avgflooru(A, B) from (A & B) + ((A ^ B) >> 1) +static SDValue combineFixedwidthToAVGFLOORU(SDNode *N, SelectionDAG &DAG) { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + SDValue N0 = N->getOperand(0); + EVT VT = N0.getValueType(); + SDLoc DL(N); + if (TLI.isOperationLegal(ISD::AVGFLOORU, VT)) { + SDValue A, B; + if (sd_match(N, m_Add(m_And(m_Value(A), m_Value(B)), + m_Srl(m_Xor(m_Deferred(A), m_Deferred(B)), + m_SpecificInt(1))))) { + return DAG.getNode(ISD::AVGFLOORU, DL, VT, A, B); + } + } + return SDValue(); +} + SDValue DAGCombiner::visitADD(SDNode *N) { SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); @@ -2835,6 +2852,10 @@ SDValue DAGCombiner::visitADD(SDNode *N) { if (SDValue V = foldAddSubOfSignBit(N, DAG)) return V; + // Try to match AVGFLOORU fixedwidth pattern + if (SDValue V = combineFixedwidthToAVGFLOORU(N, DAG)) + return V; + // fold (a+b) -> (a|b) iff a and b share no bits. if ((!LegalOperations || TLI.isOperationLegal(ISD::OR, VT)) && DAG.haveNoCommonBitsSet(N0, N1)) diff --git a/llvm/test/CodeGen/AArch64/hadd-combine.ll b/llvm/test/CodeGen/AArch64/hadd-combine.ll index 2269d75cdbb9..b035ba03529c 100644 --- a/llvm/test/CodeGen/AArch64/hadd-combine.ll +++ b/llvm/test/CodeGen/AArch64/hadd-combine.ll @@ -859,6 +859,18 @@ define <4 x i32> @urhadd_v4i32(<4 x i32> %x) { ret <4 x i32> %r } +define <8 x i16> @uhadd_fixedwidth_v4i32(<8 x i16> %a0, <8 x i16> %a1) { +; CHECK-LABEL: uhadd_fixedwidth_v4i32: +; CHECK: // %bb.0: +; CHECK-NEXT: uhadd v0.8h, v0.8h, v1.8h +; CHECK-NEXT: ret + %and = and <8 x i16> %a0, %a1 + %xor = xor <8 x i16> %a0, %a1 + %srl = lshr <8 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = add <8 x i16> %and, %srl + ret <8 x i16> %res +} + declare <8 x i8> @llvm.aarch64.neon.shadd.v8i8(<8 x i8>, <8 x i8>) declare <4 x i16> @llvm.aarch64.neon.shadd.v4i16(<4 x i16>, <4 x i16>) declare <2 x i32> @llvm.aarch64.neon.shadd.v2i32(<2 x i32>, <2 x i32>) -- GitLab From 6aaf9c83099b80e73ef2208ae9f7f300c7808659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder@redhat.com> Date: Tue, 19 Mar 2024 08:28:56 +0100 Subject: [PATCH 031/307] [clang][Interp][NFC] Sanitize collectBaseOffset parameters --- clang/lib/AST/Interp/ByteCodeExprGen.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index af214d4a8577..73831eefba45 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -3337,6 +3337,8 @@ template <class Emitter> unsigned ByteCodeExprGen<Emitter>::collectBaseOffset(const RecordType *BaseType, const RecordType *DerivedType) { + assert(BaseType); + assert(DerivedType); const auto *FinalDecl = cast<CXXRecordDecl>(BaseType->getDecl()); const RecordDecl *CurDecl = DerivedType->getDecl(); const Record *CurRecord = getRecord(CurDecl); -- GitLab From a747e86caacf0ba3d5272474da8c10eb0b67dbc2 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng <dtcxzyw2333@gmail.com> Date: Tue, 19 Mar 2024 17:16:48 +0800 Subject: [PATCH 032/307] [InstCombine] Fold `fpto{s|u}i non-norm` to zero (#85569) This patch enables more optimization after canonicalizing `fmul X, 0.0` into a copysign. I decide to implement this fold in InstCombine because `computeKnownFPClass` may be expensive. Alive2: https://alive2.llvm.org/ce/z/ASM8tQ --- .../InstCombine/InstCombineCasts.cpp | 19 ++++ llvm/test/Transforms/InstCombine/fpcast.ll | 88 +++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 381cd858d262..b19da1e07581 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1923,10 +1923,26 @@ Instruction *InstCombinerImpl::foldItoFPtoI(CastInst &FI) { return replaceInstUsesWith(FI, X); } +static Instruction *foldFPtoI(Instruction &FI, InstCombiner &IC) { + // fpto{u/s}i non-norm --> 0 + FPClassTest Mask = + FI.getOpcode() == Instruction::FPToUI ? fcPosNormal : fcNormal; + KnownFPClass FPClass = + computeKnownFPClass(FI.getOperand(0), Mask, /*Depth=*/0, + IC.getSimplifyQuery().getWithInstruction(&FI)); + if (FPClass.isKnownNever(Mask)) + return IC.replaceInstUsesWith(FI, ConstantInt::getNullValue(FI.getType())); + + return nullptr; +} + Instruction *InstCombinerImpl::visitFPToUI(FPToUIInst &FI) { if (Instruction *I = foldItoFPtoI(FI)) return I; + if (Instruction *I = foldFPtoI(FI, *this)) + return I; + return commonCastTransforms(FI); } @@ -1934,6 +1950,9 @@ Instruction *InstCombinerImpl::visitFPToSI(FPToSIInst &FI) { if (Instruction *I = foldItoFPtoI(FI)) return I; + if (Instruction *I = foldFPtoI(FI, *this)) + return I; + return commonCastTransforms(FI); } diff --git a/llvm/test/Transforms/InstCombine/fpcast.ll b/llvm/test/Transforms/InstCombine/fpcast.ll index 88ca556f4d8f..1f0bfbc40ac1 100644 --- a/llvm/test/Transforms/InstCombine/fpcast.ll +++ b/llvm/test/Transforms/InstCombine/fpcast.ll @@ -347,3 +347,91 @@ define double @masked_uint_to_fpext3(i32 %x) { %r = fpext float %f to double ret double %r } + +define i32 @fptosi_nonnorm(float nofpclass(norm) %x) { +; CHECK-LABEL: @fptosi_nonnorm( +; CHECK-NEXT: ret i32 0 +; + %ret = fptosi float %x to i32 + ret i32 %ret +} + +define i32 @fptoui_nonnorm(float nofpclass(pnorm) %x) { +; CHECK-LABEL: @fptoui_nonnorm( +; CHECK-NEXT: ret i32 0 +; + %ret = fptoui float %x to i32 + ret i32 %ret +} + +define i32 @fptosi_nonnnorm(float nofpclass(nnorm) %x) { +; CHECK-LABEL: @fptosi_nonnnorm( +; CHECK-NEXT: [[RET:%.*]] = fptosi float [[X:%.*]] to i32 +; CHECK-NEXT: ret i32 [[RET]] +; + %ret = fptosi float %x to i32 + ret i32 %ret +} + +define i32 @fptoui_nonnnorm(float nofpclass(nnorm) %x) { +; CHECK-LABEL: @fptoui_nonnnorm( +; CHECK-NEXT: [[RET:%.*]] = fptoui float [[X:%.*]] to i32 +; CHECK-NEXT: ret i32 [[RET]] +; + %ret = fptoui float %x to i32 + ret i32 %ret +} + +define i32 @fptosi_nonnorm_copysign(float %x) { +; CHECK-LABEL: @fptosi_nonnorm_copysign( +; CHECK-NEXT: ret i32 0 +; + %val = call float @llvm.copysign.f32(float 0.0, float %x) + %ret = fptosi float %val to i32 + ret i32 %ret +} + +define <2 x i32> @fptosi_nonnorm_copysign_vec(<2 x float> %x) { +; CHECK-LABEL: @fptosi_nonnorm_copysign_vec( +; CHECK-NEXT: ret <2 x i32> zeroinitializer +; + %val = call <2 x float> @llvm.copysign.v2f32(<2 x float> zeroinitializer, <2 x float> %x) + %ret = fptosi <2 x float> %val to <2 x i32> + ret <2 x i32> %ret +} + +define i32 @fptosi_nonnorm_fmul(float %x) { +; CHECK-LABEL: @fptosi_nonnorm_fmul( +; CHECK-NEXT: [[SEL:%.*]] = fmul float [[X:%.*]], 0.000000e+00 +; CHECK-NEXT: [[RET:%.*]] = fptosi float [[SEL]] to i32 +; CHECK-NEXT: ret i32 [[RET]] +; + %sel = fmul float %x, 0.000000e+00 + %ret = fptosi float %sel to i32 + ret i32 %ret +} + +define i32 @fptosi_select(i1 %cond) { +; CHECK-LABEL: @fptosi_select( +; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND:%.*]], i32 1, i32 -1 +; CHECK-NEXT: ret i32 [[RET]] +; + %sel = select i1 %cond, float 1.0, float -1.0 + %ret = fptosi float %sel to i32 + ret i32 %ret +} + +define i32 @mul_pos_zero_convert(i32 %a) { +; CHECK-LABEL: @mul_pos_zero_convert( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[FP:%.*]] = sitofp i32 [[A:%.*]] to float +; CHECK-NEXT: [[RET:%.*]] = fmul float [[FP]], 0.000000e+00 +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[RET]] to i32 +; CHECK-NEXT: ret i32 [[CONV]] +; +entry: + %fp = sitofp i32 %a to float + %ret = fmul float %fp, 0.000000e+00 + %conv = fptosi float %ret to i32 + ret i32 %conv +} -- GitLab From 1a6953a75d3120a4f9196911e6a6b79fcc315553 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <Matthew.Arsenault@amd.com> Date: Tue, 19 Mar 2024 14:24:51 +0530 Subject: [PATCH 033/307] ValueTracking: Fix bug with fcmp false to nan constant If we had a comparison to a literal nan with a false predicate, we were incorrectly treating it as an unordered compare. This was correct for fcmp true, but not fcmp false. I noticed this in the review for e44d3b3e503fa12fdaead2936b28844aa36237c1 but misdiagnosed the reason. Also change the test for the fcmp true case to be more useful, but it wasn't wrong previously. --- llvm/lib/Analysis/ValueTracking.cpp | 14 +++++++------- .../Attributor/nofpclass-implied-by-fcmp.ll | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index fe5d084b55bb..2e0a930cf0a3 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3972,10 +3972,16 @@ std::tuple<Value *, FPClassTest, FPClassTest> llvm::fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS, FPClassTest RHSClass, bool LookThroughSrc) { assert(RHSClass != fcNone); + Value *Src = LHS; + + if (Pred == FCmpInst::FCMP_TRUE) + return exactClass(Src, fcAllFlags); + + if (Pred == FCmpInst::FCMP_FALSE) + return exactClass(Src, fcNone); const FPClassTest OrigClass = RHSClass; - Value *Src = LHS; const bool IsNegativeRHS = (RHSClass & fcNegative) == RHSClass; const bool IsPositiveRHS = (RHSClass & fcPositive) == RHSClass; const bool IsNaN = (RHSClass & ~fcNan) == fcNone; @@ -3994,12 +4000,6 @@ llvm::fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS, if (Pred == FCmpInst::FCMP_UNO) return exactClass(Src, fcNan); - if (Pred == FCmpInst::FCMP_TRUE) - return exactClass(Src, fcAllFlags); - - if (Pred == FCmpInst::FCMP_FALSE) - return exactClass(Src, fcNone); - const bool IsFabs = LookThroughSrc && match(LHS, m_FAbs(m_Value(Src))); if (IsFabs) RHSClass = llvm::inverse_fabs(RHSClass); diff --git a/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll b/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll index d64f8cf3e56d..05c57052e674 100644 --- a/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll +++ b/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll @@ -2641,8 +2641,8 @@ define float @assume_false_smallest_normal(float %arg) { } define float @clamp_false_nan(float %arg) { -; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) float @clamp_false_nan( -; CHECK-SAME: float returned nofpclass(nan inf nzero sub norm) [[ARG:%.*]]) #[[ATTR2]] { +; CHECK-LABEL: define float @clamp_false_nan( +; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] { ; CHECK-NEXT: ret float [[ARG]] ; %fcmp = fcmp false float %arg, 0x7FF8000000000000 @@ -2784,12 +2784,12 @@ define float @clamp_true_smallest_normal_0.0(float %arg) { } define float @clamp_true_nan(float %arg) { -; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @clamp_true_nan( -; CHECK-SAME: float nofpclass(nan inf nzero sub norm) [[ARG:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: ret float 0.000000e+00 +; CHECK-LABEL: define float @clamp_true_nan( +; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] { +; CHECK-NEXT: ret float [[ARG]] ; %fcmp = fcmp true float %arg, 0x7FF8000000000000 - %select = select i1 %fcmp, float 0.0, float %arg + %select = select i1 %fcmp, float %arg, float 0.0 ret float %select } -- GitLab From 0d40de754a8fc34e606d0a83902f950606f42385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder@redhat.com> Date: Tue, 19 Mar 2024 10:06:20 +0100 Subject: [PATCH 034/307] [clang][Interp][NFC] Add InterpFrame::dump() --- clang/lib/AST/Interp/Disasm.cpp | 27 +++++++++++++++++++++++++++ clang/lib/AST/Interp/InterpFrame.h | 3 +++ 2 files changed, 30 insertions(+) diff --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp index 390d79d44b0a..01ef1c24744a 100644 --- a/clang/lib/AST/Interp/Disasm.cpp +++ b/clang/lib/AST/Interp/Disasm.cpp @@ -16,6 +16,7 @@ #include "FunctionPointer.h" #include "Integral.h" #include "IntegralAP.h" +#include "InterpFrame.h" #include "Opcode.h" #include "PrimType.h" #include "Program.h" @@ -206,3 +207,29 @@ LLVM_DUMP_METHOD void Descriptor::dump(llvm::raw_ostream &OS) const { if (isDummy()) OS << " dummy"; } + +LLVM_DUMP_METHOD void InterpFrame::dump(llvm::raw_ostream &OS, + unsigned Indent) const { + unsigned Spaces = Indent * 2; + { + ColorScope SC(OS, true, {llvm::raw_ostream::BLUE, true}); + OS.indent(Spaces); + if (getCallee()) + describe(OS); + else + OS << "Frame (Depth: " << getDepth() << ")"; + OS << "\n"; + } + OS.indent(Spaces) << "Function: " << getFunction(); + if (const Function *F = getFunction()) { + OS << " (" << F->getName() << ")"; + } + OS << "\n"; + OS.indent(Spaces) << "This: " << getThis() << "\n"; + OS.indent(Spaces) << "RVO: " << getRVOPtr() << "\n"; + + while (const InterpFrame *F = this->Caller) { + F->dump(OS, Indent + 1); + F = F->Caller; + } +} diff --git a/clang/lib/AST/Interp/InterpFrame.h b/clang/lib/AST/Interp/InterpFrame.h index 322d5dcfa698..1f80a0a5d2c4 100644 --- a/clang/lib/AST/Interp/InterpFrame.h +++ b/clang/lib/AST/Interp/InterpFrame.h @@ -123,6 +123,9 @@ public: unsigned getDepth() const { return Depth; } + void dump() const { dump(llvm::errs(), 0); } + void dump(llvm::raw_ostream &OS, unsigned Indent = 0) const; + private: /// Returns an original argument from the stack. template <typename T> const T &stackRef(unsigned Offset) const { -- GitLab From 29849d589c1969f6a07a69ef0d7a19896d358bc5 Mon Sep 17 00:00:00 2001 From: nicebert <110385235+nicebert@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:26:41 +0100 Subject: [PATCH 035/307] [OpenMP] Fix ompx_dump_mapping_tables lit test (#85754) Fixes ompx_dump_mapping_tables test by only using one device after breaking built bots --- .../test/api/ompx_dump_mapping_tables.cpp | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/openmp/libomptarget/test/api/ompx_dump_mapping_tables.cpp b/openmp/libomptarget/test/api/ompx_dump_mapping_tables.cpp index a57d0c8a6d2b..c170c2d73873 100644 --- a/openmp/libomptarget/test/api/ompx_dump_mapping_tables.cpp +++ b/openmp/libomptarget/test/api/ompx_dump_mapping_tables.cpp @@ -6,33 +6,28 @@ #define N 10 int main() { - int *a = new int[N]; // mapped and released from device 0 - int *b = new int[N]; // mapped to device 2 + int *a = new __int32_t[N]; // mapped and released from device 0 + int *b = new __int32_t[2 * N]; // mapped to device 0 // clang-format off // CHECK: Mapping tables after target enter data: // CHECK-NEXT: omptarget device 0 info: OpenMP Host-Device pointer mappings after block // CHECK-NEXT: omptarget device 0 info: Host Ptr Target Ptr Size (B) DynRefCount HoldRefCount Declaration - // CHECK-NEXT: omptarget device 0 info: {{(0x[0-9a-f]{16})}} {{(0x[0-9a-f]{16})}} - // CHECK-NEXT: omptarget device 1 info: OpenMP Host-Device pointer mappings table empty - // CHECK-NEXT: omptarget device 2 info: OpenMP Host-Device pointer mappings after block - // CHECK-NEXT: omptarget device 2 info: Host Ptr Target Ptr Size (B) DynRefCount HoldRefCount Declaration - // CHECK-NEXT: omptarget device 2 info: {{(0x[0-9a-f]{16})}} {{(0x[0-9a-f]{16})}} - // clang-format on + // CHECK-NEXT: omptarget device 0 info: {{(0x[0-9a-f]{16})}} {{(0x[0-9a-f]{16})}} {{[48]}}0 + // CHECK-NEXT: omptarget device 0 info: {{(0x[0-9a-f]{16})}} {{(0x[0-9a-f]{16})}} {{[48]}}0 #pragma omp target enter data device(0) map(to : a[ : N]) -#pragma omp target enter data device(2) map(to : b[ : N]) +#pragma omp target enter data device(0) map(to : b[ : 2*N]) + // clang-format on printf("Mapping tables after target enter data:\n"); ompx_dump_mapping_tables(); // clang-format off // CHECK: Mapping tables after target exit data for a: - // CHECK-NEXT: omptarget device 0 info: OpenMP Host-Device pointer mappings table empty - // CHECK-NEXT: omptarget device 1 info: OpenMP Host-Device pointer mappings table empty - // CHECK-NEXT: omptarget device 2 info: OpenMP Host-Device pointer mappings after block - // CHECK-NEXT: omptarget device 2 info: Host Ptr Target Ptr Size (B) DynRefCount HoldRefCount Declaration - // CHECK-NEXT: omptarget device 2 info: {{(0x[0-9a-f]{16})}} {{(0x[0-9a-f]{16})}} - // clang-format on + // CHECK-NEXT: omptarget device 0 info: OpenMP Host-Device pointer mappings after block + // CHECK-NEXT: omptarget device 0 info: Host Ptr Target Ptr Size (B) DynRefCount HoldRefCount Declaration + // CHECK-NEXT: omptarget device 0 info: {{(0x[0-9a-f]{16})}} {{(0x[0-9a-f]{16})}} 80 #pragma omp target exit data device(0) map(release : a[ : N]) + // clang-format on printf("\nMapping tables after target exit data for a:\n"); ompx_dump_mapping_tables(); -- GitLab From db6049112790f6bee51883b6aa99d0660f17e3a5 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Tue, 19 Mar 2024 10:31:25 +0100 Subject: [PATCH 036/307] [mlir][bufferization] Check OpFilter before casting to BufferizableOpInterface (#85690) This doesn't change functionality, but lets us avoid attaching all the interfaces after 513cdb82223a106f183b49a40d9acb1f7efbbe7e turned casting without loading into an error. --- mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp | 4 ++-- mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp b/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp index 8f0f6d1fcc84..55c9299c58ef 100644 --- a/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp +++ b/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp @@ -344,11 +344,11 @@ bool BufferizationOptions::isOpAllowed(Operation *op) const { BufferizableOpInterface BufferizationOptions::dynCastBufferizableOp(Operation *op) const { + if (!isOpAllowed(op)) + return nullptr; auto bufferizableOp = dyn_cast<BufferizableOpInterface>(op); if (!bufferizableOp) return nullptr; - if (!isOpAllowed(op)) - return nullptr; return bufferizableOp; } diff --git a/mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp b/mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp index 6a0ad6654996..8dbf70162012 100644 --- a/mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp +++ b/mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp @@ -453,7 +453,7 @@ LogicalResult bufferization::bufferizeOp(Operation *op, // canonicalize away (or canonicalize to more precise layouts). SmallVector<Operation *> worklist; op->walk<WalkOrder::PostOrder>([&](Operation *op) { - if (hasTensorSemantics(op)) + if (options.isOpAllowed(op) && hasTensorSemantics(op)) worklist.push_back(op); }); @@ -472,8 +472,6 @@ LogicalResult bufferization::bufferizeOp(Operation *op, auto bufferizableOp = options.dynCastBufferizableOp(nextOp); if (!bufferizableOp) continue; - if (!options.isOpAllowed(nextOp)) - continue; // Skip ops that no longer have tensor semantics. if (!hasTensorSemantics(nextOp)) continue; -- GitLab From 5e379b63fcd942017593d278c8c2313744413904 Mon Sep 17 00:00:00 2001 From: Pierre van Houtryve <pierre.vanhoutryve@amd.com> Date: Tue, 19 Mar 2024 10:36:12 +0100 Subject: [PATCH 037/307] [AMDGPU][PromoteAlloca] Drop bitcast handling (#85747) This is no longer needed with opaque pointers. --- llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp index b1b15e9915ae..e86132769f57 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -724,14 +724,6 @@ bool AMDGPUPromoteAllocaImpl::tryPromoteAllocaToVector(AllocaInst &Alloca) { continue; } - if (isa<BitCastInst>(Inst)) { - // Look through bitcasts. - for (Use &U : Inst->uses()) - Uses.push_back(&U); - UsersToRemove.push_back(Inst); - continue; - } - if (auto *GEP = dyn_cast<GetElementPtrInst>(Inst)) { // If we can't compute a vector index from this GEP, then we can't // promote this alloca to vector. -- GitLab From a4b23638d23d603001c19285a7c7535a8ce81317 Mon Sep 17 00:00:00 2001 From: Felix Schneider <fx.schn@gmail.com> Date: Tue, 19 Mar 2024 10:43:02 +0100 Subject: [PATCH 038/307] [mlir] Don't assert when simplifying certain `AffineExpr`s (#78855) Currently, `simplifyMul()` asserts that either `lhs` or `rhs` is symbolic or constant. This method is called by the overloaded `*` operator for `AffineExpr`s which leads to a crash when building a multiplication expression where neither operand is symbolic or constant. This patch returns a `nullptr` from `simplifyMul()` to signal that the expression could not be simplified instead. Fix https://github.com/llvm/llvm-project/issues/75770 --- mlir/lib/IR/AffineExpr.cpp | 3 ++- mlir/unittests/IR/AffineExprTest.cpp | 32 ++++++++++++++++++++++++++++ mlir/unittests/IR/CMakeLists.txt | 1 + 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 mlir/unittests/IR/AffineExprTest.cpp diff --git a/mlir/lib/IR/AffineExpr.cpp b/mlir/lib/IR/AffineExpr.cpp index 56a2d850ad3b..94562d0f15a2 100644 --- a/mlir/lib/IR/AffineExpr.cpp +++ b/mlir/lib/IR/AffineExpr.cpp @@ -774,7 +774,8 @@ static AffineExpr simplifyMul(AffineExpr lhs, AffineExpr rhs) { return getAffineConstantExpr(lhsConst.getValue() * rhsConst.getValue(), lhs.getContext()); - assert(lhs.isSymbolicOrConstant() || rhs.isSymbolicOrConstant()); + if (!lhs.isSymbolicOrConstant() && !rhs.isSymbolicOrConstant()) + return nullptr; // Canonicalize the mul expression so that the constant/symbolic term is the // RHS. If both the lhs and rhs are symbolic, swap them if the lhs is a diff --git a/mlir/unittests/IR/AffineExprTest.cpp b/mlir/unittests/IR/AffineExprTest.cpp new file mode 100644 index 000000000000..ff154eb29807 --- /dev/null +++ b/mlir/unittests/IR/AffineExprTest.cpp @@ -0,0 +1,32 @@ +//===- AffineExprTest.cpp - unit tests for affine expression API ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "mlir/IR/AffineExpr.h" +#include "mlir/IR/Builders.h" +#include "gtest/gtest.h" + +using namespace mlir; + +// Test creating AffineExprs using the overloaded binary operators. +TEST(AffineExprTest, constructFromBinaryOperators) { + MLIRContext ctx; + OpBuilder b(&ctx); + + auto d0 = b.getAffineDimExpr(0); + auto d1 = b.getAffineDimExpr(1); + + auto sum = d0 + d1; + auto difference = d0 - d1; + auto product = d0 * d1; + auto remainder = d0 % d1; + + ASSERT_EQ(sum.getKind(), AffineExprKind::Add); + ASSERT_EQ(difference.getKind(), AffineExprKind::Add); + ASSERT_EQ(product.getKind(), AffineExprKind::Mul); + ASSERT_EQ(remainder.getKind(), AffineExprKind::Mod); +} diff --git a/mlir/unittests/IR/CMakeLists.txt b/mlir/unittests/IR/CMakeLists.txt index e7e9c3b56516..71f8f449756e 100644 --- a/mlir/unittests/IR/CMakeLists.txt +++ b/mlir/unittests/IR/CMakeLists.txt @@ -1,5 +1,6 @@ add_mlir_unittest(MLIRIRTests AdaptorTest.cpp + AffineExprTest.cpp AffineMapTest.cpp AttributeTest.cpp DialectTest.cpp -- GitLab From e85bfa65651eb45aefc8a9233e160f27af55f894 Mon Sep 17 00:00:00 2001 From: Jonathan Thackray <jonathan.thackray@arm.com> Date: Tue, 19 Mar 2024 10:04:51 +0000 Subject: [PATCH 039/307] [AArch64] Add support for Cortex-A520AE and Cortex-A720AE CPUs (#85401) [AArch64] Add support for Cortex-A520AE and Cortex-A720AE CPUs Cortex-A520AE and Cortex-A720AE are Armv9.2 AArch64 CPUs. Technical Reference Manual for Cortex-A520AE: https://developer.arm.com/documentation/107726/latest/ Technical Reference Manual for Cortex-A720AE: https://developer.arm.com/documentation/102828/latest/ --- clang/docs/ReleaseNotes.rst | 2 ++ clang/test/Driver/aarch64-mcpu.c | 4 +++ clang/test/Misc/target-invalid-cpu-note.c | 4 +-- llvm/docs/ReleaseNotes.rst | 2 ++ .../llvm/TargetParser/AArch64TargetParser.h | 11 ++++++ llvm/lib/Target/AArch64/AArch64.td | 27 ++++++++++++++ llvm/lib/TargetParser/Host.cpp | 2 ++ .../TargetParser/TargetParserTest.cpp | 35 ++++++++++++++++++- 8 files changed, 84 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3a74c070ff9f..dab7e1bf3697 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -445,6 +445,8 @@ Arm and AArch64 Support like ``target_version`` or ``target_clones``. - Support has been added for the following processors (-mcpu identifiers in parenthesis): * Arm Cortex-A78AE (cortex-a78ae). + * Arm Cortex-A520AE (cortex-a520ae). + * Arm Cortex-A720AE (cortex-a720ae). Android Support ^^^^^^^^^^^^^^^ diff --git a/clang/test/Driver/aarch64-mcpu.c b/clang/test/Driver/aarch64-mcpu.c index cacfc691058d..77ba43122b24 100644 --- a/clang/test/Driver/aarch64-mcpu.c +++ b/clang/test/Driver/aarch64-mcpu.c @@ -56,6 +56,8 @@ // CORTEX-A715: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a715" // RUN: %clang --target=aarch64 -mcpu=cortex-a720 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A720 %s // CORTEX-A720: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a720" +// RUN: %clang --target=aarch64 -mcpu=cortex-a720ae -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A720AE %s +// CORTEX-A720AE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a720ae" // RUN: %clang --target=aarch64 -mcpu=neoverse-e1 -### -c %s 2>&1 | FileCheck -check-prefix=NEOVERSE-E1 %s // NEOVERSE-E1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-e1" // RUN: %clang --target=aarch64 -mcpu=neoverse-v1 -### -c %s 2>&1 | FileCheck -check-prefix=NEOVERSE-V1 %s @@ -70,6 +72,8 @@ // NEOVERSE-512TVB: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-512tvb" // RUN: %clang --target=aarch64 -mcpu=cortex-a520 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A520 %s // CORTEX-A520: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a520" +// RUN: %clang --target=aarch64 -mcpu=cortex-a520ae -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A520AE %s +// CORTEX-A520AE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a520ae" // RUN: %clang --target=aarch64 -mcpu=cortex-r82 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEXR82 %s // CORTEXR82: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-r82" diff --git a/clang/test/Misc/target-invalid-cpu-note.c b/clang/test/Misc/target-invalid-cpu-note.c index b65a8fb057ee..9c91c4157cd6 100644 --- a/clang/test/Misc/target-invalid-cpu-note.c +++ b/clang/test/Misc/target-invalid-cpu-note.c @@ -5,11 +5,11 @@ // RUN: not %clang_cc1 -triple arm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AARCH64 // AARCH64: error: unknown target CPU 'not-a-cpu' -// AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}} +// AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}} // RUN: not %clang_cc1 -triple arm64--- -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE_AARCH64 // TUNE_AARCH64: error: unknown target CPU 'not-a-cpu' -// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}} +// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}} // RUN: not %clang_cc1 -triple i386--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix X86 // X86: error: unknown target CPU 'not-a-cpu' diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 5e5b94255359..254f76d9e514 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -67,6 +67,8 @@ Changes to Interprocedural Optimizations Changes to the AArch64 Backend ------------------------------ +* Added support for Cortex-A78AE, Cortex-A520AE and Cortex-A720AE CPUs. + Changes to the AMDGPU Backend ----------------------------- diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h index f4bb94f98bcd..805b963a7a13 100644 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h +++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h @@ -554,6 +554,11 @@ inline constexpr CpuInfo CpuInfos[] = { {AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_MTE, AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_PREDRES})}, + {"cortex-a520ae", ARMV9_2A, + AArch64::ExtensionBitset( + {AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_MTE, + AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, + AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_PREDRES})}, {"cortex-a57", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, @@ -621,6 +626,12 @@ inline constexpr CpuInfo CpuInfos[] = { AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_PREDRES, AArch64::AEK_PROFILE})}, + {"cortex-a720ae", ARMV9_2A, + AArch64::ExtensionBitset({AArch64::AEK_SB, AArch64::AEK_SSBS, + AArch64::AEK_MTE, AArch64::AEK_FP16FML, + AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, + AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, + AArch64::AEK_PREDRES, AArch64::AEK_PROFILE})}, {"cortex-r82", ARMV8R, AArch64::ExtensionBitset({AArch64::AEK_LSE})}, {"cortex-x1", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td index 402c7292d7f8..6425aa9b091f 100644 --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -873,6 +873,12 @@ def TuneA520 : SubtargetFeature<"a520", "ARMProcFamily", "CortexA520", FeatureFuseAdrpAdd, FeaturePostRAScheduler]>; +def TuneA520AE : SubtargetFeature<"a520ae", "ARMProcFamily", "CortexA520", + "Cortex-A520AE ARM processors", [ + FeatureFuseAES, + FeatureFuseAdrpAdd, + FeaturePostRAScheduler]>; + def TuneA57 : SubtargetFeature<"a57", "ARMProcFamily", "CortexA57", "Cortex-A57 ARM processors", [ FeatureFuseAES, @@ -1001,6 +1007,17 @@ def TuneA720 : SubtargetFeature<"a720", "ARMProcFamily", "CortexA720", FeatureEnableSelectOptimize, FeaturePredictableSelectIsExpensive]>; +def TuneA720AE : SubtargetFeature<"a720ae", "ARMProcFamily", "CortexA720", + "Cortex-A720AE ARM processors", [ + FeatureFuseAES, + FeaturePostRAScheduler, + FeatureCmpBccFusion, + FeatureAddrLSLFast, + FeatureALULSLFast, + FeatureFuseAdrpAdd, + FeatureEnableSelectOptimize, + FeaturePredictableSelectIsExpensive]>; + def TuneR82 : SubtargetFeature<"cortex-r82", "ARMProcFamily", "CortexR82", "Cortex-R82 ARM processors", [ @@ -1423,6 +1440,9 @@ def ProcessorFeatures { list<SubtargetFeature> A520 = [HasV9_2aOps, FeaturePerfMon, FeatureAM, FeatureMTE, FeatureETE, FeatureSVE2BitPerm, FeatureFP16FML]; + list<SubtargetFeature> A520AE = [HasV9_2aOps, FeaturePerfMon, FeatureAM, + FeatureMTE, FeatureETE, FeatureSVE2BitPerm, + FeatureFP16FML]; list<SubtargetFeature> A65 = [HasV8_2aOps, FeatureCrypto, FeatureFPARMv8, FeatureNEON, FeatureFullFP16, FeatureDotProd, FeatureRCPC, FeatureSSBS, FeatureRAS, @@ -1456,6 +1476,9 @@ def ProcessorFeatures { list<SubtargetFeature> A720 = [HasV9_2aOps, FeatureMTE, FeatureFP16FML, FeatureTRBE, FeatureSVE2BitPerm, FeatureETE, FeaturePerfMon, FeatureSPE, FeatureSPE_EEF]; + list<SubtargetFeature> A720AE = [HasV9_2aOps, FeatureMTE, FeatureFP16FML, + FeatureTRBE, FeatureSVE2BitPerm, FeatureETE, + FeaturePerfMon, FeatureSPE, FeatureSPE_EEF]; list<SubtargetFeature> R82 = [HasV8_0rOps, FeaturePerfMon, FeatureFullFP16, FeatureFP16FML, FeatureSSBS, FeaturePredRes, FeatureSB, FeatureRDM, FeatureDotProd, @@ -1598,6 +1621,8 @@ def : ProcessorModel<"cortex-a510", CortexA510Model, ProcessorFeatures.A510, [TuneA510]>; def : ProcessorModel<"cortex-a520", CortexA510Model, ProcessorFeatures.A520, [TuneA520]>; +def : ProcessorModel<"cortex-a520ae", CortexA510Model, ProcessorFeatures.A520AE, + [TuneA520AE]>; def : ProcessorModel<"cortex-a57", CortexA57Model, ProcessorFeatures.A53, [TuneA57]>; def : ProcessorModel<"cortex-a65", CortexA53Model, ProcessorFeatures.A65, @@ -1628,6 +1653,8 @@ def : ProcessorModel<"cortex-a715", NeoverseN2Model, ProcessorFeatures.A715, [TuneA715]>; def : ProcessorModel<"cortex-a720", NeoverseN2Model, ProcessorFeatures.A720, [TuneA720]>; +def : ProcessorModel<"cortex-a720ae", NeoverseN2Model, ProcessorFeatures.A720AE, + [TuneA720AE]>; def : ProcessorModel<"cortex-r82", CortexA55Model, ProcessorFeatures.R82, [TuneR82]>; def : ProcessorModel<"cortex-x1", CortexA57Model, ProcessorFeatures.X1, diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index f65ed259eade..d2c9bae97364 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -220,6 +220,7 @@ StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) { .Case("0xd05", "cortex-a55") .Case("0xd46", "cortex-a510") .Case("0xd80", "cortex-a520") + .Case("0xd88", "cortex-a520ae") .Case("0xd07", "cortex-a57") .Case("0xd06", "cortex-a65") .Case("0xd43", "cortex-a65ae") @@ -235,6 +236,7 @@ StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) { .Case("0xd47", "cortex-a710") .Case("0xd4d", "cortex-a715") .Case("0xd81", "cortex-a720") + .Case("0xd89", "cortex-a720ae") .Case("0xd44", "cortex-x1") .Case("0xd4c", "cortex-x1c") .Case("0xd48", "cortex-x2") diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index 3773f59a3c5a..a7d0b1687a7f 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -1140,6 +1140,22 @@ INSTANTIATE_TEST_SUITE_P( AArch64::AEK_PERFMON, AArch64::AEK_PREDRES, AArch64::AEK_JSCVT, AArch64::AEK_FCMA}), "9.2-A"), + ARMCPUTestParams<AArch64::ExtensionBitset>( + "cortex-a520ae", "armv9.2-a", "crypto-neon-fp-armv8", + AArch64::ExtensionBitset( + {AArch64::AEK_BF16, AArch64::AEK_I8MM, + AArch64::AEK_SVE, AArch64::AEK_SVE2, + AArch64::AEK_FP16, AArch64::AEK_DOTPROD, + AArch64::AEK_LSE, AArch64::AEK_RDM, + AArch64::AEK_SIMD, AArch64::AEK_RCPC, + AArch64::AEK_RAS, AArch64::AEK_CRC, + AArch64::AEK_FP, AArch64::AEK_SB, + AArch64::AEK_SSBS, AArch64::AEK_MTE, + AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, + AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM, + AArch64::AEK_PERFMON, AArch64::AEK_PREDRES, + AArch64::AEK_JSCVT, AArch64::AEK_FCMA}), + "9.2-A"), ARMCPUTestParams<AArch64::ExtensionBitset>( "cortex-a57", "armv8-a", "crypto-neon-fp-armv8", AArch64::ExtensionBitset({AArch64::AEK_CRC, AArch64::AEK_AES, @@ -1283,6 +1299,23 @@ INSTANTIATE_TEST_SUITE_P( AArch64::AEK_PROFILE, AArch64::AEK_JSCVT, AArch64::AEK_FCMA}), "9.2-A"), + ARMCPUTestParams<AArch64::ExtensionBitset>( + "cortex-a720ae", "armv9.2-a", "crypto-neon-fp-armv8", + AArch64::ExtensionBitset( + {AArch64::AEK_BF16, AArch64::AEK_I8MM, + AArch64::AEK_SVE, AArch64::AEK_SVE2, + AArch64::AEK_FP16, AArch64::AEK_DOTPROD, + AArch64::AEK_LSE, AArch64::AEK_RDM, + AArch64::AEK_SIMD, AArch64::AEK_RCPC, + AArch64::AEK_RAS, AArch64::AEK_CRC, + AArch64::AEK_FP, AArch64::AEK_SB, + AArch64::AEK_SSBS, AArch64::AEK_MTE, + AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, + AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM, + AArch64::AEK_PERFMON, AArch64::AEK_PREDRES, + AArch64::AEK_PROFILE, AArch64::AEK_JSCVT, + AArch64::AEK_FCMA}), + "9.2-A"), ARMCPUTestParams<AArch64::ExtensionBitset>( "neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8", AArch64::ExtensionBitset( @@ -1717,7 +1750,7 @@ INSTANTIATE_TEST_SUITE_P( ARMCPUTestParams<AArch64::ExtensionBitset>::PrintToStringParamName); // Note: number of CPUs includes aliases. -static constexpr unsigned NumAArch64CPUArchs = 70; +static constexpr unsigned NumAArch64CPUArchs = 72; TEST(TargetParserTest, testAArch64CPUArchList) { SmallVector<StringRef, NumAArch64CPUArchs> List; -- GitLab From 29cde04c3972a54efeb6d09b1580b275f39c315a Mon Sep 17 00:00:00 2001 From: Hirofumi Nakamura <k.nakamura.hirofumi@gmail.com> Date: Tue, 19 Mar 2024 19:13:06 +0900 Subject: [PATCH 040/307] [clang-format] Fixed the warning in building document for TableGenBreakingDAGArgOperators. (#85760) Intend to fix the `Test documentation build `, degraded here https://github.com/llvm/llvm-project/pull/83149 . --- clang/docs/ClangFormatStyleOptions.rst | 2 +- clang/include/clang/Format/Format.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 35b6d0a2b52b..be021dfc5c08 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -6204,7 +6204,7 @@ the configuration (without a prefix: ``Auto``). For example the configuration, - .. code-block:: c++ + .. code-block:: yaml TableGenBreakInsideDAGArg: BreakAll TableGenBreakingDAGArgOperators: ['ins', 'outs'] diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 54861a66889e..7ad2579bf777 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -4735,7 +4735,7 @@ struct FormatStyle { /// the specified identifiers. /// /// For example the configuration, - /// \code + /// \code{.yaml} /// TableGenBreakInsideDAGArg: BreakAll /// TableGenBreakingDAGArgOperators: ['ins', 'outs'] /// \endcode -- GitLab From 6bc6e1ace9fa8453e164fa04b5d9acd5a77e089a Mon Sep 17 00:00:00 2001 From: serge-sans-paille <sguelton@mozilla.com> Date: Tue, 19 Mar 2024 11:13:15 +0100 Subject: [PATCH 041/307] [tsan][test] Switch setitimer(ITIMER_REAL, ...) to setitimer(ITIMER_VIRTUAL, ...) Followup to #85188. --- compiler-rt/test/tsan/signal_thread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler-rt/test/tsan/signal_thread.cpp b/compiler-rt/test/tsan/signal_thread.cpp index e5ea44187e32..7bba8159bf38 100644 --- a/compiler-rt/test/tsan/signal_thread.cpp +++ b/compiler-rt/test/tsan/signal_thread.cpp @@ -24,7 +24,7 @@ static void* thr(void *p) { int main() { struct sigaction act = {}; act.sa_handler = &handler; - if (sigaction(SIGALRM, &act, 0)) { + if (sigaction(SIGVTALRM, &act, 0)) { perror("sigaction"); exit(1); } @@ -33,7 +33,7 @@ int main() { t.it_value.tv_sec = 0; t.it_value.tv_usec = 10; t.it_interval = t.it_value; - if (setitimer(ITIMER_REAL, &t, 0)) { + if (setitimer(ITIMER_VIRTUAL, &t, 0)) { perror("setitimer"); exit(1); } -- GitLab From d9c31ee9568277e4303715736b40925e41503596 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand <ulrich.weigand@de.ibm.com> Date: Tue, 19 Mar 2024 11:14:57 +0100 Subject: [PATCH 042/307] Fix overflow flag for i128 USUBO We use the VSCBIQ/VSBIQ/VSBCBIQ family of instructions to implement USUBO/USUBO_CARRY for the i128 data type. However, these instructions use an inverted sense of the borrow indication flag (a value of 1 indicates *no* borrow, while a value of 0 indicated borrow). This does not match the semantics of the boolean "overflow" flag of the USUBO/USUBO_CARRY ISD nodes. Fix this by generating code to explicitly invert the flag. These cancel out of the result of USUBO feeds into an USUBO_CARRY. To avoid unnecessary zero-extend operations, also improve the DAGCombine handling of ZERO_EXTEND to optimize (zext (xor (trunc))) sequences where appropriate. Fixes: https://github.com/llvm/llvm-project/issues/83268 --- .../Target/SystemZ/SystemZISelLowering.cpp | 34 +++++++++++++++++++ llvm/test/CodeGen/SystemZ/int-usub-12.ll | 22 ++++++++++++ llvm/test/CodeGen/SystemZ/int-usub-13.ll | 2 ++ 3 files changed, 58 insertions(+) diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index 887c35a7ba24..6158b044e5db 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -4263,6 +4263,7 @@ SDValue SystemZTargetLowering::lowerXALUO(SDValue Op, if (N->getValueType(0) == MVT::i128) { unsigned BaseOp = 0; unsigned FlagOp = 0; + bool IsBorrow = false; switch (Op.getOpcode()) { default: llvm_unreachable("Unknown instruction!"); case ISD::UADDO: @@ -4272,6 +4273,7 @@ SDValue SystemZTargetLowering::lowerXALUO(SDValue Op, case ISD::USUBO: BaseOp = ISD::SUB; FlagOp = SystemZISD::VSCBI; + IsBorrow = true; break; } SDValue Result = DAG.getNode(BaseOp, DL, MVT::i128, LHS, RHS); @@ -4279,6 +4281,9 @@ SDValue SystemZTargetLowering::lowerXALUO(SDValue Op, Flag = DAG.getNode(ISD::AssertZext, DL, MVT::i128, Flag, DAG.getValueType(MVT::i1)); Flag = DAG.getZExtOrTrunc(Flag, DL, N->getValueType(1)); + if (IsBorrow) + Flag = DAG.getNode(ISD::XOR, DL, Flag.getValueType(), + Flag, DAG.getConstant(1, DL, Flag.getValueType())); return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, Flag); } @@ -4351,6 +4356,7 @@ SDValue SystemZTargetLowering::lowerUADDSUBO_CARRY(SDValue Op, if (VT == MVT::i128) { unsigned BaseOp = 0; unsigned FlagOp = 0; + bool IsBorrow = false; switch (Op.getOpcode()) { default: llvm_unreachable("Unknown instruction!"); case ISD::UADDO_CARRY: @@ -4360,14 +4366,21 @@ SDValue SystemZTargetLowering::lowerUADDSUBO_CARRY(SDValue Op, case ISD::USUBO_CARRY: BaseOp = SystemZISD::VSBI; FlagOp = SystemZISD::VSBCBI; + IsBorrow = true; break; } + if (IsBorrow) + Carry = DAG.getNode(ISD::XOR, DL, Carry.getValueType(), + Carry, DAG.getConstant(1, DL, Carry.getValueType())); Carry = DAG.getZExtOrTrunc(Carry, DL, MVT::i128); SDValue Result = DAG.getNode(BaseOp, DL, MVT::i128, LHS, RHS, Carry); SDValue Flag = DAG.getNode(FlagOp, DL, MVT::i128, LHS, RHS, Carry); Flag = DAG.getNode(ISD::AssertZext, DL, MVT::i128, Flag, DAG.getValueType(MVT::i1)); Flag = DAG.getZExtOrTrunc(Flag, DL, N->getValueType(1)); + if (IsBorrow) + Flag = DAG.getNode(ISD::XOR, DL, Flag.getValueType(), + Flag, DAG.getConstant(1, DL, Flag.getValueType())); return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, Flag); } @@ -6571,6 +6584,27 @@ SDValue SystemZTargetLowering::combineTruncateExtract( } } } + // Convert (zext (xor (trunc X), C)) into (xor (trunc X), C') if the size + // of the result is smaller than the size of X and all the truncated bits + // of X are already zero. + if (N0.getOpcode() == ISD::XOR && + N0.hasOneUse() && N0.getOperand(0).hasOneUse() && + N0.getOperand(0).getOpcode() == ISD::TRUNCATE && + N0.getOperand(1).getOpcode() == ISD::Constant) { + SDValue X = N0.getOperand(0).getOperand(0); + if (VT.isScalarInteger() && VT.getSizeInBits() < X.getValueSizeInBits()) { + KnownBits Known = DAG.computeKnownBits(X); + APInt TruncatedBits = APInt::getBitsSet(X.getValueSizeInBits(), + N0.getValueSizeInBits(), + VT.getSizeInBits()); + if (TruncatedBits.isSubsetOf(Known.Zero)) { + X = DAG.getNode(ISD::TRUNCATE, SDLoc(X), VT, X); + APInt Mask = N0.getConstantOperandAPInt(1).zext(VT.getSizeInBits()); + return DAG.getNode(ISD::XOR, SDLoc(N0), VT, + X, DAG.getConstant(Mask, SDLoc(N0), VT)); + } + } + } return SDValue(); } diff --git a/llvm/test/CodeGen/SystemZ/int-usub-12.ll b/llvm/test/CodeGen/SystemZ/int-usub-12.ll index c39a6da37048..147fbfd920a9 100644 --- a/llvm/test/CodeGen/SystemZ/int-usub-12.ll +++ b/llvm/test/CodeGen/SystemZ/int-usub-12.ll @@ -11,6 +11,7 @@ define zeroext i1 @f1(i128 %a, i128 %b, ptr %res) { ; CHECK-NEXT: vscbiq %v2, %v1, %v0 ; CHECK-NEXT: vlgvg %r2, %v2, 1 ; CHECK-NEXT: vsq %v0, %v1, %v0 +; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: vst %v0, 0(%r4), 3 ; CHECK-NEXT: br %r14 %t = call {i128, i1} @llvm.usub.with.overflow.i128(i128 %a, i128 %b) @@ -27,6 +28,7 @@ define zeroext i1 @f2(i128 %a, i128 %b) { ; CHECK-NEXT: vl %v1, 0(%r2), 3 ; CHECK-NEXT: vscbiq %v0, %v1, %v0 ; CHECK-NEXT: vlgvg %r2, %v0, 1 +; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: br %r14 %t = call {i128, i1} @llvm.usub.with.overflow.i128(i128 %a, i128 %b) %obit = extractvalue {i128, i1} %t, 1 @@ -46,5 +48,25 @@ define i128 @f3(i128 %a, i128 %b) { ret i128 %val } +define i128 @f4(i128 %a, i128 %b) { +; CHECK-LABEL: f4: +; CHECK: # %bb.0: +; CHECK-NEXT: vl %v0, 0(%r4), 3 +; CHECK-NEXT: vl %v1, 0(%r3), 3 +; CHECK-NEXT: vscbiq %v2, %v1, %v0 +; CHECK-NEXT: vlgvf %r0, %v2, 3 +; CHECK-NEXT: vgbm %v2, 0 +; CHECK-NEXT: xilf %r0, 1 +; CHECK-NEXT: jl .LBB3_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: vsq %v2, %v1, %v0 +; CHECK-NEXT: .LBB3_2: +; CHECK-NEXT: vst %v2, 0(%r2), 3 +; CHECK-NEXT: br %r14 + %val = call i128 @llvm.usub.sat.i128(i128 %a, i128 %b) + ret i128 %val +} + declare {i128, i1} @llvm.usub.with.overflow.i128(i128, i128) nounwind readnone +declare i128 @llvm.usub.sat.i128(i128, i128) nounwind readnone diff --git a/llvm/test/CodeGen/SystemZ/int-usub-13.ll b/llvm/test/CodeGen/SystemZ/int-usub-13.ll index 637e1a81de99..794af3b73fbe 100644 --- a/llvm/test/CodeGen/SystemZ/int-usub-13.ll +++ b/llvm/test/CodeGen/SystemZ/int-usub-13.ll @@ -15,6 +15,7 @@ define zeroext i1 @f1(i256 %a, i256 %b, ptr %res) { ; CHECK-NEXT: vlgvg %r2, %v5, 1 ; CHECK-NEXT: vsbiq %v0, %v1, %v0, %v4 ; CHECK-NEXT: vsq %v1, %v3, %v2 +; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: vst %v1, 16(%r4), 3 ; CHECK-NEXT: vst %v0, 0(%r4), 3 ; CHECK-NEXT: br %r14 @@ -35,6 +36,7 @@ define zeroext i1 @f2(i256 %a, i256 %b) { ; CHECK-NEXT: vscbiq %v2, %v3, %v2 ; CHECK-NEXT: vsbcbiq %v0, %v1, %v0, %v2 ; CHECK-NEXT: vlgvg %r2, %v0, 1 +; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: br %r14 %t = call {i256, i1} @llvm.usub.with.overflow.i256(i256 %a, i256 %b) %obit = extractvalue {i256, i1} %t, 1 -- GitLab From 8eee236021f72821d628ec31d8e8d1f92e7821d3 Mon Sep 17 00:00:00 2001 From: jeanPerier <jperier@nvidia.com> Date: Tue, 19 Mar 2024 11:26:36 +0100 Subject: [PATCH 043/307] [flang] Lower sequence associated argument passed by descriptor (#85696) The current lowering did not handle sequence associated argument passed by descriptor. This case is special because sequence association implies that the actual and dummy argument need to to agree in rank and shape. Usually, arguments that can be sequence associated are passed by raw address, and the shape mistmatch is transparent. But there are three cases of explicit and assumed-size arrays passed by descriptors: - polymorphic arguments - BIND(C) assumed-length arguments (F'2023 18.3.7 (5)). - length parametrized derived types (TBD) The callee side is expecting a descriptor containing the dummy rank and shape. This was not the case. This patch fix that by evaluating the dummy shape on the caller side using the interface (that has to be available when arguments are passed by descriptors). --- .../include/flang/Evaluate/characteristics.h | 8 + flang/include/flang/Lower/CallInterface.h | 40 ++- flang/include/flang/Lower/ConvertVariable.h | 13 +- flang/lib/Lower/CallInterface.cpp | 134 ++++++-- flang/lib/Lower/ConvertCall.cpp | 158 ++++++++- flang/lib/Lower/ConvertVariable.cpp | 29 +- .../call-sequence-associated-descriptors.f90 | 309 ++++++++++++++++++ 7 files changed, 642 insertions(+), 49 deletions(-) create mode 100644 flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90 diff --git a/flang/include/flang/Evaluate/characteristics.h b/flang/include/flang/Evaluate/characteristics.h index f2f37866ecde..82c31c0c4043 100644 --- a/flang/include/flang/Evaluate/characteristics.h +++ b/flang/include/flang/Evaluate/characteristics.h @@ -177,6 +177,14 @@ public: int corank() const { return corank_; } int Rank() const { return GetRank(shape_); } + + // Can sequence association apply to this argument? + bool CanBeSequenceAssociated() const { + constexpr Attrs notAssumedOrExplicitShape{ + ~Attrs{Attr::AssumedSize, Attr::Coarray}}; + return Rank() > 0 && (attrs() & notAssumedOrExplicitShape).none(); + } + bool IsCompatibleWith(parser::ContextualMessages &, const TypeAndShape &that, const char *thisIs = "pointer", const char *thatIs = "target", bool omitShapeConformanceCheck = false, diff --git a/flang/include/flang/Lower/CallInterface.h b/flang/include/flang/Lower/CallInterface.h index e77ac4e179ba..80b057642537 100644 --- a/flang/include/flang/Lower/CallInterface.h +++ b/flang/include/flang/Lower/CallInterface.h @@ -174,6 +174,12 @@ public: /// May the dummy argument require INTENT(OUT) finalization /// on entry to the invoked procedure? Provides conservative answer. bool mayRequireIntentoutFinalization() const; + /// Is the dummy argument an explicit-shape or assumed-size array that + /// must be passed by descriptor? Sequence association imply the actual + /// argument shape/rank may differ with the dummy shape/rank (see F'2023 + /// section 15.5.2.12), so care is needed when creating the descriptor + /// for the dummy argument. + bool isSequenceAssociatedDescriptor() const; /// How entity is passed by. PassEntityBy passBy; /// What is the entity (SymbolRef for callee/ActualArgument* for caller) @@ -273,8 +279,6 @@ public: actualInputs.resize(getNumFIRArguments()); } - using ExprVisitor = std::function<void(evaluate::Expr<evaluate::SomeType>)>; - /// CRTP callbacks bool hasAlternateReturns() const; std::string getMangledName() const; @@ -312,12 +316,21 @@ public: /// procedure. const Fortran::semantics::Symbol *getProcedureSymbol() const; + /// Return the dummy argument symbol if this is a call to a user + /// defined procedure with explicit interface. Returns nullptr if there + /// is no user defined explicit interface. + const Fortran::semantics::Symbol * + getDummySymbol(const PassedEntity &entity) const; + /// Helpers to place the lowered arguments at the right place once they /// have been lowered. void placeInput(const PassedEntity &passedEntity, mlir::Value arg); void placeAddressAndLengthInput(const PassedEntity &passedEntity, mlir::Value addr, mlir::Value len); + /// Get lowered FIR argument given the Fortran argument. + mlir::Value getInput(const PassedEntity &passedEntity); + /// If this is a call to a procedure pointer or dummy, returns the related /// procedure designator. Nullptr otherwise. const Fortran::evaluate::ProcedureDesignator *getIfIndirectCall() const; @@ -333,13 +346,27 @@ public: /// the result specification expressions (extents and lengths) ? If needed, /// this mapping must be done after argument lowering, and before the call /// itself. - bool mustMapInterfaceSymbols() const; + bool mustMapInterfaceSymbolsForResult() const; + /// Must the caller map function interface symbols in order to evaluate + /// the specification expressions of a given dummy argument? + bool mustMapInterfaceSymbolsForDummyArgument(const PassedEntity &) const; + + /// Visitor for specification expression. Boolean indicate the specification + /// expression is for the last extent of an assumed size array. + using ExprVisitor = + std::function<void(evaluate::Expr<evaluate::SomeType>, bool)>; /// Walk the result non-deferred extent specification expressions. - void walkResultExtents(ExprVisitor) const; + void walkResultExtents(const ExprVisitor &) const; /// Walk the result non-deferred length specification expressions. - void walkResultLengths(ExprVisitor) const; + void walkResultLengths(const ExprVisitor &) const; + /// Walk non-deferred extent specification expressions of a dummy argument. + void walkDummyArgumentExtents(const PassedEntity &, + const ExprVisitor &) const; + /// Walk non-deferred length specification expressions of a dummy argument. + void walkDummyArgumentLengths(const PassedEntity &, + const ExprVisitor &) const; /// Get the mlir::Value that is passed as argument \p sym of the function /// being called. The arguments must have been placed before calling this @@ -355,6 +382,9 @@ public: /// returns the storage type. mlir::Type getResultStorageType() const; + /// Return FIR type of argument. + mlir::Type getDummyArgumentType(const PassedEntity &) const; + // Copy of base implementation. static constexpr bool hasHostAssociated() { return false; } mlir::Type getHostAssociatedTy() const { diff --git a/flang/include/flang/Lower/ConvertVariable.h b/flang/include/flang/Lower/ConvertVariable.h index b13bb412f0f3..ab30e317d1d9 100644 --- a/flang/include/flang/Lower/ConvertVariable.h +++ b/flang/include/flang/Lower/ConvertVariable.h @@ -93,9 +93,16 @@ void mapSymbolAttributes(AbstractConverter &, const semantics::SymbolRef &, /// Instantiate the variables that appear in the specification expressions /// of the result of a function call. The instantiated variables are added /// to \p symMap. -void mapCallInterfaceSymbols(AbstractConverter &, - const Fortran::lower::CallerInterface &caller, - SymMap &symMap); +void mapCallInterfaceSymbolsForResult( + AbstractConverter &, const Fortran::lower::CallerInterface &caller, + SymMap &symMap); + +/// Instantiate the variables that appear in the specification expressions +/// of a dummy argument of a procedure call. The instantiated variables are +/// added to \p symMap. +void mapCallInterfaceSymbolsForDummyArgument( + AbstractConverter &, const Fortran::lower::CallerInterface &caller, + SymMap &symMap, const Fortran::semantics::Symbol &dummySymbol); // TODO: consider saving the initial expression symbol dependence analysis in // in the PFT variable and dealing with the dependent symbols instantiation in diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp index 6b71aabf7fdc..2f95d53c383b 100644 --- a/flang/lib/Lower/CallInterface.cpp +++ b/flang/lib/Lower/CallInterface.cpp @@ -310,21 +310,22 @@ bool Fortran::lower::CallerInterface::verifyActualInputs() const { return true; } -void Fortran::lower::CallerInterface::walkResultLengths( - ExprVisitor visitor) const { - assert(characteristic && "characteristic was not computed"); - const Fortran::evaluate::characteristics::FunctionResult &result = - characteristic->functionResult.value(); - const Fortran::evaluate::characteristics::TypeAndShape *typeAndShape = - result.GetTypeAndShape(); - assert(typeAndShape && "no result type"); - Fortran::evaluate::DynamicType dynamicType = typeAndShape->type(); - // Visit result length specification expressions that are explicit. +mlir::Value +Fortran::lower::CallerInterface::getInput(const PassedEntity &passedEntity) { + return actualInputs[passedEntity.firArgument]; +} + +static void walkLengths( + const Fortran::evaluate::characteristics::TypeAndShape &typeAndShape, + const Fortran::lower::CallerInterface::ExprVisitor &visitor, + Fortran::lower::AbstractConverter &converter) { + Fortran::evaluate::DynamicType dynamicType = typeAndShape.type(); + // Visit length specification expressions that are explicit. if (dynamicType.category() == Fortran::common::TypeCategory::Character) { if (std::optional<Fortran::evaluate::ExtentExpr> length = dynamicType.GetCharLength()) - visitor(toEvExpr(*length)); - } else if (dynamicType.category() == common::TypeCategory::Derived && + visitor(toEvExpr(*length), /*assumedSize=*/false); + } else if (dynamicType.category() == Fortran::common::TypeCategory::Derived && !dynamicType.IsUnlimitedPolymorphic()) { const Fortran::semantics::DerivedTypeSpec &derivedTypeSpec = dynamicType.GetDerivedTypeSpec(); @@ -334,11 +335,33 @@ void Fortran::lower::CallerInterface::walkResultLengths( } } +void Fortran::lower::CallerInterface::walkResultLengths( + const ExprVisitor &visitor) const { + assert(characteristic && "characteristic was not computed"); + const Fortran::evaluate::characteristics::FunctionResult &result = + characteristic->functionResult.value(); + const Fortran::evaluate::characteristics::TypeAndShape *typeAndShape = + result.GetTypeAndShape(); + assert(typeAndShape && "no result type"); + return walkLengths(*typeAndShape, visitor, converter); +} + +void Fortran::lower::CallerInterface::walkDummyArgumentLengths( + const PassedEntity &passedEntity, const ExprVisitor &visitor) const { + if (!passedEntity.characteristics) + return; + if (const auto *dummy = + std::get_if<Fortran::evaluate::characteristics::DummyDataObject>( + &passedEntity.characteristics->u)) + walkLengths(dummy->type, visitor, converter); +} + // Compute extent expr from shapeSpec of an explicit shape. -// TODO: Allow evaluate shape analysis to work in a mode where it disregards -// the non-constant aspects when building the shape to avoid having this here. static Fortran::evaluate::ExtentExpr getExtentExpr(const Fortran::semantics::ShapeSpec &shapeSpec) { + if (shapeSpec.ubound().isStar()) + // F'2023 18.5.3 point 5. + return Fortran::evaluate::ExtentExpr{-1}; const auto &ubound = shapeSpec.ubound().GetExplicit(); const auto &lbound = shapeSpec.lbound().GetExplicit(); assert(lbound && ubound && "shape must be explicit"); @@ -346,20 +369,27 @@ getExtentExpr(const Fortran::semantics::ShapeSpec &shapeSpec) { Fortran::evaluate::ExtentExpr{1}; } +static void +walkExtents(const Fortran::semantics::Symbol &symbol, + const Fortran::lower::CallerInterface::ExprVisitor &visitor) { + if (const auto *objectDetails = + symbol.detailsIf<Fortran::semantics::ObjectEntityDetails>()) + if (objectDetails->shape().IsExplicitShape() || + Fortran::semantics::IsAssumedSizeArray(symbol)) + for (const Fortran::semantics::ShapeSpec &shapeSpec : + objectDetails->shape()) + visitor(Fortran::evaluate::AsGenericExpr(getExtentExpr(shapeSpec)), + /*assumedSize=*/shapeSpec.ubound().isStar()); +} + void Fortran::lower::CallerInterface::walkResultExtents( - ExprVisitor visitor) const { + const ExprVisitor &visitor) const { // Walk directly the result symbol shape (the characteristic shape may contain // descriptor inquiries to it that would fail to lower on the caller side). const Fortran::semantics::SubprogramDetails *interfaceDetails = getInterfaceDetails(); if (interfaceDetails) { - const Fortran::semantics::Symbol &result = interfaceDetails->result(); - if (const auto *objectDetails = - result.detailsIf<Fortran::semantics::ObjectEntityDetails>()) - if (objectDetails->shape().IsExplicitShape()) - for (const Fortran::semantics::ShapeSpec &shapeSpec : - objectDetails->shape()) - visitor(Fortran::evaluate::AsGenericExpr(getExtentExpr(shapeSpec))); + walkExtents(interfaceDetails->result(), visitor); } else { if (procRef.Rank() != 0) fir::emitFatalError( @@ -368,7 +398,18 @@ void Fortran::lower::CallerInterface::walkResultExtents( } } -bool Fortran::lower::CallerInterface::mustMapInterfaceSymbols() const { +void Fortran::lower::CallerInterface::walkDummyArgumentExtents( + const PassedEntity &passedEntity, const ExprVisitor &visitor) const { + const Fortran::semantics::SubprogramDetails *interfaceDetails = + getInterfaceDetails(); + if (!interfaceDetails) + return; + const Fortran::semantics::Symbol *dummy = getDummySymbol(passedEntity); + assert(dummy && "dummy symbol was not set"); + walkExtents(*dummy, visitor); +} + +bool Fortran::lower::CallerInterface::mustMapInterfaceSymbolsForResult() const { assert(characteristic && "characteristic was not computed"); const std::optional<Fortran::evaluate::characteristics::FunctionResult> &result = characteristic->functionResult; @@ -376,7 +417,7 @@ bool Fortran::lower::CallerInterface::mustMapInterfaceSymbols() const { !getInterfaceDetails() || result->IsProcedurePointer()) return false; bool allResultSpecExprConstant = true; - auto visitor = [&](const Fortran::lower::SomeExpr &e) { + auto visitor = [&](const Fortran::lower::SomeExpr &e, bool) { allResultSpecExprConstant &= Fortran::evaluate::IsConstantExpr(e); }; walkResultLengths(visitor); @@ -384,6 +425,17 @@ bool Fortran::lower::CallerInterface::mustMapInterfaceSymbols() const { return !allResultSpecExprConstant; } +bool Fortran::lower::CallerInterface::mustMapInterfaceSymbolsForDummyArgument( + const PassedEntity &arg) const { + bool allResultSpecExprConstant = true; + auto visitor = [&](const Fortran::lower::SomeExpr &e, bool) { + allResultSpecExprConstant &= Fortran::evaluate::IsConstantExpr(e); + }; + walkDummyArgumentLengths(arg, visitor); + walkDummyArgumentExtents(arg, visitor); + return !allResultSpecExprConstant; +} + mlir::Value Fortran::lower::CallerInterface::getArgumentValue( const semantics::Symbol &sym) const { mlir::Location loc = converter.getCurrentLocation(); @@ -401,6 +453,24 @@ mlir::Value Fortran::lower::CallerInterface::getArgumentValue( return actualInputs[mlirArgIndex]; } +const Fortran::semantics::Symbol * +Fortran::lower::CallerInterface::getDummySymbol( + const PassedEntity &passedEntity) const { + const Fortran::semantics::SubprogramDetails *ifaceDetails = + getInterfaceDetails(); + if (!ifaceDetails) + return nullptr; + std::size_t argPosition = 0; + for (const auto &arg : getPassedArguments()) { + if (&arg == &passedEntity) + break; + ++argPosition; + } + if (argPosition >= ifaceDetails->dummyArgs().size()) + return nullptr; + return ifaceDetails->dummyArgs()[argPosition]; +} + mlir::Type Fortran::lower::CallerInterface::getResultStorageType() const { if (passedResult) return fir::dyn_cast_ptrEleTy(inputs[passedResult->firArgument].type); @@ -408,6 +478,11 @@ mlir::Type Fortran::lower::CallerInterface::getResultStorageType() const { return outputs[0].type; } +mlir::Type Fortran::lower::CallerInterface::getDummyArgumentType( + const PassedEntity &passedEntity) const { + return inputs[passedEntity.firArgument].type; +} + const Fortran::semantics::Symbol & Fortran::lower::CallerInterface::getResultSymbol() const { mlir::Location loc = converter.getCurrentLocation(); @@ -1387,6 +1462,17 @@ bool Fortran::lower::CallInterface< return Fortran::semantics::IsFinalizable(*derived); } +template <typename T> +bool Fortran::lower::CallInterface< + T>::PassedEntity::isSequenceAssociatedDescriptor() const { + if (!characteristics || passBy != PassEntityBy::Box) + return false; + const auto *dummy = + std::get_if<Fortran::evaluate::characteristics::DummyDataObject>( + &characteristics->u); + return dummy && dummy->type.CanBeSequenceAssociated(); +} + template <typename T> void Fortran::lower::CallInterface<T>::determineInterface( bool isImplicit, diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp index 95569337a06e..6eba243c237c 100644 --- a/flang/lib/Lower/ConvertCall.cpp +++ b/flang/lib/Lower/ConvertCall.cpp @@ -164,6 +164,125 @@ static mlir::Value readDim3Value(fir::FirOpBuilder &builder, mlir::Location loc, return hlfir::loadTrivialScalar(loc, builder, hlfir::Entity{designate}); } +static mlir::Value remapActualToDummyDescriptor( + mlir::Location loc, Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymMap &symMap, + const Fortran::lower::CallerInterface::PassedEntity &arg, + Fortran::lower::CallerInterface &caller, bool isBindcCall) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + mlir::IndexType idxTy = builder.getIndexType(); + mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0); + Fortran::lower::StatementContext localStmtCtx; + auto lowerSpecExpr = [&](const auto &expr, + bool isAssumedSizeExtent) -> mlir::Value { + mlir::Value convertExpr = builder.createConvert( + loc, idxTy, fir::getBase(converter.genExprValue(expr, localStmtCtx))); + if (isAssumedSizeExtent) + return convertExpr; + return fir::factory::genMaxWithZero(builder, loc, convertExpr); + }; + bool mapSymbols = caller.mustMapInterfaceSymbolsForDummyArgument(arg); + if (mapSymbols) { + symMap.pushScope(); + const Fortran::semantics::Symbol *sym = caller.getDummySymbol(arg); + assert(sym && "call must have explicit interface to map interface symbols"); + Fortran::lower::mapCallInterfaceSymbolsForDummyArgument(converter, caller, + symMap, *sym); + } + llvm::SmallVector<mlir::Value> extents; + llvm::SmallVector<mlir::Value> lengths; + mlir::Type dummyBoxType = caller.getDummyArgumentType(arg); + mlir::Type dummyBaseType = fir::unwrapPassByRefType(dummyBoxType); + if (dummyBaseType.isa<fir::SequenceType>()) + caller.walkDummyArgumentExtents( + arg, [&](const Fortran::lower::SomeExpr &e, bool isAssumedSizeExtent) { + extents.emplace_back(lowerSpecExpr(e, isAssumedSizeExtent)); + }); + mlir::Value shape; + if (!extents.empty()) { + if (isBindcCall) { + // Preserve zero lower bounds (see F'2023 18.5.3). + llvm::SmallVector<mlir::Value> lowerBounds(extents.size(), zero); + shape = builder.genShape(loc, lowerBounds, extents); + } else { + shape = builder.genShape(loc, extents); + } + } + + hlfir::Entity explicitArgument = hlfir::Entity{caller.getInput(arg)}; + mlir::Type dummyElementType = fir::unwrapSequenceType(dummyBaseType); + if (auto recType = llvm::dyn_cast<fir::RecordType>(dummyElementType)) + if (recType.getNumLenParams() > 0) + TODO(loc, "sequence association of length parameterized derived type " + "dummy arguments"); + if (fir::isa_char(dummyElementType)) + lengths.emplace_back(hlfir::genCharLength(loc, builder, explicitArgument)); + mlir::Value baseAddr = + hlfir::genVariableRawAddress(loc, builder, explicitArgument); + baseAddr = builder.createConvert(loc, fir::ReferenceType::get(dummyBaseType), + baseAddr); + mlir::Value mold; + if (fir::isPolymorphicType(dummyBoxType)) + mold = explicitArgument; + mlir::Value remapped = + builder.create<fir::EmboxOp>(loc, dummyBoxType, baseAddr, shape, + /*slice=*/mlir::Value{}, lengths, mold); + if (mapSymbols) + symMap.popScope(); + return remapped; +} + +/// Create a descriptor for sequenced associated descriptor that are passed +/// by descriptor. Sequence association (F'2023 15.5.2.12) implies that the +/// dummy shape and rank need to not be the same as the actual argument. This +/// helper creates a descriptor based on the dummy shape and rank (sequence +/// association can only happen with explicit and assumed-size array) so that it +/// is safe to assume the rank of the incoming descriptor inside the callee. +/// This helper must be called once all the actual arguments have been lowered +/// and placed inside "caller". Copy-in/copy-out must already have been +/// generated if needed using the actual argument shape (the dummy shape may be +/// assumed-size). +static void remapActualToDummyDescriptors( + mlir::Location loc, Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymMap &symMap, + const Fortran::lower::PreparedActualArguments &loweredActuals, + Fortran::lower::CallerInterface &caller, bool isBindcCall) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + for (auto [preparedActual, arg] : + llvm::zip(loweredActuals, caller.getPassedArguments())) { + if (arg.isSequenceAssociatedDescriptor()) { + if (!preparedActual.value().handleDynamicOptional()) { + mlir::Value remapped = remapActualToDummyDescriptor( + loc, converter, symMap, arg, caller, isBindcCall); + caller.placeInput(arg, remapped); + } else { + // Absent optional actual argument descriptor cannot be read and + // remapped unconditionally. + mlir::Type dummyType = caller.getDummyArgumentType(arg); + mlir::Value isPresent = preparedActual.value().getIsPresent(); + auto &argLambdaCapture = arg; + mlir::Value remapped = + builder + .genIfOp(loc, {dummyType}, isPresent, + /*withElseRegion=*/true) + .genThen([&]() { + mlir::Value newBox = remapActualToDummyDescriptor( + loc, converter, symMap, argLambdaCapture, caller, + isBindcCall); + builder.create<fir::ResultOp>(loc, newBox); + }) + .genElse([&]() { + mlir::Value absent = + builder.create<fir::AbsentOp>(loc, dummyType); + builder.create<fir::ResultOp>(loc, absent); + }) + .getResults()[0]; + caller.placeInput(arg, remapped); + } + } + } +} + std::pair<fir::ExtendedValue, bool> Fortran::lower::genCallOpAndResult( mlir::Location loc, Fortran::lower::AbstractConverter &converter, Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx, @@ -171,12 +290,11 @@ std::pair<fir::ExtendedValue, bool> Fortran::lower::genCallOpAndResult( std::optional<mlir::Type> resultType, bool isElemental) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); using PassBy = Fortran::lower::CallerInterface::PassEntityBy; - // Handle cases where caller must allocate the result or a fir.box for it. bool mustPopSymMap = false; - if (caller.mustMapInterfaceSymbols()) { + if (caller.mustMapInterfaceSymbolsForResult()) { symMap.pushScope(); mustPopSymMap = true; - Fortran::lower::mapCallInterfaceSymbols(converter, caller, symMap); + Fortran::lower::mapCallInterfaceSymbolsForResult(converter, caller, symMap); } // If this is an indirect call, retrieve the function address. Also retrieve // the result length if this is a character function (note that this length @@ -221,12 +339,16 @@ std::pair<fir::ExtendedValue, bool> Fortran::lower::genCallOpAndResult( return {}; mlir::Type type = caller.getResultStorageType(); if (type.isa<fir::SequenceType>()) - caller.walkResultExtents([&](const Fortran::lower::SomeExpr &e) { - extents.emplace_back(lowerSpecExpr(e)); - }); - caller.walkResultLengths([&](const Fortran::lower::SomeExpr &e) { - lengths.emplace_back(lowerSpecExpr(e)); - }); + caller.walkResultExtents( + [&](const Fortran::lower::SomeExpr &e, bool isAssumedSizeExtent) { + assert(!isAssumedSizeExtent && "result cannot be assumed-size"); + extents.emplace_back(lowerSpecExpr(e)); + }); + caller.walkResultLengths( + [&](const Fortran::lower::SomeExpr &e, bool isAssumedSizeExtent) { + assert(!isAssumedSizeExtent && "result cannot be assumed-size"); + lengths.emplace_back(lowerSpecExpr(e)); + }); // Result length parameters should not be provided to box storage // allocation and save_results, but they are still useful information to @@ -1056,10 +1178,16 @@ static PreparedDummyArgument preparePresentUserCallActualArgument( // Create dummy type with actual argument rank when the dummy is an assumed // rank. That way, all the operation to create dummy descriptors are ranked if // the actual argument is ranked, which allows simple code generation. + // Also do the same when the dummy is a sequence associated descriptor + // because the actual shape/rank may mismatch with the dummy, and the dummy + // may be an assumed-size array, so any descriptor manipulation should use the + // actual argument shape information. A descriptor with the dummy shape + // information will be created later when all actual arguments are ready. mlir::Type dummyTypeWithActualRank = dummyType; if (auto baseBoxDummy = mlir::dyn_cast<fir::BaseBoxType>(dummyType)) if (baseBoxDummy.isAssumedRank() || - arg.testTKR(Fortran::common::IgnoreTKR::Rank)) + arg.testTKR(Fortran::common::IgnoreTKR::Rank) || + arg.isSequenceAssociatedDescriptor()) dummyTypeWithActualRank = baseBoxDummy.getBoxTypeWithNewShape(actual.getType()); // Preserve the actual type in the argument preparation in case IgnoreTKR(t) @@ -1342,6 +1470,7 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals, mlir::FunctionType callSiteType, CallContext &callContext) { using PassBy = Fortran::lower::CallerInterface::PassEntityBy; mlir::Location loc = callContext.loc; + bool mustRemapActualToDummyDescriptors = false; fir::FirOpBuilder &builder = callContext.getBuilder(); llvm::SmallVector<CallCleanUp> callCleanUps; for (auto [preparedActual, arg] : @@ -1398,6 +1527,9 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals, callCleanUps.append(preparedDummy.cleanups.rbegin(), preparedDummy.cleanups.rend()); caller.placeInput(arg, preparedDummy.dummy); + if (arg.passBy == PassBy::Box) + mustRemapActualToDummyDescriptors |= + arg.isSequenceAssociatedDescriptor(); } break; case PassBy::BoxProcRef: { PreparedDummyArgument preparedDummy = @@ -1490,6 +1622,12 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals, } break; } } + // Handle cases where caller must allocate the result or a fir.box for it. + if (mustRemapActualToDummyDescriptors) + remapActualToDummyDescriptors(loc, callContext.converter, + callContext.symMap, loweredActuals, caller, + callContext.isBindcCall()); + // Prepare lowered arguments according to the interface // and map the lowered values to the dummy // arguments. diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index a673a18cd20d..94d849862099 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -2260,19 +2260,20 @@ void Fortran::lower::instantiateVariable(AbstractConverter &converter, instantiateLocal(converter, var, symMap); } -void Fortran::lower::mapCallInterfaceSymbols( - AbstractConverter &converter, const Fortran::lower::CallerInterface &caller, - SymMap &symMap) { +static void +mapCallInterfaceSymbol(const Fortran::semantics::Symbol &interfaceSymbol, + Fortran::lower::AbstractConverter &converter, + const Fortran::lower::CallerInterface &caller, + Fortran::lower::SymMap &symMap) { Fortran::lower::AggregateStoreMap storeMap; - const Fortran::semantics::Symbol &result = caller.getResultSymbol(); for (Fortran::lower::pft::Variable var : - Fortran::lower::pft::getDependentVariableList(result)) { + Fortran::lower::pft::getDependentVariableList(interfaceSymbol)) { if (var.isAggregateStore()) { instantiateVariable(converter, var, symMap, storeMap); continue; } const Fortran::semantics::Symbol &sym = var.getSymbol(); - if (&sym == &result) + if (&sym == &interfaceSymbol) continue; const auto *hostDetails = sym.detailsIf<Fortran::semantics::HostAssocDetails>(); @@ -2293,7 +2294,8 @@ void Fortran::lower::mapCallInterfaceSymbols( // instantiateVariable that would try to allocate a new storage. continue; } - if (Fortran::semantics::IsDummy(sym) && sym.owner() == result.owner()) { + if (Fortran::semantics::IsDummy(sym) && + sym.owner() == interfaceSymbol.owner()) { // Get the argument for the dummy argument symbols of the current call. symMap.addSymbol(sym, caller.getArgumentValue(sym)); // All the properties of the dummy variable may not come from the actual @@ -2307,6 +2309,19 @@ void Fortran::lower::mapCallInterfaceSymbols( } } +void Fortran::lower::mapCallInterfaceSymbolsForResult( + AbstractConverter &converter, const Fortran::lower::CallerInterface &caller, + SymMap &symMap) { + const Fortran::semantics::Symbol &result = caller.getResultSymbol(); + mapCallInterfaceSymbol(result, converter, caller, symMap); +} + +void Fortran::lower::mapCallInterfaceSymbolsForDummyArgument( + AbstractConverter &converter, const Fortran::lower::CallerInterface &caller, + SymMap &symMap, const Fortran::semantics::Symbol &dummySymbol) { + mapCallInterfaceSymbol(dummySymbol, converter, caller, symMap); +} + void Fortran::lower::mapSymbolAttributes( AbstractConverter &converter, const Fortran::semantics::SymbolRef &symbol, Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx, diff --git a/flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90 b/flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90 new file mode 100644 index 000000000000..9cbb9279a868 --- /dev/null +++ b/flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90 @@ -0,0 +1,309 @@ +! Test lowering of sequence associated arguments (F'2023 15.5.2.12) passed +! by descriptor. The descriptor on the caller side is prepared according to +! the dummy argument shape. +! RUN: bbc -emit-hlfir -polymorphic-type -o - %s | FileCheck %s + +module bindc_seq_assoc + interface + subroutine takes_char(x, n) bind(c) + integer :: n + character(*) :: x(n) + end subroutine + subroutine takes_char_assumed_size(x) bind(c) + character(*) :: x(10, *) + end subroutine + subroutine takes_optional_char(x, n) bind(c) + integer :: n + character(*), optional :: x(n) + end subroutine + end interface +contains + subroutine test_char_1(x) + character(*) :: x(10, 20) + call takes_char(x, 100) + end subroutine +! CHECK-LABEL: func.func @_QMbindc_seq_assocPtest_char_1( +! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_2:.*]](%[[VAL_5:.*]]) typeparams %[[VAL_1:.*]]#1 {uniq_name = "_QMbindc_seq_assocFtest_char_1Ex"} : (!fir.ref<!fir.array<10x20x!fir.char<1,?>>>, !fir.shape<2>, index) -> (!fir.box<!fir.array<10x20x!fir.char<1,?>>>, !fir.ref<!fir.array<10x20x!fir.char<1,?>>>) +! CHECK: %[[VAL_7:.*]] = arith.constant 100 : i32 +! CHECK: %[[VAL_8:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_9:.*]] = fir.shift %[[VAL_8]], %[[VAL_8]] : (index, index) -> !fir.shift<2> +! CHECK: %[[VAL_10:.*]] = fir.rebox %[[VAL_6]]#0(%[[VAL_9]]) : (!fir.box<!fir.array<10x20x!fir.char<1,?>>>, !fir.shift<2>) -> !fir.box<!fir.array<10x20x!fir.char<1,?>>> +! CHECK: %[[VAL_11:.*]]:3 = hlfir.associate %[[VAL_7]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1) +! CHECK: %[[VAL_12:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_11]]#1 {uniq_name = "_QMbindc_seq_assocFtakes_charEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) +! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_13]]#0 : !fir.ref<i32> +! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i32) -> i64 +! CHECK: %[[VAL_16:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_15]], %[[VAL_16]] : i64 +! CHECK: %[[VAL_18:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_17]], %[[VAL_18]] : i64 +! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (i64) -> index +! CHECK: %[[VAL_21:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_22:.*]] = arith.cmpi sgt, %[[VAL_20]], %[[VAL_21]] : index +! CHECK: %[[VAL_23:.*]] = arith.select %[[VAL_22]], %[[VAL_20]], %[[VAL_21]] : index +! CHECK: %[[VAL_24:.*]] = fir.shape_shift %[[VAL_12]], %[[VAL_23]] : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_25:.*]] = fir.box_elesize %[[VAL_10]] : (!fir.box<!fir.array<10x20x!fir.char<1,?>>>) -> index +! CHECK: %[[VAL_26:.*]] = fir.box_addr %[[VAL_10]] : (!fir.box<!fir.array<10x20x!fir.char<1,?>>>) -> !fir.ref<!fir.array<10x20x!fir.char<1,?>>> +! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<!fir.array<10x20x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>> +! CHECK: %[[VAL_28:.*]] = fir.embox %[[VAL_27]](%[[VAL_24]]) typeparams %[[VAL_25]] : (!fir.ref<!fir.array<?x!fir.char<1,?>>>, !fir.shapeshift<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,?>>> +! CHECK: fir.call @takes_char(%[[VAL_28]], %[[VAL_11]]#1) fastmath<contract> : (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.ref<i32>) -> () +! CHECK: hlfir.end_associate %[[VAL_11]]#1, %[[VAL_11]]#2 : !fir.ref<i32>, i1 +! CHECK: return +! CHECK: } + + subroutine test_char_copy_in_copy_out(x) + character(*) :: x(:, :) + call takes_char(x, 100) + end subroutine +! CHECK-LABEL: func.func @_QMbindc_seq_assocPtest_char_copy_in_copy_out( +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:.*]] {uniq_name = "_QMbindc_seq_assocFtest_char_copy_in_copy_outEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.box<!fir.array<?x?x!fir.char<1,?>>>) +! CHECK: %[[VAL_2:.*]] = arith.constant 100 : i32 +! CHECK: %[[VAL_3:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i1) +! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_5:.*]] = fir.shift %[[VAL_4]], %[[VAL_4]] : (index, index) -> !fir.shift<2> +! CHECK: %[[VAL_6:.*]] = fir.rebox %[[VAL_3]]#0(%[[VAL_5]]) : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>> +! CHECK: %[[VAL_7:.*]]:3 = hlfir.associate %[[VAL_2]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1) +! CHECK: %[[VAL_8:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]]#1 {uniq_name = "_QMbindc_seq_assocFtakes_charEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) +! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i32> +! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i32) -> i64 +! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_13:.*]] = arith.subi %[[VAL_11]], %[[VAL_12]] : i64 +! CHECK: %[[VAL_14:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_13]], %[[VAL_14]] : i64 +! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i64) -> index +! CHECK: %[[VAL_17:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_18:.*]] = arith.cmpi sgt, %[[VAL_16]], %[[VAL_17]] : index +! CHECK: %[[VAL_19:.*]] = arith.select %[[VAL_18]], %[[VAL_16]], %[[VAL_17]] : index +! CHECK: %[[VAL_20:.*]] = fir.shape_shift %[[VAL_8]], %[[VAL_19]] : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_21:.*]] = fir.box_elesize %[[VAL_6]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> index +! CHECK: %[[VAL_22:.*]] = fir.box_addr %[[VAL_6]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>> +! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>> +! CHECK: %[[VAL_24:.*]] = fir.embox %[[VAL_23]](%[[VAL_20]]) typeparams %[[VAL_21]] : (!fir.ref<!fir.array<?x!fir.char<1,?>>>, !fir.shapeshift<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,?>>> +! CHECK: fir.call @takes_char(%[[VAL_24]], %[[VAL_7]]#1) fastmath<contract> : (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.ref<i32>) -> () +! CHECK: hlfir.copy_out %[[VAL_3]]#0, %[[VAL_3]]#1 to %[[VAL_1]]#0 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i1, !fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> () +! CHECK: hlfir.end_associate %[[VAL_7]]#1, %[[VAL_7]]#2 : !fir.ref<i32>, i1 +! CHECK: return +! CHECK: } + + subroutine test_char_assumed_size(x) + character(*) :: x(:, :) + call takes_char_assumed_size(x) + end subroutine +! CHECK-LABEL: func.func @_QMbindc_seq_assocPtest_char_assumed_size( +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:.*]] {uniq_name = "_QMbindc_seq_assocFtest_char_assumed_sizeEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.box<!fir.array<?x?x!fir.char<1,?>>>) +! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i1) +! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_4:.*]] = fir.shift %[[VAL_3]], %[[VAL_3]] : (index, index) -> !fir.shift<2> +! CHECK: %[[VAL_5:.*]] = fir.rebox %[[VAL_2]]#0(%[[VAL_4]]) : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>> +! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_7:.*]] = arith.constant 10 : i64 +! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_7]], %[[VAL_8]] : i64 +! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_11:.*]] = arith.addi %[[VAL_9]], %[[VAL_10]] : i64 +! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i64) -> index +! CHECK: %[[VAL_13:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_14:.*]] = arith.cmpi sgt, %[[VAL_12]], %[[VAL_13]] : index +! CHECK: %[[VAL_15:.*]] = arith.select %[[VAL_14]], %[[VAL_12]], %[[VAL_13]] : index +! CHECK: %[[VAL_16:.*]] = arith.constant -1 : i64 +! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index +! CHECK: %[[VAL_18:.*]] = fir.shape_shift %[[VAL_6]], %[[VAL_15]], %[[VAL_6]], %[[VAL_17]] : (index, index, index, index) -> !fir.shapeshift<2> +! CHECK: %[[VAL_19:.*]] = fir.box_elesize %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> index +! CHECK: %[[VAL_20:.*]] = fir.box_addr %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>> +! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<10x?x!fir.char<1,?>>> +! CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_21]](%[[VAL_18]]) typeparams %[[VAL_19]] : (!fir.ref<!fir.array<10x?x!fir.char<1,?>>>, !fir.shapeshift<2>, index) -> !fir.box<!fir.array<10x?x!fir.char<1,?>>> +! CHECK: fir.call @takes_char_assumed_size(%[[VAL_22]]) fastmath<contract> : (!fir.box<!fir.array<10x?x!fir.char<1,?>>>) -> () +! CHECK: hlfir.copy_out %[[VAL_2]]#0, %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i1, !fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> () +! CHECK: return +! CHECK: } + + subroutine test_optional_char(x) + character(*), optional :: x(10, 20) + call takes_optional_char(x, 100) + end subroutine +! CHECK-LABEL: func.func @_QMbindc_seq_assocPtest_optional_char( +! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_2:.*]](%[[VAL_5:.*]]) typeparams %[[VAL_1:.*]]#1 {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QMbindc_seq_assocFtest_optional_charEx"} : (!fir.ref<!fir.array<10x20x!fir.char<1,?>>>, !fir.shape<2>, index) -> (!fir.box<!fir.array<10x20x!fir.char<1,?>>>, !fir.ref<!fir.array<10x20x!fir.char<1,?>>>) +! CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_6]]#0 : (!fir.box<!fir.array<10x20x!fir.char<1,?>>>) -> i1 +! CHECK: %[[VAL_8:.*]] = arith.constant 100 : i32 +! CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_7]] -> (!fir.box<!fir.array<10x20x!fir.char<1,?>>>) { +! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_11:.*]] = fir.shift %[[VAL_10]], %[[VAL_10]] : (index, index) -> !fir.shift<2> +! CHECK: %[[VAL_12:.*]] = fir.rebox %[[VAL_6]]#0(%[[VAL_11]]) : (!fir.box<!fir.array<10x20x!fir.char<1,?>>>, !fir.shift<2>) -> !fir.box<!fir.array<10x20x!fir.char<1,?>>> +! CHECK: fir.result %[[VAL_12]] : !fir.box<!fir.array<10x20x!fir.char<1,?>>> +! CHECK: } else { +! CHECK: %[[VAL_13:.*]] = fir.absent !fir.box<!fir.array<10x20x!fir.char<1,?>>> +! CHECK: fir.result %[[VAL_13]] : !fir.box<!fir.array<10x20x!fir.char<1,?>>> +! CHECK: } +! CHECK: %[[VAL_14:.*]]:3 = hlfir.associate %[[VAL_8]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1) +! CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_7]] -> (!fir.box<!fir.array<?x!fir.char<1,?>>>) { +! CHECK: %[[VAL_16:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_17:.*]]:2 = hlfir.declare %[[VAL_14]]#1 {uniq_name = "_QMbindc_seq_assocFtakes_optional_charEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) +! CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_17]]#0 : !fir.ref<i32> +! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i32) -> i64 +! CHECK: %[[VAL_20:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_21:.*]] = arith.subi %[[VAL_19]], %[[VAL_20]] : i64 +! CHECK: %[[VAL_22:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_23:.*]] = arith.addi %[[VAL_21]], %[[VAL_22]] : i64 +! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_23]] : (i64) -> index +! CHECK: %[[VAL_25:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_26:.*]] = arith.cmpi sgt, %[[VAL_24]], %[[VAL_25]] : index +! CHECK: %[[VAL_27:.*]] = arith.select %[[VAL_26]], %[[VAL_24]], %[[VAL_25]] : index +! CHECK: %[[VAL_28:.*]] = fir.shape_shift %[[VAL_16]], %[[VAL_27]] : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_29:.*]] = fir.box_elesize %[[VAL_9]] : (!fir.box<!fir.array<10x20x!fir.char<1,?>>>) -> index +! CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<!fir.array<10x20x!fir.char<1,?>>>) -> !fir.ref<!fir.array<10x20x!fir.char<1,?>>> +! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.ref<!fir.array<10x20x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>> +! CHECK: %[[VAL_32:.*]] = fir.embox %[[VAL_31]](%[[VAL_28]]) typeparams %[[VAL_29]] : (!fir.ref<!fir.array<?x!fir.char<1,?>>>, !fir.shapeshift<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,?>>> +! CHECK: fir.result %[[VAL_32]] : !fir.box<!fir.array<?x!fir.char<1,?>>> +! CHECK: } else { +! CHECK: %[[VAL_33:.*]] = fir.absent !fir.box<!fir.array<?x!fir.char<1,?>>> +! CHECK: fir.result %[[VAL_33]] : !fir.box<!fir.array<?x!fir.char<1,?>>> +! CHECK: } +! CHECK: fir.call @takes_optional_char(%[[VAL_15]], %[[VAL_14]]#1) fastmath<contract> : (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.ref<i32>) -> () +! CHECK: hlfir.end_associate %[[VAL_14]]#1, %[[VAL_14]]#2 : !fir.ref<i32>, i1 +! CHECK: return +! CHECK: } +end module + +module poly_seq_assoc + interface + subroutine takes_poly(x, n) + integer :: n + class(*) :: x(n) + end subroutine + subroutine takes_poly_assumed_size(x) + class(*) :: x(10, *) + end subroutine + subroutine takes_optional_poly(x, n) + integer :: n + class(*), optional :: x(n) + end subroutine + end interface +contains + subroutine test_poly_1(x) + class(*) :: x(10, 20) + call takes_poly(x, 100) + end subroutine +! CHECK-LABEL: func.func @_QMpoly_seq_assocPtest_poly_1( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.array<10x20xnone>> {fir.bindc_name = "x"}) { +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:.*]] {uniq_name = "_QMpoly_seq_assocFtest_poly_1Ex"} : (!fir.class<!fir.array<10x20xnone>>) -> (!fir.class<!fir.array<10x20xnone>>, !fir.class<!fir.array<10x20xnone>>) +! CHECK: %[[VAL_2:.*]] = arith.constant 100 : i32 +! CHECK: %[[VAL_3:.*]]:3 = hlfir.associate %[[VAL_2]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1) +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]]#1 {uniq_name = "_QMpoly_seq_assocFtakes_polyEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) +! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i32> +! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> i64 +! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_8:.*]] = arith.subi %[[VAL_6]], %[[VAL_7]] : i64 +! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_10:.*]] = arith.addi %[[VAL_8]], %[[VAL_9]] : i64 +! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i64) -> index +! CHECK: %[[VAL_12:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_13:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[VAL_12]] : index +! CHECK: %[[VAL_14:.*]] = arith.select %[[VAL_13]], %[[VAL_11]], %[[VAL_12]] : index +! CHECK: %[[VAL_15:.*]] = fir.shape %[[VAL_14]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_16:.*]] = fir.box_addr %[[VAL_1]]#1 : (!fir.class<!fir.array<10x20xnone>>) -> !fir.ref<!fir.array<10x20xnone>> +! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (!fir.ref<!fir.array<10x20xnone>>) -> !fir.ref<!fir.array<?xnone>> +! CHECK: %[[VAL_18:.*]] = fir.embox %[[VAL_17]](%[[VAL_15]]) source_box %[[VAL_1]]#0 : (!fir.ref<!fir.array<?xnone>>, !fir.shape<1>, !fir.class<!fir.array<10x20xnone>>) -> !fir.class<!fir.array<?xnone>> +! CHECK: fir.call @_QPtakes_poly(%[[VAL_18]], %[[VAL_3]]#1) fastmath<contract> : (!fir.class<!fir.array<?xnone>>, !fir.ref<i32>) -> () +! CHECK: hlfir.end_associate %[[VAL_3]]#1, %[[VAL_3]]#2 : !fir.ref<i32>, i1 +! CHECK: return +! CHECK: } + + subroutine test_poly_copy_in_copy_out(x) + class(*) :: x(:, :) + call takes_poly(x, 100) + end subroutine +! CHECK-LABEL: func.func @_QMpoly_seq_assocPtest_poly_copy_in_copy_out( +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:.*]] {uniq_name = "_QMpoly_seq_assocFtest_poly_copy_in_copy_outEx"} : (!fir.class<!fir.array<?x?xnone>>) -> (!fir.class<!fir.array<?x?xnone>>, !fir.class<!fir.array<?x?xnone>>) +! CHECK: %[[VAL_2:.*]] = arith.constant 100 : i32 +! CHECK: %[[VAL_3:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>) -> (!fir.class<!fir.array<?x?xnone>>, i1) +! CHECK: %[[VAL_4:.*]]:3 = hlfir.associate %[[VAL_2]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1) +! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]]#1 {uniq_name = "_QMpoly_seq_assocFtakes_polyEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) +! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32> +! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> i64 +! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_7]], %[[VAL_8]] : i64 +! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_11:.*]] = arith.addi %[[VAL_9]], %[[VAL_10]] : i64 +! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i64) -> index +! CHECK: %[[VAL_13:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_14:.*]] = arith.cmpi sgt, %[[VAL_12]], %[[VAL_13]] : index +! CHECK: %[[VAL_15:.*]] = arith.select %[[VAL_14]], %[[VAL_12]], %[[VAL_13]] : index +! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_15]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_17:.*]] = fir.box_addr %[[VAL_3]]#0 : (!fir.class<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?x?xnone>> +! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (!fir.ref<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?xnone>> +! CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_18]](%[[VAL_16]]) source_box %[[VAL_3]]#0 : (!fir.ref<!fir.array<?xnone>>, !fir.shape<1>, !fir.class<!fir.array<?x?xnone>>) -> !fir.class<!fir.array<?xnone>> +! CHECK: fir.call @_QPtakes_poly(%[[VAL_19]], %[[VAL_4]]#1) fastmath<contract> : (!fir.class<!fir.array<?xnone>>, !fir.ref<i32>) -> () +! CHECK: hlfir.copy_out %[[VAL_3]]#0, %[[VAL_3]]#1 to %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>, i1, !fir.class<!fir.array<?x?xnone>>) -> () +! CHECK: hlfir.end_associate %[[VAL_4]]#1, %[[VAL_4]]#2 : !fir.ref<i32>, i1 +! CHECK: return +! CHECK: } + + subroutine test_poly_assumed_size(x) + class(*) :: x(:, :) + call takes_poly_assumed_size(x) + end subroutine +! CHECK-LABEL: func.func @_QMpoly_seq_assocPtest_poly_assumed_size( +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:.*]] {uniq_name = "_QMpoly_seq_assocFtest_poly_assumed_sizeEx"} : (!fir.class<!fir.array<?x?xnone>>) -> (!fir.class<!fir.array<?x?xnone>>, !fir.class<!fir.array<?x?xnone>>) +! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>) -> (!fir.class<!fir.array<?x?xnone>>, i1) +! CHECK: %[[VAL_3:.*]] = arith.constant 10 : i64 +! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_5:.*]] = arith.subi %[[VAL_3]], %[[VAL_4]] : i64 +! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_7:.*]] = arith.addi %[[VAL_5]], %[[VAL_6]] : i64 +! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i64) -> index +! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_10:.*]] = arith.cmpi sgt, %[[VAL_8]], %[[VAL_9]] : index +! CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_10]], %[[VAL_8]], %[[VAL_9]] : index +! CHECK: %[[VAL_12:.*]] = arith.constant -1 : i64 +! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i64) -> index +! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_11]], %[[VAL_13]] : (index, index) -> !fir.shape<2> +! CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_2]]#0 : (!fir.class<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?x?xnone>> +! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (!fir.ref<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<10x?xnone>> +! CHECK: %[[VAL_17:.*]] = fir.embox %[[VAL_16]](%[[VAL_14]]) source_box %[[VAL_2]]#0 : (!fir.ref<!fir.array<10x?xnone>>, !fir.shape<2>, !fir.class<!fir.array<?x?xnone>>) -> !fir.class<!fir.array<10x?xnone>> +! CHECK: fir.call @_QPtakes_poly_assumed_size(%[[VAL_17]]) fastmath<contract> : (!fir.class<!fir.array<10x?xnone>>) -> () +! CHECK: hlfir.copy_out %[[VAL_2]]#0, %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>, i1, !fir.class<!fir.array<?x?xnone>>) -> () +! CHECK: return +! CHECK: } + + subroutine test_optional_poly(x) + class(*), optional :: x(10, 20) + call takes_optional_poly(x, 100) + end subroutine +! CHECK-LABEL: func.func @_QMpoly_seq_assocPtest_optional_poly( +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:.*]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QMpoly_seq_assocFtest_optional_polyEx"} : (!fir.class<!fir.array<10x20xnone>>) -> (!fir.class<!fir.array<10x20xnone>>, !fir.class<!fir.array<10x20xnone>>) +! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_1]]#0 : (!fir.class<!fir.array<10x20xnone>>) -> i1 +! CHECK: %[[VAL_3:.*]] = arith.constant 100 : i32 +! CHECK: %[[VAL_4:.*]] = fir.if %[[VAL_2]] -> (!fir.class<!fir.array<10x20xnone>>) { +! CHECK: fir.result %[[VAL_1]]#0 : !fir.class<!fir.array<10x20xnone>> +! CHECK: } else { +! CHECK: %[[VAL_5:.*]] = fir.absent !fir.class<!fir.array<10x20xnone>> +! CHECK: fir.result %[[VAL_5]] : !fir.class<!fir.array<10x20xnone>> +! CHECK: } +! CHECK: %[[VAL_6:.*]]:3 = hlfir.associate %[[VAL_3]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1) +! CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_2]] -> (!fir.class<!fir.array<?xnone>>) { +! CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_6]]#1 {uniq_name = "_QMpoly_seq_assocFtakes_optional_polyEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) +! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> +! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> i64 +! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_12:.*]] = arith.subi %[[VAL_10]], %[[VAL_11]] : i64 +! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i64 +! CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_12]], %[[VAL_13]] : i64 +! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> index +! CHECK: %[[VAL_16:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_17:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[VAL_16]] : index +! CHECK: %[[VAL_18:.*]] = arith.select %[[VAL_17]], %[[VAL_15]], %[[VAL_16]] : index +! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_18]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_20:.*]] = fir.box_addr %[[VAL_4]] : (!fir.class<!fir.array<10x20xnone>>) -> !fir.ref<!fir.array<10x20xnone>> +! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.ref<!fir.array<10x20xnone>>) -> !fir.ref<!fir.array<?xnone>> +! CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_21]](%[[VAL_19]]) source_box %[[VAL_4]] : (!fir.ref<!fir.array<?xnone>>, !fir.shape<1>, !fir.class<!fir.array<10x20xnone>>) -> !fir.class<!fir.array<?xnone>> +! CHECK: fir.result %[[VAL_22]] : !fir.class<!fir.array<?xnone>> +! CHECK: } else { +! CHECK: %[[VAL_23:.*]] = fir.absent !fir.class<!fir.array<?xnone>> +! CHECK: fir.result %[[VAL_23]] : !fir.class<!fir.array<?xnone>> +! CHECK: } +! CHECK: fir.call @_QPtakes_optional_poly(%[[VAL_7]], %[[VAL_6]]#1) fastmath<contract> : (!fir.class<!fir.array<?xnone>>, !fir.ref<i32>) -> () +! CHECK: hlfir.end_associate %[[VAL_6]]#1, %[[VAL_6]]#2 : !fir.ref<i32>, i1 +! CHECK: return +! CHECK: } +end module -- GitLab From 9f6b6636c77ad4736c66efd0119b3be4541e9af4 Mon Sep 17 00:00:00 2001 From: Sergio Afonso <safonsof@amd.com> Date: Tue, 19 Mar 2024 10:39:57 +0000 Subject: [PATCH 044/307] [Flang][OpenMP] Complete and organize directive sets (#85219) This patch adds a couple of new directive sets for composite constructs, completes some of the existing ones with missing values, refactors all* sets to always build on the corresponding top* set and reorders sets and directives alphabetically. No functional change intended. --- .../flang/Semantics/openmp-directive-sets.h | 392 ++++++++++-------- 1 file changed, 210 insertions(+), 182 deletions(-) diff --git a/flang/include/flang/Semantics/openmp-directive-sets.h b/flang/include/flang/Semantics/openmp-directive-sets.h index a4f27b00152e..91773ae3ea9a 100644 --- a/flang/include/flang/Semantics/openmp-directive-sets.h +++ b/flang/include/flang/Semantics/openmp-directive-sets.h @@ -20,32 +20,27 @@ namespace llvm::omp { // Directive sets for single directives //===----------------------------------------------------------------------===// // - top<Directive>Set: The directive appears alone or as the first in a -// combined construct. -// - all<Directive>Set: All standalone or combined uses of the directive. +// compound construct. +// - all<Directive>Set: All standalone or compound uses of the directive. -static const OmpDirectiveSet topParallelSet{ - Directive::OMPD_parallel, - Directive::OMPD_parallel_do, - Directive::OMPD_parallel_do_simd, - Directive::OMPD_parallel_sections, - Directive::OMPD_parallel_workshare, -}; - -static const OmpDirectiveSet allParallelSet{ +static const OmpDirectiveSet topDistributeSet{ + Directive::OMPD_distribute, Directive::OMPD_distribute_parallel_do, Directive::OMPD_distribute_parallel_do_simd, - Directive::OMPD_parallel, - Directive::OMPD_parallel_do, - Directive::OMPD_parallel_do_simd, - Directive::OMPD_parallel_sections, - Directive::OMPD_parallel_workshare, - Directive::OMPD_target_parallel, - Directive::OMPD_target_parallel_do, - Directive::OMPD_target_parallel_do_simd, - Directive::OMPD_target_teams_distribute_parallel_do, - Directive::OMPD_target_teams_distribute_parallel_do_simd, - Directive::OMPD_teams_distribute_parallel_do, - Directive::OMPD_teams_distribute_parallel_do_simd, + Directive::OMPD_distribute_simd, +}; + +static const OmpDirectiveSet allDistributeSet{ + OmpDirectiveSet{ + llvm::omp::OMPD_target_teams_distribute, + llvm::omp::OMPD_target_teams_distribute_parallel_do, + llvm::omp::OMPD_target_teams_distribute_parallel_do_simd, + llvm::omp::OMPD_target_teams_distribute_simd, + llvm::omp::OMPD_teams_distribute, + llvm::omp::OMPD_teams_distribute_parallel_do, + llvm::omp::OMPD_teams_distribute_parallel_do_simd, + llvm::omp::OMPD_teams_distribute_simd, + } | topDistributeSet, }; static const OmpDirectiveSet topDoSet{ @@ -54,26 +49,69 @@ static const OmpDirectiveSet topDoSet{ }; static const OmpDirectiveSet allDoSet{ - Directive::OMPD_distribute_parallel_do, - Directive::OMPD_distribute_parallel_do_simd, + OmpDirectiveSet{ + Directive::OMPD_distribute_parallel_do, + Directive::OMPD_distribute_parallel_do_simd, + Directive::OMPD_parallel_do, + Directive::OMPD_parallel_do_simd, + Directive::OMPD_target_parallel_do, + Directive::OMPD_target_parallel_do_simd, + Directive::OMPD_target_teams_distribute_parallel_do, + Directive::OMPD_target_teams_distribute_parallel_do_simd, + Directive::OMPD_teams_distribute_parallel_do, + Directive::OMPD_teams_distribute_parallel_do_simd, + } | topDoSet, +}; + +static const OmpDirectiveSet topParallelSet{ + Directive::OMPD_parallel, Directive::OMPD_parallel_do, Directive::OMPD_parallel_do_simd, - Directive::OMPD_do, - Directive::OMPD_do_simd, - Directive::OMPD_target_parallel_do, - Directive::OMPD_target_parallel_do_simd, - Directive::OMPD_target_teams_distribute_parallel_do, - Directive::OMPD_target_teams_distribute_parallel_do_simd, - Directive::OMPD_teams_distribute_parallel_do, - Directive::OMPD_teams_distribute_parallel_do_simd, + Directive::OMPD_parallel_masked_taskloop, + Directive::OMPD_parallel_masked_taskloop_simd, + Directive::OMPD_parallel_master_taskloop, + Directive::OMPD_parallel_master_taskloop_simd, + Directive::OMPD_parallel_sections, + Directive::OMPD_parallel_workshare, }; -static const OmpDirectiveSet topTaskloopSet{ - Directive::OMPD_taskloop, - Directive::OMPD_taskloop_simd, +static const OmpDirectiveSet allParallelSet{ + OmpDirectiveSet{ + Directive::OMPD_distribute_parallel_do, + Directive::OMPD_distribute_parallel_do_simd, + Directive::OMPD_target_parallel, + Directive::OMPD_target_parallel_do, + Directive::OMPD_target_parallel_do_simd, + Directive::OMPD_target_teams_distribute_parallel_do, + Directive::OMPD_target_teams_distribute_parallel_do_simd, + Directive::OMPD_teams_distribute_parallel_do, + Directive::OMPD_teams_distribute_parallel_do_simd, + } | topParallelSet, +}; + +static const OmpDirectiveSet topSimdSet{ + Directive::OMPD_simd, }; -static const OmpDirectiveSet allTaskloopSet{topTaskloopSet}; +static const OmpDirectiveSet allSimdSet{ + OmpDirectiveSet{ + Directive::OMPD_distribute_parallel_do_simd, + Directive::OMPD_distribute_simd, + Directive::OMPD_do_simd, + Directive::OMPD_masked_taskloop_simd, + Directive::OMPD_master_taskloop_simd, + Directive::OMPD_parallel_do_simd, + Directive::OMPD_parallel_masked_taskloop_simd, + Directive::OMPD_parallel_master_taskloop_simd, + Directive::OMPD_target_parallel_do_simd, + Directive::OMPD_target_simd, + Directive::OMPD_target_teams_distribute_parallel_do_simd, + Directive::OMPD_target_teams_distribute_simd, + Directive::OMPD_taskloop_simd, + Directive::OMPD_teams_distribute_parallel_do_simd, + Directive::OMPD_teams_distribute_simd, + } | topSimdSet, +}; static const OmpDirectiveSet topTargetSet{ Directive::OMPD_target, @@ -90,23 +128,22 @@ static const OmpDirectiveSet topTargetSet{ static const OmpDirectiveSet allTargetSet{topTargetSet}; -static const OmpDirectiveSet topSimdSet{ - Directive::OMPD_simd, +static const OmpDirectiveSet topTaskloopSet{ + Directive::OMPD_taskloop, + Directive::OMPD_taskloop_simd, }; -static const OmpDirectiveSet allSimdSet{ - Directive::OMPD_distribute_parallel_do_simd, - Directive::OMPD_distribute_simd, - Directive::OMPD_do_simd, - Directive::OMPD_parallel_do_simd, - Directive::OMPD_simd, - Directive::OMPD_target_parallel_do_simd, - Directive::OMPD_target_simd, - Directive::OMPD_target_teams_distribute_parallel_do_simd, - Directive::OMPD_target_teams_distribute_simd, - Directive::OMPD_taskloop_simd, - Directive::OMPD_teams_distribute_parallel_do_simd, - Directive::OMPD_teams_distribute_simd, +static const OmpDirectiveSet allTaskloopSet{ + OmpDirectiveSet{ + Directive::OMPD_masked_taskloop, + Directive::OMPD_masked_taskloop_simd, + Directive::OMPD_master_taskloop, + Directive::OMPD_master_taskloop_simd, + Directive::OMPD_parallel_masked_taskloop, + Directive::OMPD_parallel_masked_taskloop_simd, + Directive::OMPD_parallel_master_taskloop, + Directive::OMPD_parallel_master_taskloop_simd, + } | topTaskloopSet, }; static const OmpDirectiveSet topTeamsSet{ @@ -118,178 +155,134 @@ static const OmpDirectiveSet topTeamsSet{ }; static const OmpDirectiveSet allTeamsSet{ - llvm::omp::OMPD_target_teams, - llvm::omp::OMPD_target_teams_distribute, - llvm::omp::OMPD_target_teams_distribute_parallel_do, - llvm::omp::OMPD_target_teams_distribute_parallel_do_simd, - llvm::omp::OMPD_target_teams_distribute_simd, - llvm::omp::OMPD_teams, - llvm::omp::OMPD_teams_distribute, - llvm::omp::OMPD_teams_distribute_parallel_do, - llvm::omp::OMPD_teams_distribute_parallel_do_simd, - llvm::omp::OMPD_teams_distribute_simd, -}; - -static const OmpDirectiveSet topDistributeSet{ - Directive::OMPD_distribute, - Directive::OMPD_distribute_parallel_do, - Directive::OMPD_distribute_parallel_do_simd, - Directive::OMPD_distribute_simd, -}; - -static const OmpDirectiveSet allDistributeSet{ - llvm::omp::OMPD_distribute, - llvm::omp::OMPD_distribute_parallel_do, - llvm::omp::OMPD_distribute_parallel_do_simd, - llvm::omp::OMPD_distribute_simd, - llvm::omp::OMPD_target_teams_distribute, - llvm::omp::OMPD_target_teams_distribute_parallel_do, - llvm::omp::OMPD_target_teams_distribute_parallel_do_simd, - llvm::omp::OMPD_target_teams_distribute_simd, - llvm::omp::OMPD_teams_distribute, - llvm::omp::OMPD_teams_distribute_parallel_do, - llvm::omp::OMPD_teams_distribute_parallel_do_simd, - llvm::omp::OMPD_teams_distribute_simd, + OmpDirectiveSet{ + llvm::omp::OMPD_target_teams, + llvm::omp::OMPD_target_teams_distribute, + llvm::omp::OMPD_target_teams_distribute_parallel_do, + llvm::omp::OMPD_target_teams_distribute_parallel_do_simd, + llvm::omp::OMPD_target_teams_distribute_simd, + } | topTeamsSet, }; //===----------------------------------------------------------------------===// // Directive sets for groups of multiple directives //===----------------------------------------------------------------------===// +// Composite constructs +static const OmpDirectiveSet allDistributeParallelDoSet{ + allDistributeSet & allParallelSet & allDoSet}; +static const OmpDirectiveSet allDistributeParallelDoSimdSet{ + allDistributeSet & allParallelSet & allDoSet & allSimdSet}; +static const OmpDirectiveSet allDistributeSimdSet{ + allDistributeSet & allSimdSet}; static const OmpDirectiveSet allDoSimdSet{allDoSet & allSimdSet}; +static const OmpDirectiveSet allTaskloopSimdSet{allTaskloopSet & allSimdSet}; -static const OmpDirectiveSet workShareSet{ - OmpDirectiveSet{ - Directive::OMPD_workshare, - Directive::OMPD_parallel_workshare, - Directive::OMPD_parallel_sections, - Directive::OMPD_sections, - Directive::OMPD_single, - } | allDoSet, -}; - -static const OmpDirectiveSet taskGeneratingSet{ - OmpDirectiveSet{ - Directive::OMPD_task, - } | allTaskloopSet, -}; - -static const OmpDirectiveSet nonPartialVarSet{ - Directive::OMPD_allocate, - Directive::OMPD_allocators, - Directive::OMPD_threadprivate, - Directive::OMPD_declare_target, +static const OmpDirectiveSet blockConstructSet{ + Directive::OMPD_master, + Directive::OMPD_ordered, + Directive::OMPD_parallel, + Directive::OMPD_parallel_workshare, + Directive::OMPD_single, + Directive::OMPD_target, + Directive::OMPD_target_data, + Directive::OMPD_target_parallel, + Directive::OMPD_target_teams, + Directive::OMPD_task, + Directive::OMPD_taskgroup, + Directive::OMPD_teams, + Directive::OMPD_workshare, }; static const OmpDirectiveSet loopConstructSet{ - Directive::OMPD_distribute_parallel_do_simd, + Directive::OMPD_distribute, Directive::OMPD_distribute_parallel_do, + Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_distribute_simd, - Directive::OMPD_distribute, - Directive::OMPD_do_simd, Directive::OMPD_do, - Directive::OMPD_parallel_do_simd, + Directive::OMPD_do_simd, + Directive::OMPD_masked_taskloop, + Directive::OMPD_masked_taskloop_simd, + Directive::OMPD_master_taskloop, + Directive::OMPD_master_taskloop_simd, Directive::OMPD_parallel_do, + Directive::OMPD_parallel_do_simd, + Directive::OMPD_parallel_masked_taskloop, + Directive::OMPD_parallel_masked_taskloop_simd, + Directive::OMPD_parallel_master_taskloop, + Directive::OMPD_parallel_master_taskloop_simd, Directive::OMPD_simd, - Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_parallel_do, + Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_simd, - Directive::OMPD_target_teams_distribute_parallel_do_simd, + Directive::OMPD_target_teams_distribute, Directive::OMPD_target_teams_distribute_parallel_do, + Directive::OMPD_target_teams_distribute_parallel_do_simd, Directive::OMPD_target_teams_distribute_simd, - Directive::OMPD_target_teams_distribute, - Directive::OMPD_taskloop_simd, Directive::OMPD_taskloop, - Directive::OMPD_teams_distribute_parallel_do_simd, + Directive::OMPD_taskloop_simd, + Directive::OMPD_teams_distribute, Directive::OMPD_teams_distribute_parallel_do, + Directive::OMPD_teams_distribute_parallel_do_simd, Directive::OMPD_teams_distribute_simd, - Directive::OMPD_teams_distribute, Directive::OMPD_tile, Directive::OMPD_unroll, }; -static const OmpDirectiveSet blockConstructSet{ - Directive::OMPD_master, - Directive::OMPD_ordered, - Directive::OMPD_parallel_workshare, - Directive::OMPD_parallel, - Directive::OMPD_single, - Directive::OMPD_target_data, - Directive::OMPD_target_parallel, - Directive::OMPD_target_teams, - Directive::OMPD_target, - Directive::OMPD_task, - Directive::OMPD_taskgroup, - Directive::OMPD_teams, - Directive::OMPD_workshare, -}; - -//===----------------------------------------------------------------------===// -// Directive sets for allowed/not allowed nested directives -//===----------------------------------------------------------------------===// - -static const OmpDirectiveSet nestedOrderedErrSet{ - Directive::OMPD_critical, - Directive::OMPD_ordered, - Directive::OMPD_atomic, - Directive::OMPD_task, - Directive::OMPD_taskloop, +static const OmpDirectiveSet nonPartialVarSet{ + Directive::OMPD_allocate, + Directive::OMPD_allocators, + Directive::OMPD_threadprivate, + Directive::OMPD_declare_target, }; -static const OmpDirectiveSet nestedWorkshareErrSet{ +static const OmpDirectiveSet taskGeneratingSet{ OmpDirectiveSet{ Directive::OMPD_task, - Directive::OMPD_taskloop, - Directive::OMPD_critical, - Directive::OMPD_ordered, - Directive::OMPD_atomic, - Directive::OMPD_master, - } | workShareSet, + } | allTaskloopSet, }; -static const OmpDirectiveSet nestedMasterErrSet{ +static const OmpDirectiveSet workShareSet{ OmpDirectiveSet{ - Directive::OMPD_atomic, - } | taskGeneratingSet | - workShareSet, + Directive::OMPD_workshare, + Directive::OMPD_parallel_workshare, + Directive::OMPD_parallel_sections, + Directive::OMPD_sections, + Directive::OMPD_single, + } | allDoSet, }; +//===----------------------------------------------------------------------===// +// Directive sets for allowed/not allowed nested directives +//===----------------------------------------------------------------------===// + static const OmpDirectiveSet nestedBarrierErrSet{ OmpDirectiveSet{ - Directive::OMPD_critical, - Directive::OMPD_ordered, Directive::OMPD_atomic, + Directive::OMPD_critical, Directive::OMPD_master, + Directive::OMPD_ordered, } | taskGeneratingSet | workShareSet, }; -static const OmpDirectiveSet nestedTeamsAllowedSet{ - Directive::OMPD_parallel, - Directive::OMPD_parallel_do, - Directive::OMPD_parallel_do_simd, - Directive::OMPD_parallel_master, - Directive::OMPD_parallel_master_taskloop, - Directive::OMPD_parallel_master_taskloop_simd, - Directive::OMPD_parallel_sections, - Directive::OMPD_parallel_workshare, - Directive::OMPD_distribute, +static const OmpDirectiveSet nestedCancelDoAllowedSet{ Directive::OMPD_distribute_parallel_do, - Directive::OMPD_distribute_parallel_do_simd, - Directive::OMPD_distribute_simd, + Directive::OMPD_do, + Directive::OMPD_parallel_do, + Directive::OMPD_target_parallel_do, + Directive::OMPD_target_teams_distribute_parallel_do, + Directive::OMPD_teams_distribute_parallel_do, }; -static const OmpDirectiveSet nestedOrderedParallelErrSet{ +static const OmpDirectiveSet nestedCancelParallelAllowedSet{ Directive::OMPD_parallel, Directive::OMPD_target_parallel, - Directive::OMPD_parallel_sections, - Directive::OMPD_parallel_workshare, }; -static const OmpDirectiveSet nestedOrderedDoAllowedSet{ - Directive::OMPD_do, - Directive::OMPD_parallel_do, - Directive::OMPD_target_parallel_do, +static const OmpDirectiveSet nestedCancelSectionsAllowedSet{ + Directive::OMPD_parallel_sections, + Directive::OMPD_sections, }; static const OmpDirectiveSet nestedCancelTaskgroupAllowedSet{ @@ -297,29 +290,64 @@ static const OmpDirectiveSet nestedCancelTaskgroupAllowedSet{ Directive::OMPD_taskloop, }; -static const OmpDirectiveSet nestedCancelSectionsAllowedSet{ - Directive::OMPD_sections, - Directive::OMPD_parallel_sections, +static const OmpDirectiveSet nestedMasterErrSet{ + OmpDirectiveSet{ + Directive::OMPD_atomic, + } | taskGeneratingSet | + workShareSet, }; -static const OmpDirectiveSet nestedCancelDoAllowedSet{ +static const OmpDirectiveSet nestedOrderedDoAllowedSet{ Directive::OMPD_do, - Directive::OMPD_distribute_parallel_do, Directive::OMPD_parallel_do, Directive::OMPD_target_parallel_do, - Directive::OMPD_target_teams_distribute_parallel_do, - Directive::OMPD_teams_distribute_parallel_do, }; -static const OmpDirectiveSet nestedCancelParallelAllowedSet{ +static const OmpDirectiveSet nestedOrderedErrSet{ + Directive::OMPD_atomic, + Directive::OMPD_critical, + Directive::OMPD_ordered, + Directive::OMPD_task, + Directive::OMPD_taskloop, +}; + +static const OmpDirectiveSet nestedOrderedParallelErrSet{ Directive::OMPD_parallel, + Directive::OMPD_parallel_sections, + Directive::OMPD_parallel_workshare, Directive::OMPD_target_parallel, }; static const OmpDirectiveSet nestedReduceWorkshareAllowedSet{ Directive::OMPD_do, - Directive::OMPD_sections, Directive::OMPD_do_simd, + Directive::OMPD_sections, +}; + +static const OmpDirectiveSet nestedTeamsAllowedSet{ + Directive::OMPD_distribute, + Directive::OMPD_distribute_parallel_do, + Directive::OMPD_distribute_parallel_do_simd, + Directive::OMPD_distribute_simd, + Directive::OMPD_parallel, + Directive::OMPD_parallel_do, + Directive::OMPD_parallel_do_simd, + Directive::OMPD_parallel_master, + Directive::OMPD_parallel_master_taskloop, + Directive::OMPD_parallel_master_taskloop_simd, + Directive::OMPD_parallel_sections, + Directive::OMPD_parallel_workshare, +}; + +static const OmpDirectiveSet nestedWorkshareErrSet{ + OmpDirectiveSet{ + Directive::OMPD_atomic, + Directive::OMPD_critical, + Directive::OMPD_master, + Directive::OMPD_ordered, + Directive::OMPD_task, + Directive::OMPD_taskloop, + } | workShareSet, }; } // namespace llvm::omp -- GitLab From 577306133e14fc4f448b010920dc446607fcabaf Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Tue, 19 Mar 2024 11:32:05 +0100 Subject: [PATCH 045/307] [mlir][bufferization] Fix OpFilter not to crash on unloaded dialects --- .../mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h index d8cfeee24663..94d5c08dfe45 100644 --- a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h +++ b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h @@ -142,7 +142,7 @@ public: /// This function adds an ALLOW entry. void allowDialect(StringRef dialectNamespace) { Entry::FilterFn filterFn = [=](Operation *op) { - return op->getDialect()->getNamespace() == dialectNamespace; + return op->getName().getDialectNamespace() == dialectNamespace; }; entries.push_back(Entry{filterFn, Entry::FilterType::ALLOW}); } -- GitLab From d1c37959686db3303f6d5ffaeee12be12facc640 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand <ulrich.weigand@de.ibm.com> Date: Tue, 19 Mar 2024 11:43:05 +0100 Subject: [PATCH 046/307] Revert "Fix overflow flag for i128 USUBO" This reverts commit d9c31ee9568277e4303715736b40925e41503596. --- .../Target/SystemZ/SystemZISelLowering.cpp | 34 ------------------- llvm/test/CodeGen/SystemZ/int-usub-12.ll | 22 ------------ llvm/test/CodeGen/SystemZ/int-usub-13.ll | 2 -- 3 files changed, 58 deletions(-) diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index 6158b044e5db..887c35a7ba24 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -4263,7 +4263,6 @@ SDValue SystemZTargetLowering::lowerXALUO(SDValue Op, if (N->getValueType(0) == MVT::i128) { unsigned BaseOp = 0; unsigned FlagOp = 0; - bool IsBorrow = false; switch (Op.getOpcode()) { default: llvm_unreachable("Unknown instruction!"); case ISD::UADDO: @@ -4273,7 +4272,6 @@ SDValue SystemZTargetLowering::lowerXALUO(SDValue Op, case ISD::USUBO: BaseOp = ISD::SUB; FlagOp = SystemZISD::VSCBI; - IsBorrow = true; break; } SDValue Result = DAG.getNode(BaseOp, DL, MVT::i128, LHS, RHS); @@ -4281,9 +4279,6 @@ SDValue SystemZTargetLowering::lowerXALUO(SDValue Op, Flag = DAG.getNode(ISD::AssertZext, DL, MVT::i128, Flag, DAG.getValueType(MVT::i1)); Flag = DAG.getZExtOrTrunc(Flag, DL, N->getValueType(1)); - if (IsBorrow) - Flag = DAG.getNode(ISD::XOR, DL, Flag.getValueType(), - Flag, DAG.getConstant(1, DL, Flag.getValueType())); return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, Flag); } @@ -4356,7 +4351,6 @@ SDValue SystemZTargetLowering::lowerUADDSUBO_CARRY(SDValue Op, if (VT == MVT::i128) { unsigned BaseOp = 0; unsigned FlagOp = 0; - bool IsBorrow = false; switch (Op.getOpcode()) { default: llvm_unreachable("Unknown instruction!"); case ISD::UADDO_CARRY: @@ -4366,21 +4360,14 @@ SDValue SystemZTargetLowering::lowerUADDSUBO_CARRY(SDValue Op, case ISD::USUBO_CARRY: BaseOp = SystemZISD::VSBI; FlagOp = SystemZISD::VSBCBI; - IsBorrow = true; break; } - if (IsBorrow) - Carry = DAG.getNode(ISD::XOR, DL, Carry.getValueType(), - Carry, DAG.getConstant(1, DL, Carry.getValueType())); Carry = DAG.getZExtOrTrunc(Carry, DL, MVT::i128); SDValue Result = DAG.getNode(BaseOp, DL, MVT::i128, LHS, RHS, Carry); SDValue Flag = DAG.getNode(FlagOp, DL, MVT::i128, LHS, RHS, Carry); Flag = DAG.getNode(ISD::AssertZext, DL, MVT::i128, Flag, DAG.getValueType(MVT::i1)); Flag = DAG.getZExtOrTrunc(Flag, DL, N->getValueType(1)); - if (IsBorrow) - Flag = DAG.getNode(ISD::XOR, DL, Flag.getValueType(), - Flag, DAG.getConstant(1, DL, Flag.getValueType())); return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, Flag); } @@ -6584,27 +6571,6 @@ SDValue SystemZTargetLowering::combineTruncateExtract( } } } - // Convert (zext (xor (trunc X), C)) into (xor (trunc X), C') if the size - // of the result is smaller than the size of X and all the truncated bits - // of X are already zero. - if (N0.getOpcode() == ISD::XOR && - N0.hasOneUse() && N0.getOperand(0).hasOneUse() && - N0.getOperand(0).getOpcode() == ISD::TRUNCATE && - N0.getOperand(1).getOpcode() == ISD::Constant) { - SDValue X = N0.getOperand(0).getOperand(0); - if (VT.isScalarInteger() && VT.getSizeInBits() < X.getValueSizeInBits()) { - KnownBits Known = DAG.computeKnownBits(X); - APInt TruncatedBits = APInt::getBitsSet(X.getValueSizeInBits(), - N0.getValueSizeInBits(), - VT.getSizeInBits()); - if (TruncatedBits.isSubsetOf(Known.Zero)) { - X = DAG.getNode(ISD::TRUNCATE, SDLoc(X), VT, X); - APInt Mask = N0.getConstantOperandAPInt(1).zext(VT.getSizeInBits()); - return DAG.getNode(ISD::XOR, SDLoc(N0), VT, - X, DAG.getConstant(Mask, SDLoc(N0), VT)); - } - } - } return SDValue(); } diff --git a/llvm/test/CodeGen/SystemZ/int-usub-12.ll b/llvm/test/CodeGen/SystemZ/int-usub-12.ll index 147fbfd920a9..c39a6da37048 100644 --- a/llvm/test/CodeGen/SystemZ/int-usub-12.ll +++ b/llvm/test/CodeGen/SystemZ/int-usub-12.ll @@ -11,7 +11,6 @@ define zeroext i1 @f1(i128 %a, i128 %b, ptr %res) { ; CHECK-NEXT: vscbiq %v2, %v1, %v0 ; CHECK-NEXT: vlgvg %r2, %v2, 1 ; CHECK-NEXT: vsq %v0, %v1, %v0 -; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: vst %v0, 0(%r4), 3 ; CHECK-NEXT: br %r14 %t = call {i128, i1} @llvm.usub.with.overflow.i128(i128 %a, i128 %b) @@ -28,7 +27,6 @@ define zeroext i1 @f2(i128 %a, i128 %b) { ; CHECK-NEXT: vl %v1, 0(%r2), 3 ; CHECK-NEXT: vscbiq %v0, %v1, %v0 ; CHECK-NEXT: vlgvg %r2, %v0, 1 -; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: br %r14 %t = call {i128, i1} @llvm.usub.with.overflow.i128(i128 %a, i128 %b) %obit = extractvalue {i128, i1} %t, 1 @@ -48,25 +46,5 @@ define i128 @f3(i128 %a, i128 %b) { ret i128 %val } -define i128 @f4(i128 %a, i128 %b) { -; CHECK-LABEL: f4: -; CHECK: # %bb.0: -; CHECK-NEXT: vl %v0, 0(%r4), 3 -; CHECK-NEXT: vl %v1, 0(%r3), 3 -; CHECK-NEXT: vscbiq %v2, %v1, %v0 -; CHECK-NEXT: vlgvf %r0, %v2, 3 -; CHECK-NEXT: vgbm %v2, 0 -; CHECK-NEXT: xilf %r0, 1 -; CHECK-NEXT: jl .LBB3_2 -; CHECK-NEXT: # %bb.1: -; CHECK-NEXT: vsq %v2, %v1, %v0 -; CHECK-NEXT: .LBB3_2: -; CHECK-NEXT: vst %v2, 0(%r2), 3 -; CHECK-NEXT: br %r14 - %val = call i128 @llvm.usub.sat.i128(i128 %a, i128 %b) - ret i128 %val -} - declare {i128, i1} @llvm.usub.with.overflow.i128(i128, i128) nounwind readnone -declare i128 @llvm.usub.sat.i128(i128, i128) nounwind readnone diff --git a/llvm/test/CodeGen/SystemZ/int-usub-13.ll b/llvm/test/CodeGen/SystemZ/int-usub-13.ll index 794af3b73fbe..637e1a81de99 100644 --- a/llvm/test/CodeGen/SystemZ/int-usub-13.ll +++ b/llvm/test/CodeGen/SystemZ/int-usub-13.ll @@ -15,7 +15,6 @@ define zeroext i1 @f1(i256 %a, i256 %b, ptr %res) { ; CHECK-NEXT: vlgvg %r2, %v5, 1 ; CHECK-NEXT: vsbiq %v0, %v1, %v0, %v4 ; CHECK-NEXT: vsq %v1, %v3, %v2 -; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: vst %v1, 16(%r4), 3 ; CHECK-NEXT: vst %v0, 0(%r4), 3 ; CHECK-NEXT: br %r14 @@ -36,7 +35,6 @@ define zeroext i1 @f2(i256 %a, i256 %b) { ; CHECK-NEXT: vscbiq %v2, %v3, %v2 ; CHECK-NEXT: vsbcbiq %v0, %v1, %v0, %v2 ; CHECK-NEXT: vlgvg %r2, %v0, 1 -; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: br %r14 %t = call {i256, i1} @llvm.usub.with.overflow.i256(i256 %a, i256 %b) %obit = extractvalue {i256, i1} %t, 1 -- GitLab From d0829fbdeda0a2faa8cf684e1396e579691bdfa2 Mon Sep 17 00:00:00 2001 From: jeanPerier <jperier@nvidia.com> Date: Tue, 19 Mar 2024 11:45:31 +0100 Subject: [PATCH 047/307] [flang] Enable polymorphic lowering by default (#83285) Polymorphic entity lowering status is good. The main remaining TODO is to allow lowering of vector subscripted polymorphic entity, but this does not deserve blocking all application using polymorphism. Remove experimental option and enable lowering of polymorphic entity by default. --- clang/include/clang/Driver/Options.td | 5 ----- clang/lib/Driver/ToolChains/Flang.cpp | 1 - flang/include/flang/Lower/LoweringOptions.def | 3 --- flang/lib/Frontend/CompilerInvocation.cpp | 5 ----- flang/lib/Lower/CallInterface.cpp | 6 ------ flang/lib/Lower/ConvertType.cpp | 4 ---- flang/test/Driver/driver-help-hidden.f90 | 2 -- .../Driver/flang-experimental-polymorphism-flag.f90 | 10 ---------- flang/test/Driver/frontend-forwarding.f90 | 2 -- flang/test/Fir/dispatch.f90 | 4 ++-- flang/test/HLFIR/assumed-type-actual-args.f90 | 2 +- flang/test/HLFIR/boxchar_emboxing.f90 | 2 +- flang/test/HLFIR/call_with_poly_dummy.f90 | 2 +- .../Lower/HLFIR/actual_target_for_dummy_pointer.f90 | 2 +- flang/test/Lower/HLFIR/allocatable-return.f90 | 2 +- flang/test/Lower/HLFIR/array-ctor-derived.f90 | 2 +- .../HLFIR/call-sequence-associated-descriptors.f90 | 2 +- flang/test/Lower/HLFIR/calls-assumed-shape.f90 | 2 +- .../HLFIR/calls-constant-expr-arg-polymorphic.f90 | 2 +- flang/test/Lower/HLFIR/calls-optional.f90 | 2 +- flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f90 | 2 +- flang/test/Lower/HLFIR/convert-mbox-to-value.f90 | 2 +- flang/test/Lower/HLFIR/designators-component-ref.f90 | 2 +- .../Lower/HLFIR/designators-parameter-array-slice.f90 | 2 +- flang/test/Lower/HLFIR/elemental-array-ops.f90 | 2 +- flang/test/Lower/HLFIR/elemental-polymorphic-merge.f90 | 2 +- .../HLFIR/elemental-user-procedure-ref-polymorphic.f90 | 2 +- flang/test/Lower/HLFIR/function-return-as-expr.f90 | 2 +- flang/test/Lower/HLFIR/function-return-destroy.f90 | 2 +- .../Lower/HLFIR/ignore-rank-unlimited-polymorphic.f90 | 2 +- flang/test/Lower/HLFIR/ignore-type-assumed-shape.f90 | 2 +- .../Lower/HLFIR/intentout-allocatable-components.f90 | 2 +- .../Lower/HLFIR/internal-procedures-polymorphic.f90 | 2 +- flang/test/Lower/HLFIR/intrinsic-assumed-type.f90 | 2 +- flang/test/Lower/HLFIR/parent-component-ref.f90 | 2 +- flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90 | 2 +- flang/test/Lower/HLFIR/polymorphic-expressions.f90 | 2 +- flang/test/Lower/HLFIR/proc-pointer-comp-nopass.f90 | 2 +- flang/test/Lower/HLFIR/proc-pointer-comp-pass.f90 | 2 +- flang/test/Lower/HLFIR/select-type-selector.f90 | 2 +- flang/test/Lower/HLFIR/transpose.f90 | 2 +- flang/test/Lower/HLFIR/type-bound-call-mismatch.f90 | 2 +- flang/test/Lower/HLFIR/vector-subscript-as-value.f90 | 2 +- flang/test/Lower/Intrinsics/extends_type_of.f90 | 2 +- flang/test/Lower/Intrinsics/same_type_as.f90 | 2 +- flang/test/Lower/Intrinsics/sizeof.f90 | 2 +- flang/test/Lower/Intrinsics/spread.f90 | 2 +- flang/test/Lower/Intrinsics/storage_size.f90 | 2 +- flang/test/Lower/allocatable-polymorphic.f90 | 4 ++-- flang/test/Lower/allocatable-return.f90 | 2 +- flang/test/Lower/assumed-type.f90 | 2 +- flang/test/Lower/default-initialization.f90 | 2 +- flang/test/Lower/derived-type-finalization.f90 | 2 +- flang/test/Lower/dispatch-table.f90 | 2 +- flang/test/Lower/dispatch.f90 | 2 +- flang/test/Lower/intentout-deallocate.f90 | 4 ++-- flang/test/Lower/io-derived-type-2.f90 | 2 +- flang/test/Lower/io-derived-type.f90 | 2 +- flang/test/Lower/nullify-polymorphic.f90 | 2 +- flang/test/Lower/pass-null-for-class-arg.f90 | 4 ++-- flang/test/Lower/pointer-association-polymorphic.f90 | 2 +- flang/test/Lower/pointer-disassociate.f90 | 2 +- flang/test/Lower/polymorphic-temp.f90 | 2 +- flang/test/Lower/polymorphic-types.f90 | 2 +- flang/test/Lower/polymorphic.f90 | 2 +- flang/test/Lower/select-type-2.f90 | 2 +- flang/test/Lower/select-type.f90 | 4 ++-- flang/tools/bbc/bbc.cpp | 6 ------ 68 files changed, 63 insertions(+), 107 deletions(-) delete mode 100644 flang/test/Driver/flang-experimental-polymorphism-flag.f90 diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 4b1fcf1db1ad..29c226f4bd8d 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6441,11 +6441,6 @@ def flang_deprecated_no_hlfir : Flag<["-"], "flang-deprecated-no-hlfir">, Flags<[HelpHidden]>, Visibility<[FlangOption, FC1Option]>, HelpText<"Do not use HLFIR lowering (deprecated)">; -def flang_experimental_polymorphism : Flag<["-"], "flang-experimental-polymorphism">, - Flags<[HelpHidden]>, Visibility<[FlangOption, FC1Option]>, - HelpText<"Enable Fortran 2003 polymorphism (experimental)">; - - //===----------------------------------------------------------------------===// // FLangOption + CoreOption + NoXarchOption //===----------------------------------------------------------------------===// diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 6168b42dc782..70daa699e3a9 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -148,7 +148,6 @@ void Flang::addCodegenOptions(const ArgList &Args, Args.addAllArgs(CmdArgs, {options::OPT_flang_experimental_hlfir, options::OPT_flang_deprecated_no_hlfir, - options::OPT_flang_experimental_polymorphism, options::OPT_fno_ppc_native_vec_elem_order, options::OPT_fppc_native_vec_elem_order}); } diff --git a/flang/include/flang/Lower/LoweringOptions.def b/flang/include/flang/Lower/LoweringOptions.def index 9de69ac5c80f..be080a4d29d7 100644 --- a/flang/include/flang/Lower/LoweringOptions.def +++ b/flang/include/flang/Lower/LoweringOptions.def @@ -24,9 +24,6 @@ LOWERINGOPT(Name, Bits, Default) /// If true, lower transpose without a runtime call. ENUM_LOWERINGOPT(OptimizeTranspose, unsigned, 1, 1) -/// If true, enable polymorphic type lowering feature. On by default. -ENUM_LOWERINGOPT(PolymorphicTypeImpl, unsigned, 1, 1) - /// If true, lower to High level FIR before lowering to FIR. On by default. ENUM_LOWERINGOPT(LowerToHighLevelFIR, unsigned, 1, 1) diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 2e3fa1f6e660..c830c7af2462 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -1191,11 +1191,6 @@ bool CompilerInvocation::createFromArgs( invoc.loweringOpts.setLowerToHighLevelFIR(false); } - if (args.hasArg( - clang::driver::options::OPT_flang_experimental_polymorphism)) { - invoc.loweringOpts.setPolymorphicTypeImpl(true); - } - // -fno-ppc-native-vector-element-order if (args.hasArg(clang::driver::options::OPT_fno_ppc_native_vec_elem_order)) { invoc.loweringOpts.setNoPPCNativeVecElemOrder(true); diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp index 2f95d53c383b..c65becc49745 100644 --- a/flang/lib/Lower/CallInterface.cpp +++ b/flang/lib/Lower/CallInterface.cpp @@ -1050,12 +1050,6 @@ private: Fortran::common::TypeCategory cat = dynamicType.category(); // DERIVED if (cat == Fortran::common::TypeCategory::Derived) { - // TODO is kept under experimental flag until feature is complete. - if (dynamicType.IsPolymorphic() && - !getConverter().getLoweringOptions().getPolymorphicTypeImpl()) - TODO(interface.converter.getCurrentLocation(), - "support for polymorphic types"); - if (dynamicType.IsUnlimitedPolymorphic()) return mlir::NoneType::get(&mlirContext); return getConverter().genType(dynamicType.GetDerivedTypeSpec()); diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp index 21564e8b81d7..e6557d7f0b76 100644 --- a/flang/lib/Lower/ConvertType.cpp +++ b/flang/lib/Lower/ConvertType.cpp @@ -263,10 +263,6 @@ struct TypeBuilderImpl { llvm::SmallVector<Fortran::lower::LenParameterTy> params; translateLenParameters(params, tySpec->category(), ultimate); ty = genFIRType(context, tySpec->category(), kind, params); - } else if (type->IsPolymorphic() && - !converter.getLoweringOptions().getPolymorphicTypeImpl()) { - // TODO is kept under experimental flag until feature is complete. - TODO(loc, "support for polymorphic types"); } else if (type->IsUnlimitedPolymorphic()) { ty = mlir::NoneType::get(context); } else if (const Fortran::semantics::DerivedTypeSpec *tySpec = diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 index 44dbac44772b..bf3660d57cbb 100644 --- a/flang/test/Driver/driver-help-hidden.f90 +++ b/flang/test/Driver/driver-help-hidden.f90 @@ -52,8 +52,6 @@ ! CHECK-NEXT: Do not use HLFIR lowering (deprecated) ! CHECK-NEXT: -flang-experimental-hlfir ! CHECK-NEXT: Use HLFIR lowering (experimental) -! CHECK-NEXT: -flang-experimental-polymorphism -! CHECK-NEXT: Enable Fortran 2003 polymorphism (experimental) ! CHECK-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics ! CHECK-NEXT: -flogical-abbreviations Enable logical abbreviations ! CHECK-NEXT: -flto=auto Enable LTO in 'full' mode diff --git a/flang/test/Driver/flang-experimental-polymorphism-flag.f90 b/flang/test/Driver/flang-experimental-polymorphism-flag.f90 deleted file mode 100644 index 095c1cc929e6..000000000000 --- a/flang/test/Driver/flang-experimental-polymorphism-flag.f90 +++ /dev/null @@ -1,10 +0,0 @@ -! Test -flang-experimental-hlfir flag -! RUN: %flang_fc1 -flang-experimental-polymorphism -emit-fir -o - %s | FileCheck %s -! RUN: %flang_fc1 -emit-fir -o - %s 2>&1 | FileCheck %s --check-prefix NO-POLYMORPHISM - -! CHECK: func.func @_QPtest(%{{.*}}: !fir.class<none> {fir.bindc_name = "poly"}) -subroutine test(poly) - class(*) :: poly -end subroutine test - -! NO-POLYMORPHISM: func.func @_QPtest diff --git a/flang/test/Driver/frontend-forwarding.f90 b/flang/test/Driver/frontend-forwarding.f90 index 8e9c9b78c3c1..eac9773ce25c 100644 --- a/flang/test/Driver/frontend-forwarding.f90 +++ b/flang/test/Driver/frontend-forwarding.f90 @@ -17,7 +17,6 @@ ! RUN: -fomit-frame-pointer \ ! RUN: -fpass-plugin=Bye%pluginext \ ! RUN: -fversion-loops-for-stride \ -! RUN: -flang-experimental-polymorphism \ ! RUN: -flang-experimental-hlfir \ ! RUN: -flang-deprecated-no-hlfir \ ! RUN: -fno-ppc-native-vector-element-order \ @@ -49,7 +48,6 @@ ! CHECK: "-fconvert=little-endian" ! CHECK: "-fpass-plugin=Bye ! CHECK: "-fversion-loops-for-stride" -! CHECK: "-flang-experimental-polymorphism" ! CHECK: "-flang-experimental-hlfir" ! CHECK: "-flang-deprecated-no-hlfir" ! CHECK: "-fno-ppc-native-vector-element-order" diff --git a/flang/test/Fir/dispatch.f90 b/flang/test/Fir/dispatch.f90 index 1dc71038813d..1479d611b986 100644 --- a/flang/test/Fir/dispatch.f90 +++ b/flang/test/Fir/dispatch.f90 @@ -1,5 +1,5 @@ -! RUN: bbc -polymorphic-type -emit-hlfir %s -o - | fir-opt --fir-polymorphic-op | FileCheck %s -! RUN: bbc -polymorphic-type -emit-hlfir %s -o - | FileCheck %s --check-prefix=BT +! RUN: bbc -emit-hlfir %s -o - | fir-opt --fir-polymorphic-op | FileCheck %s +! RUN: bbc -emit-hlfir %s -o - | FileCheck %s --check-prefix=BT ! Tests codegen of fir.dispatch operation. This test is intentionally run from ! Fortran through bbc and tco so we have all the binding tables lowered to FIR diff --git a/flang/test/HLFIR/assumed-type-actual-args.f90 b/flang/test/HLFIR/assumed-type-actual-args.f90 index 58c282b6ab18..dbdfc1785ce9 100644 --- a/flang/test/HLFIR/assumed-type-actual-args.f90 +++ b/flang/test/HLFIR/assumed-type-actual-args.f90 @@ -1,6 +1,6 @@ ! Test lowering to FIR of actual arguments that are assumed type ! variables (Fortran 2018 7.3.2.2 point 3). -! RUN: bbc --polymorphic-type -emit-hlfir -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s subroutine test1(x) interface diff --git a/flang/test/HLFIR/boxchar_emboxing.f90 b/flang/test/HLFIR/boxchar_emboxing.f90 index 3e9ccde6baba..fbc41bbea72d 100644 --- a/flang/test/HLFIR/boxchar_emboxing.f90 +++ b/flang/test/HLFIR/boxchar_emboxing.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-hlfir %s -o - | FileCheck %s +! RUN: bbc -emit-hlfir %s -o - | FileCheck %s ! CHECK-LABEL: func.func @_QPtest1( ! CHECK-SAME: %[[VAL_0:.*]]: !fir.class<none> {fir.bindc_name = "x"}) { diff --git a/flang/test/HLFIR/call_with_poly_dummy.f90 b/flang/test/HLFIR/call_with_poly_dummy.f90 index af6876e26603..00a795c5b1fb 100644 --- a/flang/test/HLFIR/call_with_poly_dummy.f90 +++ b/flang/test/HLFIR/call_with_poly_dummy.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-hlfir %s -o - | FileCheck %s +! RUN: bbc -emit-hlfir %s -o - | FileCheck %s ! Test passing arguments to subprograms with polymorphic dummy arguments. diff --git a/flang/test/Lower/HLFIR/actual_target_for_dummy_pointer.f90 b/flang/test/Lower/HLFIR/actual_target_for_dummy_pointer.f90 index 76ed237fb672..129aa49b811d 100644 --- a/flang/test/Lower/HLFIR/actual_target_for_dummy_pointer.f90 +++ b/flang/test/Lower/HLFIR/actual_target_for_dummy_pointer.f90 @@ -1,5 +1,5 @@ ! Test actual TARGET argument association to dummy POINTER: -! RUN: bbc -emit-hlfir --polymorphic-type -o - -I nowhere %s 2>&1 | FileCheck %s +! RUN: bbc -emit-hlfir -o - -I nowhere %s 2>&1 | FileCheck %s module target_to_pointer_types type t1 diff --git a/flang/test/Lower/HLFIR/allocatable-return.f90 b/flang/test/Lower/HLFIR/allocatable-return.f90 index d652b2f9f767..e1bac34ef1a0 100644 --- a/flang/test/Lower/HLFIR/allocatable-return.f90 +++ b/flang/test/Lower/HLFIR/allocatable-return.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -emit-hlfir --polymorphic-type -I nowhere %s -o - | FileCheck %s +! RUN: bbc -emit-hlfir -I nowhere %s -o - | FileCheck %s ! Test allocatable return. ! Allocatable arrays must have default runtime lbounds after the return. diff --git a/flang/test/Lower/HLFIR/array-ctor-derived.f90 b/flang/test/Lower/HLFIR/array-ctor-derived.f90 index 21a3eb78a199..111225462a4b 100644 --- a/flang/test/Lower/HLFIR/array-ctor-derived.f90 +++ b/flang/test/Lower/HLFIR/array-ctor-derived.f90 @@ -1,5 +1,5 @@ ! Test lowering of derived type array constructors to HLFIR. -! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s module types type simple diff --git a/flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90 b/flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90 index 9cbb9279a868..7a2ea5cc14b6 100644 --- a/flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90 +++ b/flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90 @@ -1,7 +1,7 @@ ! Test lowering of sequence associated arguments (F'2023 15.5.2.12) passed ! by descriptor. The descriptor on the caller side is prepared according to ! the dummy argument shape. -! RUN: bbc -emit-hlfir -polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s module bindc_seq_assoc interface diff --git a/flang/test/Lower/HLFIR/calls-assumed-shape.f90 b/flang/test/Lower/HLFIR/calls-assumed-shape.f90 index 92b87a6987a5..a2094f1f1f0e 100644 --- a/flang/test/Lower/HLFIR/calls-assumed-shape.f90 +++ b/flang/test/Lower/HLFIR/calls-assumed-shape.f90 @@ -1,6 +1,6 @@ ! Test lowering of calls involving assumed shape arrays or arrays with ! VALUE attribute. -! RUN: bbc -emit-hlfir -polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s subroutine test_assumed_to_assumed(x) interface diff --git a/flang/test/Lower/HLFIR/calls-constant-expr-arg-polymorphic.f90 b/flang/test/Lower/HLFIR/calls-constant-expr-arg-polymorphic.f90 index a862033c0fef..4ee70e55079d 100644 --- a/flang/test/Lower/HLFIR/calls-constant-expr-arg-polymorphic.f90 +++ b/flang/test/Lower/HLFIR/calls-constant-expr-arg-polymorphic.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s ! Test when constant argument are copied in memory ! and passed to polymorphic arguments. diff --git a/flang/test/Lower/HLFIR/calls-optional.f90 b/flang/test/Lower/HLFIR/calls-optional.f90 index cf684981f800..df9519a24fb7 100644 --- a/flang/test/Lower/HLFIR/calls-optional.f90 +++ b/flang/test/Lower/HLFIR/calls-optional.f90 @@ -2,7 +2,7 @@ ! that is syntactically present, but may be absent at runtime (is ! an optional or a pointer/allocatable). ! -! RUN: bbc -emit-hlfir -polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s subroutine optional_copy_in_out(x) interface diff --git a/flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f90 b/flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f90 index ffd21e01ef98..b14f1bb1f443 100644 --- a/flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f90 +++ b/flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f90 @@ -1,6 +1,6 @@ ! Test passing rank 2 CLASS(*) deferred shape to assumed size assumed type ! This requires copy-in/copy-out logic. -! RUN: bbc -emit-hlfir -polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s subroutine pass_poly_to_assumed_type_assumed_size(x) class(*), target :: x(:,:) diff --git a/flang/test/Lower/HLFIR/convert-mbox-to-value.f90 b/flang/test/Lower/HLFIR/convert-mbox-to-value.f90 index b943cd3225a5..b9d55d3fde4f 100644 --- a/flang/test/Lower/HLFIR/convert-mbox-to-value.f90 +++ b/flang/test/Lower/HLFIR/convert-mbox-to-value.f90 @@ -1,5 +1,5 @@ ! Test conversion of MutableBoxValue to value. -! RUN: bbc -emit-hlfir -polymorphic-type -I nowhere %s -o - | FileCheck %s +! RUN: bbc -emit-hlfir -I nowhere %s -o - | FileCheck %s subroutine test_int_allocatable(a) integer, allocatable :: a diff --git a/flang/test/Lower/HLFIR/designators-component-ref.f90 b/flang/test/Lower/HLFIR/designators-component-ref.f90 index 3e9fa037040d..392eda66fd03 100644 --- a/flang/test/Lower/HLFIR/designators-component-ref.f90 +++ b/flang/test/Lower/HLFIR/designators-component-ref.f90 @@ -1,5 +1,5 @@ ! Test lowering of component reference to HLFIR -! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s module comp_ref type t1 integer :: scalar_i diff --git a/flang/test/Lower/HLFIR/designators-parameter-array-slice.f90 b/flang/test/Lower/HLFIR/designators-parameter-array-slice.f90 index 3bf199234533..42e130ee3f49 100644 --- a/flang/test/Lower/HLFIR/designators-parameter-array-slice.f90 +++ b/flang/test/Lower/HLFIR/designators-parameter-array-slice.f90 @@ -1,5 +1,5 @@ ! Test non-contiguous slice of parameter array. -! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s subroutine test2(i) integer, parameter :: a(*,*) = reshape( [ 1,2,3,4 ], [ 2,2 ]) integer :: x(2) diff --git a/flang/test/Lower/HLFIR/elemental-array-ops.f90 b/flang/test/Lower/HLFIR/elemental-array-ops.f90 index 6984e5ef74c6..9778adeb6179 100644 --- a/flang/test/Lower/HLFIR/elemental-array-ops.f90 +++ b/flang/test/Lower/HLFIR/elemental-array-ops.f90 @@ -1,5 +1,5 @@ ! Test lowering of elemental intrinsic operations with array arguments to HLFIR -! RUN: bbc -emit-hlfir --polymorphic-type -I nowhere -o - %s 2>&1 | FileCheck %s +! RUN: bbc -emit-hlfir -I nowhere -o - %s 2>&1 | FileCheck %s subroutine binary(x, y) integer :: x(100), y(100) diff --git a/flang/test/Lower/HLFIR/elemental-polymorphic-merge.f90 b/flang/test/Lower/HLFIR/elemental-polymorphic-merge.f90 index c2f97b6fccfe..eb93099b3890 100644 --- a/flang/test/Lower/HLFIR/elemental-polymorphic-merge.f90 +++ b/flang/test/Lower/HLFIR/elemental-polymorphic-merge.f90 @@ -1,5 +1,5 @@ ! Test that the produced hlfir.elemental had proper result type and the mold. -! RUN: bbc --emit-hlfir --polymorphic-type -I nowhere -o - %s | FileCheck %s +! RUN: bbc --emit-hlfir -I nowhere -o - %s | FileCheck %s subroutine test_polymorphic_merge(x, y, r, m) type t diff --git a/flang/test/Lower/HLFIR/elemental-user-procedure-ref-polymorphic.f90 b/flang/test/Lower/HLFIR/elemental-user-procedure-ref-polymorphic.f90 index 1cd5c5133bd9..84bb7a55377b 100644 --- a/flang/test/Lower/HLFIR/elemental-user-procedure-ref-polymorphic.f90 +++ b/flang/test/Lower/HLFIR/elemental-user-procedure-ref-polymorphic.f90 @@ -1,6 +1,6 @@ ! Test lowering of user defined elemental procedure reference to HLFIR ! With polymorphic arguments. -! RUN: bbc -emit-hlfir -I nw -polymorphic-type -o - %s 2>&1 | FileCheck %s +! RUN: bbc -emit-hlfir -I nw -o - %s 2>&1 | FileCheck %s module def_some_types type :: t integer :: i diff --git a/flang/test/Lower/HLFIR/function-return-as-expr.f90 b/flang/test/Lower/HLFIR/function-return-as-expr.f90 index ae4f679a0fe6..95a0c090ef04 100644 --- a/flang/test/Lower/HLFIR/function-return-as-expr.f90 +++ b/flang/test/Lower/HLFIR/function-return-as-expr.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -emit-hlfir --polymorphic-type -o - %s -I nowhere 2>&1 | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s -I nowhere 2>&1 | FileCheck %s module types type t1 diff --git a/flang/test/Lower/HLFIR/function-return-destroy.f90 b/flang/test/Lower/HLFIR/function-return-destroy.f90 index 4663dc57e045..5bd014981c12 100644 --- a/flang/test/Lower/HLFIR/function-return-destroy.f90 +++ b/flang/test/Lower/HLFIR/function-return-destroy.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -emit-hlfir -polymorphic-type %s -o - -I nowhere | FileCheck %s +! RUN: bbc -emit-hlfir %s -o - -I nowhere | FileCheck %s module types type t1 diff --git a/flang/test/Lower/HLFIR/ignore-rank-unlimited-polymorphic.f90 b/flang/test/Lower/HLFIR/ignore-rank-unlimited-polymorphic.f90 index 952e8f565eb9..43986c8198b9 100644 --- a/flang/test/Lower/HLFIR/ignore-rank-unlimited-polymorphic.f90 +++ b/flang/test/Lower/HLFIR/ignore-rank-unlimited-polymorphic.f90 @@ -1,6 +1,6 @@ ! Test passing mismatching rank arguments to unlimited polymorphic ! dummy with IGNORE_TKR(R). -! RUN: bbc -emit-hlfir -polymorphic-type -o - -I nowhere %s 2>&1 | FileCheck %s +! RUN: bbc -emit-hlfir -o - -I nowhere %s 2>&1 | FileCheck %s module m interface diff --git a/flang/test/Lower/HLFIR/ignore-type-assumed-shape.f90 b/flang/test/Lower/HLFIR/ignore-type-assumed-shape.f90 index 3ad74ced61a3..27747ff2ad94 100644 --- a/flang/test/Lower/HLFIR/ignore-type-assumed-shape.f90 +++ b/flang/test/Lower/HLFIR/ignore-type-assumed-shape.f90 @@ -2,7 +2,7 @@ ! dummy has IGNORE_TKR(t). The descriptor should be prepared ! according to the actual argument type, but its bounds and ! attributes should still be set as expected for the dummy. -! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s module tkr_ifaces interface diff --git a/flang/test/Lower/HLFIR/intentout-allocatable-components.f90 b/flang/test/Lower/HLFIR/intentout-allocatable-components.f90 index 932fafd322a3..797e4c89ae23 100644 --- a/flang/test/Lower/HLFIR/intentout-allocatable-components.f90 +++ b/flang/test/Lower/HLFIR/intentout-allocatable-components.f90 @@ -1,6 +1,6 @@ ! Test that allocatable components of non pointer/non allocatable INTENT(OUT) ! dummy arguments are deallocated. -! RUN: bbc -emit-hlfir -polymorphic-type %s -o - -I nowhere | FileCheck %s +! RUN: bbc -emit-hlfir %s -o - -I nowhere | FileCheck %s subroutine test_intentout_component_deallocate(a) type :: t diff --git a/flang/test/Lower/HLFIR/internal-procedures-polymorphic.f90 b/flang/test/Lower/HLFIR/internal-procedures-polymorphic.f90 index 8645488290d7..5763d84cfd60 100644 --- a/flang/test/Lower/HLFIR/internal-procedures-polymorphic.f90 +++ b/flang/test/Lower/HLFIR/internal-procedures-polymorphic.f90 @@ -1,6 +1,6 @@ ! Test lowering of internal procedure capturing OPTIONAL polymorphic ! objects. -! RUN: bbc -emit-hlfir --polymorphic-type -o - %s -I nw | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s -I nw | FileCheck %s module captured_optional_polymorphic diff --git a/flang/test/Lower/HLFIR/intrinsic-assumed-type.f90 b/flang/test/Lower/HLFIR/intrinsic-assumed-type.f90 index d0381344c893..e82bc342ff88 100644 --- a/flang/test/Lower/HLFIR/intrinsic-assumed-type.f90 +++ b/flang/test/Lower/HLFIR/intrinsic-assumed-type.f90 @@ -2,7 +2,7 @@ ! arguments. These are a bit special because semantics do not represent ! assumed types actual arguments with an evaluate::Expr like for usual ! arguments. -! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s subroutine assumed_type_to_intrinsic(a) type(*) :: a(:) diff --git a/flang/test/Lower/HLFIR/parent-component-ref.f90 b/flang/test/Lower/HLFIR/parent-component-ref.f90 index b08d8f450e6d..7d04ef3b40a6 100644 --- a/flang/test/Lower/HLFIR/parent-component-ref.f90 +++ b/flang/test/Lower/HLFIR/parent-component-ref.f90 @@ -1,5 +1,5 @@ ! Test lowering of parent component references to HLFIR. -! RUN: bbc -emit-hlfir -polymorphic-type -o - %s -I nw | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s -I nw | FileCheck %s module pc_types type t diff --git a/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90 b/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90 index ec5be37f5515..f5ec7c35594b 100644 --- a/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90 +++ b/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90 @@ -1,6 +1,6 @@ ! Test passing polymorphic expression for non-polymorphic contiguous ! dummy argument: -! RUN: bbc -emit-hlfir --polymorphic-type -o - -I nowhere %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - -I nowhere %s | FileCheck %s module types type t diff --git a/flang/test/Lower/HLFIR/polymorphic-expressions.f90 b/flang/test/Lower/HLFIR/polymorphic-expressions.f90 index 37e602895db3..d6934e6ae6bd 100644 --- a/flang/test/Lower/HLFIR/polymorphic-expressions.f90 +++ b/flang/test/Lower/HLFIR/polymorphic-expressions.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -emit-hlfir --polymorphic-type -o - %s -I nowhere | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s -I nowhere | FileCheck %s module polymorphic_expressions_types type t diff --git a/flang/test/Lower/HLFIR/proc-pointer-comp-nopass.f90 b/flang/test/Lower/HLFIR/proc-pointer-comp-nopass.f90 index ebb310f581c1..6f41f678dd84 100644 --- a/flang/test/Lower/HLFIR/proc-pointer-comp-nopass.f90 +++ b/flang/test/Lower/HLFIR/proc-pointer-comp-nopass.f90 @@ -1,5 +1,5 @@ ! Test lowering of NOPASS procedure pointers components. -! RUN: bbc -emit-hlfir -polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s module proc_comp_defs interface diff --git a/flang/test/Lower/HLFIR/proc-pointer-comp-pass.f90 b/flang/test/Lower/HLFIR/proc-pointer-comp-pass.f90 index 25e4393f9dac..247008e3a93d 100644 --- a/flang/test/Lower/HLFIR/proc-pointer-comp-pass.f90 +++ b/flang/test/Lower/HLFIR/proc-pointer-comp-pass.f90 @@ -1,5 +1,5 @@ ! Test lowering of PASS procedure pointers components. -! RUN: bbc -emit-hlfir -polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s module m type t diff --git a/flang/test/Lower/HLFIR/select-type-selector.f90 b/flang/test/Lower/HLFIR/select-type-selector.f90 index a9536c9ccee6..256f003dcbf6 100644 --- a/flang/test/Lower/HLFIR/select-type-selector.f90 +++ b/flang/test/Lower/HLFIR/select-type-selector.f90 @@ -14,7 +14,7 @@ ! (16.9.109) applied to the corresponding dimension of selector. The upper bound of each dimension is one less ! than the sum of the lower bound and the extent. -! RUN: bbc -emit-hlfir -polymorphic-type -I nowhere -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -I nowhere -o - %s | FileCheck %s subroutine test() type t diff --git a/flang/test/Lower/HLFIR/transpose.f90 b/flang/test/Lower/HLFIR/transpose.f90 index e63e1ec1d689..e37e83c7a501 100644 --- a/flang/test/Lower/HLFIR/transpose.f90 +++ b/flang/test/Lower/HLFIR/transpose.f90 @@ -1,5 +1,5 @@ ! Test lowering of TRANSPOSE intrinsic to HLFIR -! RUN: bbc -emit-hlfir --polymorphic-type -o - %s 2>&1 | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s 2>&1 | FileCheck %s subroutine transpose1(m, res) integer :: m(1,2), res(2, 1) diff --git a/flang/test/Lower/HLFIR/type-bound-call-mismatch.f90 b/flang/test/Lower/HLFIR/type-bound-call-mismatch.f90 index 6794d11ece42..2e0c72ccfe04 100644 --- a/flang/test/Lower/HLFIR/type-bound-call-mismatch.f90 +++ b/flang/test/Lower/HLFIR/type-bound-call-mismatch.f90 @@ -1,6 +1,6 @@ ! Test interface that lowering handles small interface mismatch with ! type bound procedures. -! RUN: bbc -emit-hlfir --polymorphic-type %s -o - -I nw | FileCheck %s +! RUN: bbc -emit-hlfir %s -o - -I nw | FileCheck %s module dispatch_mismatch type t diff --git a/flang/test/Lower/HLFIR/vector-subscript-as-value.f90 b/flang/test/Lower/HLFIR/vector-subscript-as-value.f90 index d4026a37720f..ee8ded197c95 100644 --- a/flang/test/Lower/HLFIR/vector-subscript-as-value.f90 +++ b/flang/test/Lower/HLFIR/vector-subscript-as-value.f90 @@ -1,6 +1,6 @@ ! Test lowering of vector subscript designators outside of the ! assignment left-and side and input IO context. -! RUN: bbc -emit-hlfir -o - -I nw %s --polymorphic-type 2>&1 | FileCheck %s +! RUN: bbc -emit-hlfir -o - -I nw %s 2>&1 | FileCheck %s subroutine foo(x, y) integer :: x(100) diff --git a/flang/test/Lower/Intrinsics/extends_type_of.f90 b/flang/test/Lower/Intrinsics/extends_type_of.f90 index b36d4e8b7c0d..f99a63e30a55 100644 --- a/flang/test/Lower/Intrinsics/extends_type_of.f90 +++ b/flang/test/Lower/Intrinsics/extends_type_of.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -emit-fir -hlfir=false -polymorphic-type %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s module extends_type_of_mod diff --git a/flang/test/Lower/Intrinsics/same_type_as.f90 b/flang/test/Lower/Intrinsics/same_type_as.f90 index e1333024927d..e0fda563f08b 100644 --- a/flang/test/Lower/Intrinsics/same_type_as.f90 +++ b/flang/test/Lower/Intrinsics/same_type_as.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -emit-fir -hlfir=false -polymorphic-type %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s module same_type_as_mod diff --git a/flang/test/Lower/Intrinsics/sizeof.f90 b/flang/test/Lower/Intrinsics/sizeof.f90 index 959ca1692b51..e10cb79981a6 100644 --- a/flang/test/Lower/Intrinsics/sizeof.f90 +++ b/flang/test/Lower/Intrinsics/sizeof.f90 @@ -1,5 +1,5 @@ ! Test SIZEOF lowering for polymorphic entities. -! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir -o - %s | FileCheck %s integer(8) function test1(x) class(*) :: x diff --git a/flang/test/Lower/Intrinsics/spread.f90 b/flang/test/Lower/Intrinsics/spread.f90 index 4cd823d83745..d58725aba698 100644 --- a/flang/test/Lower/Intrinsics/spread.f90 +++ b/flang/test/Lower/Intrinsics/spread.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -emit-fir -hlfir=false -polymorphic-type %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s module spread_mod diff --git a/flang/test/Lower/Intrinsics/storage_size.f90 b/flang/test/Lower/Intrinsics/storage_size.f90 index 668322f45bd8..b0c9d51f9532 100644 --- a/flang/test/Lower/Intrinsics/storage_size.f90 +++ b/flang/test/Lower/Intrinsics/storage_size.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -emit-fir -hlfir=false -polymorphic-type %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s module storage_size_test type :: p1 diff --git a/flang/test/Lower/allocatable-polymorphic.f90 b/flang/test/Lower/allocatable-polymorphic.f90 index 6ba0b13b24b6..10d7d957a257 100644 --- a/flang/test/Lower/allocatable-polymorphic.f90 +++ b/flang/test/Lower/allocatable-polymorphic.f90 @@ -1,5 +1,5 @@ -! RUN: bbc --use-desc-for-alloc=false -polymorphic-type -emit-hlfir %s -o - | FileCheck %s -! RUN: bbc --use-desc-for-alloc=false -polymorphic-type -emit-hlfir %s -o - | tco | FileCheck %s --check-prefix=LLVM +! RUN: bbc --use-desc-for-alloc=false -emit-hlfir %s -o - | FileCheck %s +! RUN: bbc --use-desc-for-alloc=false -emit-hlfir %s -o - | tco | FileCheck %s --check-prefix=LLVM module poly type p1 diff --git a/flang/test/Lower/allocatable-return.f90 b/flang/test/Lower/allocatable-return.f90 index 92c5f8ad78d7..363d16237b9b 100644 --- a/flang/test/Lower/allocatable-return.f90 +++ b/flang/test/Lower/allocatable-return.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -emit-fir -hlfir=false --polymorphic-type -I nowhere %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false -I nowhere %s -o - | FileCheck %s ! Test allocatable return. ! Allocatable arrays must have default runtime lbounds after the return. diff --git a/flang/test/Lower/assumed-type.f90 b/flang/test/Lower/assumed-type.f90 index 99472a255adb..44ce41d75737 100644 --- a/flang/test/Lower/assumed-type.f90 +++ b/flang/test/Lower/assumed-type.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s module assumed_type_test diff --git a/flang/test/Lower/default-initialization.f90 b/flang/test/Lower/default-initialization.f90 index e692b9b08446..7a6133452b3a 100644 --- a/flang/test/Lower/default-initialization.f90 +++ b/flang/test/Lower/default-initialization.f90 @@ -1,5 +1,5 @@ ! Test default initialization of local and dummy variables (dynamic initialization) -! RUN: bbc -emit-fir -hlfir=false -polymorphic-type %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s module test_dinit type t diff --git a/flang/test/Lower/derived-type-finalization.f90 b/flang/test/Lower/derived-type-finalization.f90 index 5c4531884213..e7ade0d8145b 100644 --- a/flang/test/Lower/derived-type-finalization.f90 +++ b/flang/test/Lower/derived-type-finalization.f90 @@ -1,5 +1,5 @@ ! Test derived type finalization -! RUN: bbc --use-desc-for-alloc=false -polymorphic-type -emit-fir -hlfir=false %s -o - | FileCheck %s +! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s ! Missing tests: ! - finalization within BLOCK construct diff --git a/flang/test/Lower/dispatch-table.f90 b/flang/test/Lower/dispatch-table.f90 index 0df4981b3eaf..023dbcbedeaf 100644 --- a/flang/test/Lower/dispatch-table.f90 +++ b/flang/test/Lower/dispatch-table.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-fir %s -o - | FileCheck %s +! RUN: bbc -emit-fir %s -o - | FileCheck %s ! Tests the generation of fir.type_info operations. diff --git a/flang/test/Lower/dispatch.f90 b/flang/test/Lower/dispatch.f90 index 1aad4a4b8e46..60364076e633 100644 --- a/flang/test/Lower/dispatch.f90 +++ b/flang/test/Lower/dispatch.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-hlfir %s -o - | FileCheck %s +! RUN: bbc -emit-hlfir %s -o - | FileCheck %s ! Tests the different possible type involving polymorphic entities. diff --git a/flang/test/Lower/intentout-deallocate.f90 b/flang/test/Lower/intentout-deallocate.f90 index 30502fd5d722..8e7ccbcc9fdb 100644 --- a/flang/test/Lower/intentout-deallocate.f90 +++ b/flang/test/Lower/intentout-deallocate.f90 @@ -1,6 +1,6 @@ ! Test correct deallocation of intent(out) allocatables. -! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false -polymorphic-type %s -o - | FileCheck %s --check-prefixes=CHECK,FIR -! RUN: bbc -emit-hlfir -polymorphic-type %s -o - -I nw | FileCheck %s --check-prefixes=CHECK,HLFIR +! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes=CHECK,FIR +! RUN: bbc -emit-hlfir %s -o - -I nw | FileCheck %s --check-prefixes=CHECK,HLFIR module mod1 type, bind(c) :: t1 diff --git a/flang/test/Lower/io-derived-type-2.f90 b/flang/test/Lower/io-derived-type-2.f90 index c2f1ff185072..eeea2ae156f9 100644 --- a/flang/test/Lower/io-derived-type-2.f90 +++ b/flang/test/Lower/io-derived-type-2.f90 @@ -1,6 +1,6 @@ ! Check that InputDerivedType/OutputDeriverType APIs are used ! for io of derived types. -! RUN: bbc -polymorphic-type -emit-fir -o - %s | FileCheck %s +! RUN: bbc -emit-fir -o - %s | FileCheck %s module p type :: person diff --git a/flang/test/Lower/io-derived-type.f90 b/flang/test/Lower/io-derived-type.f90 index 84f57f46289b..08b1207f55ad 100644 --- a/flang/test/Lower/io-derived-type.f90 +++ b/flang/test/Lower/io-derived-type.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false -o - %s | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false -o - %s | FileCheck %s module m type t diff --git a/flang/test/Lower/nullify-polymorphic.f90 b/flang/test/Lower/nullify-polymorphic.f90 index ee271b815bdd..5cb966810f1b 100644 --- a/flang/test/Lower/nullify-polymorphic.f90 +++ b/flang/test/Lower/nullify-polymorphic.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-hlfir %s -o - | FileCheck %s +! RUN: bbc -emit-hlfir %s -o - | FileCheck %s module poly type p1 diff --git a/flang/test/Lower/pass-null-for-class-arg.f90 b/flang/test/Lower/pass-null-for-class-arg.f90 index d3d657f29a36..f60cad30b1bf 100644 --- a/flang/test/Lower/pass-null-for-class-arg.f90 +++ b/flang/test/Lower/pass-null-for-class-arg.f90 @@ -1,5 +1,5 @@ -! RUN: bbc -emit-fir -polymorphic-type %s -o - | FileCheck %s --check-prefix=FIR -! RUN: bbc -emit-fir -polymorphic-type -hlfir %s -o - | FileCheck %s --check-prefix=HLFIR +! RUN: bbc -emit-fir %s -o - | FileCheck %s --check-prefix=FIR +! RUN: bbc -emit-fir -hlfir %s -o - | FileCheck %s --check-prefix=HLFIR subroutine test interface diff --git a/flang/test/Lower/pointer-association-polymorphic.f90 b/flang/test/Lower/pointer-association-polymorphic.f90 index bde96429c0ee..6c56db892d1b 100644 --- a/flang/test/Lower/pointer-association-polymorphic.f90 +++ b/flang/test/Lower/pointer-association-polymorphic.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s module poly type p1 diff --git a/flang/test/Lower/pointer-disassociate.f90 b/flang/test/Lower/pointer-disassociate.f90 index 8d7190583165..e341bca5cd89 100644 --- a/flang/test/Lower/pointer-disassociate.f90 +++ b/flang/test/Lower/pointer-disassociate.f90 @@ -1,5 +1,5 @@ ! Test lowering of pointer disassociation -! RUN: bbc -emit-fir -hlfir=false --polymorphic-type %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s ! ----------------------------------------------------------------------------- diff --git a/flang/test/Lower/polymorphic-temp.f90 b/flang/test/Lower/polymorphic-temp.f90 index 46cf14dcf93f..8633620e8430 100644 --- a/flang/test/Lower/polymorphic-temp.f90 +++ b/flang/test/Lower/polymorphic-temp.f90 @@ -1,5 +1,5 @@ ! Test creation of temporary from polymorphic enities -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s module poly_tmp type p1 diff --git a/flang/test/Lower/polymorphic-types.f90 b/flang/test/Lower/polymorphic-types.f90 index 0288fea6eb38..a06e0a29b6ae 100644 --- a/flang/test/Lower/polymorphic-types.f90 +++ b/flang/test/Lower/polymorphic-types.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s ! Tests the different possible type involving polymorphic entities. diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90 index 15d8a86e4ef4..e031b4805dc5 100644 --- a/flang/test/Lower/polymorphic.f90 +++ b/flang/test/Lower/polymorphic.f90 @@ -1,4 +1,4 @@ -! RUN: bbc --use-desc-for-alloc=false -polymorphic-type -emit-fir -hlfir=false %s -o - | FileCheck %s +! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s ! Tests various aspect of the lowering of polymorphic entities. diff --git a/flang/test/Lower/select-type-2.f90 b/flang/test/Lower/select-type-2.f90 index 3769132b01c1..7b4cf96069e5 100644 --- a/flang/test/Lower/select-type-2.f90 +++ b/flang/test/Lower/select-type-2.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false %s -o - | fir-opt --fir-polymorphic-op | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | fir-opt --fir-polymorphic-op | FileCheck %s module select_type_2 type p1 integer :: a diff --git a/flang/test/Lower/select-type.f90 b/flang/test/Lower/select-type.f90 index ef91fb913a1c..3243a813e9d5 100644 --- a/flang/test/Lower/select-type.f90 +++ b/flang/test/Lower/select-type.f90 @@ -1,5 +1,5 @@ -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false %s -o - | FileCheck %s -! RUN: bbc -polymorphic-type -emit-fir -hlfir=false %s -o - | fir-opt --fir-polymorphic-op | FileCheck --check-prefix=CFG %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | fir-opt --fir-polymorphic-op | FileCheck --check-prefix=CFG %s module select_type_lower_test type p1 integer :: a diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp index 73d740ff4394..a0870d3649c2 100644 --- a/flang/tools/bbc/bbc.cpp +++ b/flang/tools/bbc/bbc.cpp @@ -191,11 +191,6 @@ static llvm::cl::opt<bool> enableOpenACC("fopenacc", llvm::cl::desc("enable openacc"), llvm::cl::init(false)); -static llvm::cl::opt<bool> enablePolymorphic( - "polymorphic-type", - llvm::cl::desc("enable polymorphic type lowering (experimental)"), - llvm::cl::init(false)); - static llvm::cl::opt<bool> enableNoPPCNativeVecElemOrder( "fno-ppc-native-vector-element-order", llvm::cl::desc("no PowerPC native vector element order."), @@ -351,7 +346,6 @@ static mlir::LogicalResult convertFortranSourceToMLIR( std::string targetTriple = targetMachine.getTargetTriple().normalize(); // Use default lowering options for bbc. Fortran::lower::LoweringOptions loweringOptions{}; - loweringOptions.setPolymorphicTypeImpl(enablePolymorphic); loweringOptions.setNoPPCNativeVecElemOrder(enableNoPPCNativeVecElemOrder); loweringOptions.setLowerToHighLevelFIR(useHLFIR || emitHLFIR); std::vector<Fortran::lower::EnvironmentDefault> envDefaults = {}; -- GitLab From d671ebe46ce6bb542ab81ea120751c985f3fe4a3 Mon Sep 17 00:00:00 2001 From: Sergio Afonso <safonsof@amd.com> Date: Tue, 19 Mar 2024 10:45:59 +0000 Subject: [PATCH 048/307] [Flang][Lower] NFC: Replace SmallVector with more suitable alternatives (#85227) In this patch some uses of `llvm::SmallVector` in Flang's lowering to MLIR are replaced by other types (i.e. `llvm::ArrayRef` and `llvm::SmallVectorImpl`) which are intended for these uses. This generally prevents relying on always passing small vectors with a particular number of elements in the stack. --- flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 6 +-- flang/lib/Lower/OpenMP/OpenMP.cpp | 59 +++++++++++----------- flang/lib/Lower/OpenMP/Utils.h | 4 +- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 6fefd04f409b..13347c8cf7b6 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -577,7 +577,7 @@ public: } // Returns the shape of array types. - const llvm::SmallVector<int64_t> &getShape() const { return shape; } + llvm::ArrayRef<int64_t> getShape() const { return shape; } // Is the type inside a box? bool isBox() const { return inBox; } @@ -788,8 +788,8 @@ bool ClauseProcessor::processLink( mlir::omp::MapInfoOp createMapInfoOp(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value baseAddr, mlir::Value varPtrPtr, std::string name, - mlir::SmallVector<mlir::Value> bounds, - mlir::SmallVector<mlir::Value> members, uint64_t mapType, + llvm::ArrayRef<mlir::Value> bounds, + llvm::ArrayRef<mlir::Value> members, uint64_t mapType, mlir::omp::VariableCaptureKind mapCaptureType, mlir::Type retTy, bool isVal) { if (auto boxTy = baseAddr.getType().dyn_cast<fir::BaseBoxType>()) { diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 7b384d84ad63..eaaa8fcd165a 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -287,9 +287,9 @@ struct OpWithBodyGenInfo { return *this; } - OpWithBodyGenInfo & - setReductions(llvm::SmallVector<const Fortran::semantics::Symbol *> *value1, - llvm::SmallVector<mlir::Type> *value2) { + OpWithBodyGenInfo &setReductions( + llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *value1, + llvm::SmallVectorImpl<mlir::Type> *value2) { reductionSymbols = value1; reductionTypes = value2; return *this; @@ -317,10 +317,10 @@ struct OpWithBodyGenInfo { /// [in] if provided, processes the construct's data-sharing attributes. DataSharingProcessor *dsp = nullptr; /// [in] if provided, list of reduction symbols - llvm::SmallVector<const Fortran::semantics::Symbol *> *reductionSymbols = + llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *reductionSymbols = nullptr; /// [in] if provided, list of reduction types - llvm::SmallVector<mlir::Type> *reductionTypes = nullptr; + llvm::SmallVectorImpl<mlir::Type> *reductionTypes = nullptr; /// [in] if provided, emits the op's region entry. Otherwise, an emtpy block /// is created in the region. GenOMPRegionEntryCBFn genRegionEntryCB = nullptr; @@ -465,11 +465,9 @@ static void genBodyOfTargetDataOp( Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, bool genNested, - mlir::omp::DataOp &dataOp, - const llvm::SmallVector<mlir::Type> &useDeviceTypes, - const llvm::SmallVector<mlir::Location> &useDeviceLocs, - const llvm::SmallVector<const Fortran::semantics::Symbol *> - &useDeviceSymbols, + mlir::omp::DataOp &dataOp, llvm::ArrayRef<mlir::Type> useDeviceTypes, + llvm::ArrayRef<mlir::Location> useDeviceLocs, + llvm::ArrayRef<const Fortran::semantics::Symbol *> useDeviceSymbols, const mlir::Location ¤tLocation) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); mlir::Region ®ion = dataOp.getRegion(); @@ -814,11 +812,12 @@ genTaskGroupOp(Fortran::lower::AbstractConverter &converter, // clause. Support for such list items in a use_device_ptr clause // is deprecated." static void promoteNonCPtrUseDevicePtrArgsToUseDeviceAddr( - llvm::SmallVector<mlir::Value> &devicePtrOperands, - llvm::SmallVector<mlir::Value> &deviceAddrOperands, - llvm::SmallVector<mlir::Type> &useDeviceTypes, - llvm::SmallVector<mlir::Location> &useDeviceLocs, - llvm::SmallVector<const Fortran::semantics::Symbol *> &useDeviceSymbols) { + llvm::SmallVectorImpl<mlir::Value> &devicePtrOperands, + llvm::SmallVectorImpl<mlir::Value> &deviceAddrOperands, + llvm::SmallVectorImpl<mlir::Type> &useDeviceTypes, + llvm::SmallVectorImpl<mlir::Location> &useDeviceLocs, + llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> + &useDeviceSymbols) { auto moveElementToBack = [](size_t idx, auto &vector) { auto *iter = std::next(vector.begin(), idx); vector.push_back(*iter); @@ -951,15 +950,15 @@ genEnterExitUpdateDataOp(Fortran::lower::AbstractConverter &converter, // This functions creates a block for the body of the targetOp's region. It adds // all the symbols present in mapSymbols as block arguments to this block. -static void genBodyOfTargetOp( - Fortran::lower::AbstractConverter &converter, - Fortran::semantics::SemanticsContext &semaCtx, - Fortran::lower::pft::Evaluation &eval, bool genNested, - mlir::omp::TargetOp &targetOp, - const llvm::SmallVector<mlir::Type> &mapSymTypes, - const llvm::SmallVector<mlir::Location> &mapSymLocs, - const llvm::SmallVector<const Fortran::semantics::Symbol *> &mapSymbols, - const mlir::Location ¤tLocation) { +static void +genBodyOfTargetOp(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, + Fortran::lower::pft::Evaluation &eval, bool genNested, + mlir::omp::TargetOp &targetOp, + llvm::ArrayRef<mlir::Type> mapSymTypes, + llvm::ArrayRef<mlir::Location> mapSymLocs, + llvm::ArrayRef<const Fortran::semantics::Symbol *> mapSymbols, + const mlir::Location ¤tLocation) { assert(mapSymTypes.size() == mapSymLocs.size()); fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); @@ -1491,7 +1490,7 @@ static void convertLoopBounds(Fortran::lower::AbstractConverter &converter, static llvm::SmallVector<const Fortran::semantics::Symbol *> genLoopVars(mlir::Operation *op, Fortran::lower::AbstractConverter &converter, mlir::Location &loc, - const llvm::SmallVector<const Fortran::semantics::Symbol *> &args) { + llvm::ArrayRef<const Fortran::semantics::Symbol *> args) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); auto ®ion = op->getRegion(0); @@ -1512,16 +1511,16 @@ genLoopVars(mlir::Operation *op, Fortran::lower::AbstractConverter &converter, } firOpBuilder.setInsertionPointAfter(storeOp); - return args; + return llvm::SmallVector<const Fortran::semantics::Symbol *>(args); } static llvm::SmallVector<const Fortran::semantics::Symbol *> genLoopAndReductionVars( mlir::Operation *op, Fortran::lower::AbstractConverter &converter, mlir::Location &loc, - const llvm::SmallVector<const Fortran::semantics::Symbol *> &loopArgs, - const llvm::SmallVector<const Fortran::semantics::Symbol *> &reductionArgs, - llvm::SmallVector<mlir::Type> &reductionTypes) { + llvm::ArrayRef<const Fortran::semantics::Symbol *> loopArgs, + llvm::ArrayRef<const Fortran::semantics::Symbol *> reductionArgs, + llvm::SmallVectorImpl<mlir::Type> &reductionTypes) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); llvm::SmallVector<mlir::Type> blockArgTypes; @@ -1564,7 +1563,7 @@ genLoopAndReductionVars( converter.bindSymbol(*arg, prv); } - return loopArgs; + return llvm::SmallVector<const Fortran::semantics::Symbol *>(loopArgs); } static void diff --git a/flang/lib/Lower/OpenMP/Utils.h b/flang/lib/Lower/OpenMP/Utils.h index 176ab2b5238a..3ab0823a4621 100644 --- a/flang/lib/Lower/OpenMP/Utils.h +++ b/flang/lib/Lower/OpenMP/Utils.h @@ -46,8 +46,8 @@ using DeclareTargetCapturePair = mlir::omp::MapInfoOp createMapInfoOp(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value baseAddr, mlir::Value varPtrPtr, std::string name, - mlir::SmallVector<mlir::Value> bounds, - mlir::SmallVector<mlir::Value> members, uint64_t mapType, + mlir::ArrayRef<mlir::Value> bounds, + mlir::ArrayRef<mlir::Value> members, uint64_t mapType, mlir::omp::VariableCaptureKind mapCaptureType, mlir::Type retTy, bool isVal = false); -- GitLab From aeb4dd14440dd7a0f11cb9a97a733b08323f56c9 Mon Sep 17 00:00:00 2001 From: Janek van Oirschot <5994977+JanekvO@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:47:40 +0000 Subject: [PATCH 049/307] Fix macro expansion for AMDHSA_BITS_SET (#85661) Corrects the `AMDHSA_BITS_SET` macro. --- llvm/include/llvm/Support/AMDHSAKernelDescriptor.h | 9 ++++++--- llvm/test/MC/AMDGPU/hsa-gfx12-v4.s | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/Support/AMDHSAKernelDescriptor.h b/llvm/include/llvm/Support/AMDHSAKernelDescriptor.h index 84cac3ef700e..a119b0724d67 100644 --- a/llvm/include/llvm/Support/AMDHSAKernelDescriptor.h +++ b/llvm/include/llvm/Support/AMDHSAKernelDescriptor.h @@ -46,9 +46,12 @@ // Sets bits for specified bit mask in specified destination. #ifndef AMDHSA_BITS_SET -#define AMDHSA_BITS_SET(DST, MSK, VAL) \ - DST &= ~MSK; \ - DST |= ((VAL << MSK ## _SHIFT) & MSK) +#define AMDHSA_BITS_SET(DST, MSK, VAL) \ + do { \ + auto local = VAL; \ + DST &= ~MSK; \ + DST |= ((local << MSK##_SHIFT) & MSK); \ + } while (0) #endif // AMDHSA_BITS_SET namespace llvm { diff --git a/llvm/test/MC/AMDGPU/hsa-gfx12-v4.s b/llvm/test/MC/AMDGPU/hsa-gfx12-v4.s index 8b90e20bb87d..7b591904e877 100644 --- a/llvm/test/MC/AMDGPU/hsa-gfx12-v4.s +++ b/llvm/test/MC/AMDGPU/hsa-gfx12-v4.s @@ -29,7 +29,7 @@ // OBJDUMP-NEXT: 0000 00000000 00000000 00000000 00000000 // OBJDUMP-NEXT: 0010 00000000 00000000 00000000 00000000 // OBJDUMP-NEXT: 0020 00000000 00000000 00000000 00000000 -// OBJDUMP-NEXT: 0030 00000c60 80000000 00000000 00000000 +// OBJDUMP-NEXT: 0030 00000c60 80000000 00040000 00000000 // complete // OBJDUMP-NEXT: 0040 01000000 01000000 08000000 00000000 // OBJDUMP-NEXT: 0050 00000000 00000000 00000000 00000000 @@ -39,12 +39,12 @@ // OBJDUMP-NEXT: 0080 00000000 00000000 00000000 00000000 // OBJDUMP-NEXT: 0090 00000000 00000000 00000000 00000000 // OBJDUMP-NEXT: 00a0 00000000 00000000 00000000 00000000 -// OBJDUMP-NEXT: 00b0 00000060 80000000 00000000 00000000 +// OBJDUMP-NEXT: 00b0 00000060 80000000 00040000 00000000 // disabled_user_sgpr // OBJDUMP-NEXT: 00c0 00000000 00000000 00000000 00000000 // OBJDUMP-NEXT: 00d0 00000000 00000000 00000000 00000000 // OBJDUMP-NEXT: 00e0 00000000 00000000 00000000 00000000 -// OBJDUMP-NEXT: 00f0 00000c60 80000000 00000000 00000000 +// OBJDUMP-NEXT: 00f0 00000c60 80000000 00040000 00000000 .text // ASM: .text -- GitLab From 953c13b5c90bed1e24fe95e90137c4e226ac2d09 Mon Sep 17 00:00:00 2001 From: Pierre van Houtryve <pierre.vanhoutryve@amd.com> Date: Tue, 19 Mar 2024 11:49:22 +0100 Subject: [PATCH 050/307] [AMDGPU][PromoteAlloca] Whole-function alloca promotion to vector (#84735) Update PromoteAllocaToVector so it considers the whole function before promoting allocas. Allocas are scored & sorted so the highest value ones are seen first. The budget is now per function instead of per alloca. Passed internal performance testing. --- .../lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp | 134 ++++++++++++++---- llvm/test/CodeGen/AMDGPU/llc-pipeline.ll | 10 +- .../CodeGen/AMDGPU/promote-alloca-scoring.ll | 69 +++++++++ 3 files changed, 182 insertions(+), 31 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/promote-alloca-scoring.ll diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp index e86132769f57..6f3cdf54dcee 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -32,6 +32,7 @@ #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/InstSimplifyFolder.h" #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/IRBuilder.h" @@ -39,6 +40,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsR600.h" #include "llvm/IR/PatternMatch.h" +#include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/Utils/SSAUpdater.h" @@ -64,10 +66,17 @@ static cl::opt<unsigned> PromoteAllocaToVectorLimit( cl::desc("Maximum byte size to consider promote alloca to vector"), cl::init(0)); +static cl::opt<unsigned> + LoopUserWeight("promote-alloca-vector-loop-user-weight", + cl::desc("The bonus weight of users of allocas within loop " + "when sorting profitable allocas"), + cl::init(4)); + // Shared implementation which can do both promotion to vector and to LDS. class AMDGPUPromoteAllocaImpl { private: const TargetMachine &TM; + LoopInfo &LI; Module *Mod = nullptr; const DataLayout *DL = nullptr; @@ -101,8 +110,11 @@ private: bool tryPromoteAllocaToVector(AllocaInst &I); bool tryPromoteAllocaToLDS(AllocaInst &I, bool SufficientLDS); + void sortAllocasToPromote(SmallVectorImpl<AllocaInst *> &Allocas); + public: - AMDGPUPromoteAllocaImpl(TargetMachine &TM) : TM(TM) { + AMDGPUPromoteAllocaImpl(TargetMachine &TM, LoopInfo &LI) : TM(TM), LI(LI) { + const Triple &TT = TM.getTargetTriple(); IsAMDGCN = TT.getArch() == Triple::amdgcn; IsAMDHSA = TT.getOS() == Triple::AMDHSA; @@ -122,7 +134,9 @@ public: if (skipFunction(F)) return false; if (auto *TPC = getAnalysisIfAvailable<TargetPassConfig>()) - return AMDGPUPromoteAllocaImpl(TPC->getTM<TargetMachine>()) + return AMDGPUPromoteAllocaImpl( + TPC->getTM<TargetMachine>(), + getAnalysis<LoopInfoWrapperPass>().getLoopInfo()) .run(F, /*PromoteToLDS*/ true); return false; } @@ -131,6 +145,7 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); + AU.addRequired<LoopInfoWrapperPass>(); FunctionPass::getAnalysisUsage(AU); } }; @@ -145,7 +160,9 @@ public: if (skipFunction(F)) return false; if (auto *TPC = getAnalysisIfAvailable<TargetPassConfig>()) - return AMDGPUPromoteAllocaImpl(TPC->getTM<TargetMachine>()) + return AMDGPUPromoteAllocaImpl( + TPC->getTM<TargetMachine>(), + getAnalysis<LoopInfoWrapperPass>().getLoopInfo()) .run(F, /*PromoteToLDS*/ false); return false; } @@ -156,6 +173,7 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); + AU.addRequired<LoopInfoWrapperPass>(); FunctionPass::getAnalysisUsage(AU); } }; @@ -186,18 +204,23 @@ INITIALIZE_PASS_BEGIN(AMDGPUPromoteAlloca, DEBUG_TYPE, // Move LDS uses from functions to kernels before promote alloca for accurate // estimation of LDS available INITIALIZE_PASS_DEPENDENCY(AMDGPULowerModuleLDSLegacy) +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_END(AMDGPUPromoteAlloca, DEBUG_TYPE, "AMDGPU promote alloca to vector or LDS", false, false) -INITIALIZE_PASS(AMDGPUPromoteAllocaToVector, DEBUG_TYPE "-to-vector", - "AMDGPU promote alloca to vector", false, false) +INITIALIZE_PASS_BEGIN(AMDGPUPromoteAllocaToVector, DEBUG_TYPE "-to-vector", + "AMDGPU promote alloca to vector", false, false) +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) +INITIALIZE_PASS_END(AMDGPUPromoteAllocaToVector, DEBUG_TYPE "-to-vector", + "AMDGPU promote alloca to vector", false, false) char &llvm::AMDGPUPromoteAllocaID = AMDGPUPromoteAlloca::ID; char &llvm::AMDGPUPromoteAllocaToVectorID = AMDGPUPromoteAllocaToVector::ID; PreservedAnalyses AMDGPUPromoteAllocaPass::run(Function &F, FunctionAnalysisManager &AM) { - bool Changed = AMDGPUPromoteAllocaImpl(TM).run(F, /*PromoteToLDS*/ true); + auto &LI = AM.getResult<LoopAnalysis>(F); + bool Changed = AMDGPUPromoteAllocaImpl(TM, LI).run(F, /*PromoteToLDS=*/true); if (Changed) { PreservedAnalyses PA; PA.preserveSet<CFGAnalyses>(); @@ -208,7 +231,8 @@ PreservedAnalyses AMDGPUPromoteAllocaPass::run(Function &F, PreservedAnalyses AMDGPUPromoteAllocaToVectorPass::run(Function &F, FunctionAnalysisManager &AM) { - bool Changed = AMDGPUPromoteAllocaImpl(TM).run(F, /*PromoteToLDS*/ false); + auto &LI = AM.getResult<LoopAnalysis>(F); + bool Changed = AMDGPUPromoteAllocaImpl(TM, LI).run(F, /*PromoteToLDS=*/false); if (Changed) { PreservedAnalyses PA; PA.preserveSet<CFGAnalyses>(); @@ -225,6 +249,55 @@ FunctionPass *llvm::createAMDGPUPromoteAllocaToVector() { return new AMDGPUPromoteAllocaToVector(); } +static void collectAllocaUses(AllocaInst &Alloca, + SmallVectorImpl<Use *> &Uses) { + SmallVector<Instruction *, 4> WorkList({&Alloca}); + while (!WorkList.empty()) { + auto *Cur = WorkList.pop_back_val(); + for (auto &U : Cur->uses()) { + Uses.push_back(&U); + + if (isa<GetElementPtrInst>(U.getUser())) + WorkList.push_back(cast<Instruction>(U.getUser())); + } + } +} + +void AMDGPUPromoteAllocaImpl::sortAllocasToPromote( + SmallVectorImpl<AllocaInst *> &Allocas) { + DenseMap<AllocaInst *, unsigned> Scores; + + for (auto *Alloca : Allocas) { + LLVM_DEBUG(dbgs() << "Scoring: " << *Alloca << "\n"); + unsigned &Score = Scores[Alloca]; + // Increment score by one for each user + a bonus for users within loops. + SmallVector<Use *, 8> Uses; + collectAllocaUses(*Alloca, Uses); + for (auto *U : Uses) { + Instruction *Inst = cast<Instruction>(U->getUser()); + if (isa<GetElementPtrInst>(Inst)) + continue; + unsigned UserScore = + 1 + (LoopUserWeight * LI.getLoopDepth(Inst->getParent())); + LLVM_DEBUG(dbgs() << " [+" << UserScore << "]:\t" << *Inst << "\n"); + Score += UserScore; + } + LLVM_DEBUG(dbgs() << " => Final Score:" << Score << "\n"); + } + + stable_sort(Allocas, [&](AllocaInst *A, AllocaInst *B) { + return Scores.at(A) > Scores.at(B); + }); + + // clang-format off + LLVM_DEBUG( + dbgs() << "Sorted Worklist:\n"; + for (auto *A: Allocas) + dbgs() << " " << *A << "\n"; + ); + // clang-format on +} + bool AMDGPUPromoteAllocaImpl::run(Function &F, bool PromoteToLDS) { Mod = F.getParent(); DL = &Mod->getDataLayout(); @@ -237,6 +310,13 @@ bool AMDGPUPromoteAllocaImpl::run(Function &F, bool PromoteToLDS) { bool SufficientLDS = PromoteToLDS ? hasSufficientLocalMem(F) : false; + // Use up to 1/4 of available register budget for vectorization. + // FIXME: Increase the limit for whole function budgets? Perhaps x2? + unsigned VectorizationBudget = + (PromoteAllocaToVectorLimit ? PromoteAllocaToVectorLimit * 8 + : (MaxVGPRs * 32)) / + 4; + SmallVector<AllocaInst *, 16> Allocas; for (Instruction &I : F.getEntryBlock()) { if (AllocaInst *AI = dyn_cast<AllocaInst>(&I)) { @@ -248,11 +328,27 @@ bool AMDGPUPromoteAllocaImpl::run(Function &F, bool PromoteToLDS) { } } + sortAllocasToPromote(Allocas); + bool Changed = false; for (AllocaInst *AI : Allocas) { - if (tryPromoteAllocaToVector(*AI)) + const unsigned AllocaCost = DL->getTypeSizeInBits(AI->getAllocatedType()); + if (AllocaCost > VectorizationBudget) { + LLVM_DEBUG(dbgs() << " Alloca too big for vectorization: " << *AI + << "\n"); + return false; + } + + if (tryPromoteAllocaToVector(*AI)) { Changed = true; - else if (PromoteToLDS && tryPromoteAllocaToLDS(*AI, SufficientLDS)) + assert((VectorizationBudget - AllocaCost) < VectorizationBudget && + "Underflow!"); + VectorizationBudget -= AllocaCost; + LLVM_DEBUG(dbgs() << " Remaining vectorization budget:" + << VectorizationBudget << "\n"); + if (VectorizationBudget == 0) + break; + } else if (PromoteToLDS && tryPromoteAllocaToLDS(*AI, SufficientLDS)) Changed = true; } @@ -641,16 +737,6 @@ bool AMDGPUPromoteAllocaImpl::tryPromoteAllocaToVector(AllocaInst &Alloca) { ArrayTy->getNumElements()); } - // Use up to 1/4 of available register budget for vectorization. - unsigned Limit = PromoteAllocaToVectorLimit ? PromoteAllocaToVectorLimit * 8 - : (MaxVGPRs * 32); - - if (DL->getTypeSizeInBits(AllocaTy) * 4 > Limit) { - LLVM_DEBUG(dbgs() << " Alloca too big for vectorization with " << MaxVGPRs - << " registers available\n"); - return false; - } - // FIXME: There is no reason why we can't support larger arrays, we // are just being conservative for now. // FIXME: We also reject alloca's of the form [ 2 x [ 2 x i32 ]] or @@ -671,7 +757,6 @@ bool AMDGPUPromoteAllocaImpl::tryPromoteAllocaToVector(AllocaInst &Alloca) { SmallVector<Instruction *> WorkList; SmallVector<Instruction *> UsersToRemove; SmallVector<Instruction *> DeferredInsts; - SmallVector<Use *, 8> Uses; DenseMap<MemTransferInst *, MemTransferInfo> TransferInfo; const auto RejectUser = [&](Instruction *Inst, Twine Msg) { @@ -680,15 +765,14 @@ bool AMDGPUPromoteAllocaImpl::tryPromoteAllocaToVector(AllocaInst &Alloca) { return false; }; - for (Use &U : Alloca.uses()) - Uses.push_back(&U); + SmallVector<Use *, 8> Uses; + collectAllocaUses(Alloca, Uses); LLVM_DEBUG(dbgs() << " Attempting promotion to: " << *VectorTy << "\n"); Type *VecEltTy = VectorTy->getElementType(); unsigned ElementSize = DL->getTypeSizeInBits(VecEltTy) / 8; - while (!Uses.empty()) { - Use *U = Uses.pop_back_val(); + for (auto *U : Uses) { Instruction *Inst = cast<Instruction>(U->getUser()); if (Value *Ptr = getLoadStorePointerOperand(Inst)) { @@ -732,8 +816,6 @@ bool AMDGPUPromoteAllocaImpl::tryPromoteAllocaToVector(AllocaInst &Alloca) { return RejectUser(Inst, "cannot compute vector index for GEP"); GEPVectorIdx[GEP] = Index; - for (Use &U : Inst->uses()) - Uses.push_back(&U); UsersToRemove.push_back(Inst); continue; } diff --git a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll index 5007f77316f5..0ff5dd3680df 100644 --- a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll +++ b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll @@ -195,13 +195,13 @@ ; GCN-O1-NEXT: Uniformity Analysis ; GCN-O1-NEXT: AMDGPU atomic optimizations ; GCN-O1-NEXT: Expand Atomic instructions -; GCN-O1-NEXT: AMDGPU Promote Alloca ; GCN-O1-NEXT: Dominator Tree Construction +; GCN-O1-NEXT: Natural Loop Information +; GCN-O1-NEXT: AMDGPU Promote Alloca ; GCN-O1-NEXT: Cycle Info Analysis ; GCN-O1-NEXT: Uniformity Analysis ; GCN-O1-NEXT: AMDGPU IR optimizations ; GCN-O1-NEXT: Basic Alias Analysis (stateless AA impl) -; GCN-O1-NEXT: Natural Loop Information ; GCN-O1-NEXT: Canonicalize natural loops ; GCN-O1-NEXT: Scalar Evolution Analysis ; GCN-O1-NEXT: Loop Pass Manager @@ -470,9 +470,9 @@ ; GCN-O1-OPTS-NEXT: Uniformity Analysis ; GCN-O1-OPTS-NEXT: AMDGPU atomic optimizations ; GCN-O1-OPTS-NEXT: Expand Atomic instructions -; GCN-O1-OPTS-NEXT: AMDGPU Promote Alloca ; GCN-O1-OPTS-NEXT: Dominator Tree Construction ; GCN-O1-OPTS-NEXT: Natural Loop Information +; GCN-O1-OPTS-NEXT: AMDGPU Promote Alloca ; GCN-O1-OPTS-NEXT: Canonicalize natural loops ; GCN-O1-OPTS-NEXT: Lazy Branch Probability Analysis ; GCN-O1-OPTS-NEXT: Lazy Block Frequency Analysis @@ -775,9 +775,9 @@ ; GCN-O2-NEXT: Uniformity Analysis ; GCN-O2-NEXT: AMDGPU atomic optimizations ; GCN-O2-NEXT: Expand Atomic instructions -; GCN-O2-NEXT: AMDGPU Promote Alloca ; GCN-O2-NEXT: Dominator Tree Construction ; GCN-O2-NEXT: Natural Loop Information +; GCN-O2-NEXT: AMDGPU Promote Alloca ; GCN-O2-NEXT: Split GEPs to a variadic base and a constant offset for better CSE ; GCN-O2-NEXT: Scalar Evolution Analysis ; GCN-O2-NEXT: Straight line strength reduction @@ -1084,9 +1084,9 @@ ; GCN-O3-NEXT: Uniformity Analysis ; GCN-O3-NEXT: AMDGPU atomic optimizations ; GCN-O3-NEXT: Expand Atomic instructions -; GCN-O3-NEXT: AMDGPU Promote Alloca ; GCN-O3-NEXT: Dominator Tree Construction ; GCN-O3-NEXT: Natural Loop Information +; GCN-O3-NEXT: AMDGPU Promote Alloca ; GCN-O3-NEXT: Split GEPs to a variadic base and a constant offset for better CSE ; GCN-O3-NEXT: Scalar Evolution Analysis ; GCN-O3-NEXT: Straight line strength reduction diff --git a/llvm/test/CodeGen/AMDGPU/promote-alloca-scoring.ll b/llvm/test/CodeGen/AMDGPU/promote-alloca-scoring.ll new file mode 100644 index 000000000000..ab03177d1edc --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/promote-alloca-scoring.ll @@ -0,0 +1,69 @@ +; RUN: opt -S -mtriple=amdgcn-unknown-amdhsa -mcpu=kaveri -debug-only=amdgpu-promote-alloca -amdgpu-promote-alloca-to-vector-limit=512 -passes=amdgpu-promote-alloca %s -o - 2>&1 | FileCheck %s +; REQUIRES: asserts + +; CHECK: Scoring: %simpleuser = alloca [4 x i64], align 4, addrspace(5) +; CHECK-NEXT: [+1]: store i32 42, ptr addrspace(5) %simpleuser, align 4 +; CHECK-NEXT: => Final Score:1 +; CHECK-NEXT: Scoring: %manyusers = alloca [4 x i64], align 4, addrspace(5) +; CHECK-NEXT: [+1]: store i32 %v0.ext, ptr addrspace(5) %manyusers.1, align 4 +; CHECK-NEXT: [+1]: %v0 = load i8, ptr addrspace(5) %manyusers.1, align 1 +; CHECK-NEXT: [+1]: store i32 %v1.ext, ptr addrspace(5) %manyusers.2, align 4 +; CHECK-NEXT: [+1]: %v1 = load i8, ptr addrspace(5) %manyusers.2, align 1 +; CHECK-NEXT: => Final Score:4 +; CHECK-NEXT: Sorted Worklist: +; CHECK-NEXT: %manyusers = alloca [4 x i64], align 4, addrspace(5) +; CHECK-NEXT: %simpleuser = alloca [4 x i64], align 4, addrspace(5) +define amdgpu_kernel void @simple_users_scores() #0 { +entry: + ; should get a score of 1 + %simpleuser = alloca [4 x i64], align 4, addrspace(5) + ; should get a score of 4 + %manyusers = alloca [4 x i64], align 4, addrspace(5) + + store i32 42, ptr addrspace(5) %simpleuser + + %manyusers.1 = getelementptr i8, ptr addrspace(5) %manyusers, i64 2 + %v0 = load i8, ptr addrspace(5) %manyusers.1 + %v0.ext = zext i8 %v0 to i32 + store i32 %v0.ext, ptr addrspace(5) %manyusers.1 + + %manyusers.2 = getelementptr i8, ptr addrspace(5) %manyusers, i64 1 + %v1 = load i8, ptr addrspace(5) %manyusers.2 + %v1.ext = zext i8 %v0 to i32 + store i32 %v1.ext, ptr addrspace(5) %manyusers.2 + + ret void +} + +; CHECK: Scoring: %stack = alloca [4 x i64], align 4, addrspace(5) +; CHECK-NEXT: [+5]: store i32 32, ptr addrspace(5) %stack, align 4 +; CHECK-NEXT: [+1]: store i32 42, ptr addrspace(5) %stack, align 4 +; CHECK-NEXT: [+9]: store i32 32, ptr addrspace(5) %stack.1, align 4 +; CHECK-NEXT: [+5]: %outer.cmp = load i1, ptr addrspace(5) %stack.1, align 1 +; CHECK-NEXT: [+1]: store i32 64, ptr addrspace(5) %stack.2, align 4 +; CHECK-NEXT: [+9]: %inner.cmp = load i1, ptr addrspace(5) %stack.2, align 1 +; CHECK-NEXT: => Final Score:30 +define amdgpu_kernel void @loop_users_alloca(i1 %x, i2) #0 { +entry: + ; should get a score of 1 + %stack = alloca [4 x i64], align 4, addrspace(5) + %stack.1 = getelementptr i8, ptr addrspace(5) %stack, i64 4 + %stack.2 = getelementptr i8, ptr addrspace(5) %stack, i64 8 + + store i32 42, ptr addrspace(5) %stack + br label %loop.outer + +loop.outer: + store i32 32, ptr addrspace(5) %stack + %outer.cmp = load i1, ptr addrspace(5) %stack.1 + br label %loop.inner + +loop.inner: + store i32 32, ptr addrspace(5) %stack.1 + %inner.cmp = load i1, ptr addrspace(5) %stack.2 + br i1 %inner.cmp, label %loop.inner, label %loop.outer + +exit: + store i32 64, ptr addrspace(5) %stack.2 + ret void +} -- GitLab From ccf042e90e1b987d69f01378ed89b832f86d434a Mon Sep 17 00:00:00 2001 From: Kai Sasaki <lewuathe@gmail.com> Date: Tue, 19 Mar 2024 20:03:05 +0900 Subject: [PATCH 051/307] [mlir][complex] Make CPU runner test platform agnostic (#85607) --- .../test/Integration/Dialect/Complex/CPU/correctness.mlir | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mlir/test/Integration/Dialect/Complex/CPU/correctness.mlir b/mlir/test/Integration/Dialect/Complex/CPU/correctness.mlir index a42ed6968d37..441f7500538f 100644 --- a/mlir/test/Integration/Dialect/Complex/CPU/correctness.mlir +++ b/mlir/test/Integration/Dialect/Complex/CPU/correctness.mlir @@ -9,9 +9,6 @@ // RUN: -shared-libs=%mlir_c_runner_utils |\ // RUN: FileCheck %s -// XFAIL: target=aarch64{{.*}} -// See: https://github.com/llvm/llvm-project/issues/58531 - func.func @test_unary(%input: tensor<?xcomplex<f32>>, %func: (complex<f32>) -> complex<f32>) { %c0 = arith.constant 0 : index @@ -189,8 +186,9 @@ func.func @entry() { // CHECK-NEXT: 0 // CHECK-NEXT: 0 (0.0, 0.0), (-1.0, 0.0), - // CHECK-NEXT: -nan - // CHECK-NEXT: -nan + // Ignoring the sign of nan as that can't be tested in platform agnostic manner. See: #58531 + // CHECK-NEXT: nan + // CHECK-NEXT: nan (1.0, 1.0), (1.0, 1.0) // CHECK-NEXT: 0.273 // CHECK-NEXT: 0.583 -- GitLab From c9bdeabdf4b46fbf1f6a9fcbf9cd61d460b18c08 Mon Sep 17 00:00:00 2001 From: serge-sans-paille <sguelton@mozilla.com> Date: Tue, 19 Mar 2024 12:15:33 +0100 Subject: [PATCH 052/307] [tsan][test] Switch setitimer(ITIMER_REAL, ...) to setitimer(ITIMER_VIRTUAL, ...) Followup to #85188 --- compiler-rt/test/tsan/signal_sync.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler-rt/test/tsan/signal_sync.cpp b/compiler-rt/test/tsan/signal_sync.cpp index b283c9341636..878b3f3b88b9 100644 --- a/compiler-rt/test/tsan/signal_sync.cpp +++ b/compiler-rt/test/tsan/signal_sync.cpp @@ -30,7 +30,7 @@ int main() { struct sigaction act = {}; act.sa_handler = &handler; - if (sigaction(SIGALRM, &act, 0)) { + if (sigaction(SIGVTALRM, &act, 0)) { perror("sigaction"); exit(1); } @@ -39,7 +39,7 @@ int main() { t.it_value.tv_sec = 0; t.it_value.tv_usec = 10; t.it_interval = t.it_value; - if (setitimer(ITIMER_REAL, &t, 0)) { + if (setitimer(ITIMER_VIRTUAL, &t, 0)) { perror("setitimer"); exit(1); } -- GitLab From 00ca80938b732ee43deb2a94bec1c7efef3025d4 Mon Sep 17 00:00:00 2001 From: Nikita Popov <npopov@redhat.com> Date: Tue, 19 Mar 2024 12:20:00 +0100 Subject: [PATCH 053/307] [ConstantFold] Fix comparison between special pointer constants This code was assuming that the LHS would always be one of GlobalVariable, BlockAddress or ConstantExpr. However, it can also be a special constant like dso_local_equivalent or no_cfi. Make sure this is handled gracefully. --- llvm/lib/IR/ConstantFold.cpp | 3 +-- .../test/Transforms/InstSimplify/ConstProp/icmp-global.ll | 8 ++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 034e397bc69f..e22785174e23 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -1154,10 +1154,9 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2) { GV->getType()->getAddressSpace())) return ICmpInst::ICMP_UGT; } - } else { + } else if (auto *CE1 = dyn_cast<ConstantExpr>(V1)) { // Ok, the LHS is known to be a constantexpr. The RHS can be any of a // constantexpr, a global, block address, or a simple constant. - ConstantExpr *CE1 = cast<ConstantExpr>(V1); Constant *CE1Op0 = CE1->getOperand(0); switch (CE1->getOpcode()) { diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/icmp-global.ll b/llvm/test/Transforms/InstSimplify/ConstProp/icmp-global.ll index 3851bd090aef..b4afb7bd4a2b 100644 --- a/llvm/test/Transforms/InstSimplify/ConstProp/icmp-global.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/icmp-global.ll @@ -298,3 +298,11 @@ bb: %cmp = icmp eq ptr blockaddress(@blockaddr_no_cfi, %bb), no_cfi @func ret i1 %cmp } + +define i1 @global_no_cfi_dso_local_equivalent() { +; CHECK-LABEL: @global_no_cfi_dso_local_equivalent( +; CHECK-NEXT: ret i1 icmp eq (ptr dso_local_equivalent @func, ptr no_cfi @func) +; + %cmp = icmp eq ptr dso_local_equivalent @func, no_cfi @func + ret i1 %cmp +} -- GitLab From 7edfbf2af2253297f48ff8adaba99373f67e8dca Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuch12@gmail.com> Date: Tue, 19 Mar 2024 11:26:43 +0000 Subject: [PATCH 054/307] [lldb][DataFormatter] Fix format specifiers in LibCxxSliceArray summary provider (#85763) This caused following warnings in an LLDB build: ``` [237/1072] Building CXX object tools/l...lusLanguage.dir/LibCxxSliceArray.cpp.o /Volumes/Data/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp:38:53: warning: format specifies type 'unsigned long long' but the argument has type 'size_t' (aka 'unsigned long') [-Wformat] 38 | stream.Printf("stride=%" PRIu64 " size=%" PRIu64, stride, size); | ~~~~~~~~~ ^~~~~~ /Volumes/Data/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp:38:61: warning: format specifies type 'unsigned long long' but the argument has type 'size_t' (aka 'unsigned long') [-Wformat] 38 | stream.Printf("stride=%" PRIu64 " size=%" PRIu64, stride, size); | ~~~~~~~~~ ^~~~ 2 warnings generated. ``` This patch simply changes the format specifiers to use the `%zu` for `size_t`s. --- lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp index 323de11b1c97..32e67d2e38c5 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp @@ -35,7 +35,7 @@ bool LibcxxStdSliceArraySummaryProvider(ValueObject &valobj, Stream &stream, return false; const size_t stride = ptr_sp->GetValueAsUnsigned(0); - stream.Printf("stride=%" PRIu64 " size=%" PRIu64, stride, size); + stream.Printf("stride=%zu size=%zu", stride, size); return true; } -- GitLab From 078aaf1f78e5df55618b71f1fe75993e4ccb6a72 Mon Sep 17 00:00:00 2001 From: wanglei <wanglei@loongson.cn> Date: Tue, 19 Mar 2024 19:36:59 +0800 Subject: [PATCH 055/307] [LoongArch] Add diagnostics for PseudoLI_D instruction (#85742) Simultaneously improved diagnostic testing for the `PseudoLI_W` instruction. --- .../LoongArch/AsmParser/LoongArchAsmParser.cpp | 12 ++++++++++++ llvm/lib/Target/LoongArch/LoongArchInstrInfo.td | 5 ++++- llvm/test/MC/LoongArch/Macros/macros-li-bad.s | 6 ++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp index 46f63a4103f9..cf163e4e1200 100644 --- a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp +++ b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp @@ -453,6 +453,14 @@ public: } bool isImm32() const { return isSImm<32>() || isUImm<32>(); } + bool isImm64() const { + if (!isImm()) + return false; + int64_t Imm; + LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + return IsConstantImm && VK == LoongArchMCExpr::VK_LoongArch_None; + } /// Gets location of the first token of this operand. SMLoc getStartLoc() const override { return StartLoc; } @@ -1514,6 +1522,10 @@ bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc(); return Error(ErrorLoc, "operand must be a 32 bit immediate"); } + case Match_InvalidImm64: { + SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, "operand must be a 64 bit immediate"); + } case Match_InvalidBareSymbol: { SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc(); return Error(ErrorLoc, "operand must be a bare symbol name"); diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td index fcfff08d1a9f..80429bc45be1 100644 --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -219,6 +219,9 @@ def grlenimm : Operand<GRLenVT>; def imm32 : Operand<GRLenVT> { let ParserMatchClass = ImmAsmOperand<"", 32, "">; } +def imm64 : Operand<i64> { + let ParserMatchClass = ImmAsmOperand<"", 64, "">; +} def uimm1 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<1>(Imm);}]>{ let ParserMatchClass = UImmAsmOperand<1>; @@ -2179,7 +2182,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0, isAsmParserOnly = 1 in { def PseudoLI_W : Pseudo<(outs GPR:$rd), (ins imm32:$imm), [], "li.w", "$rd, $imm">; -def PseudoLI_D : Pseudo<(outs GPR:$rd), (ins grlenimm:$imm), [], +def PseudoLI_D : Pseudo<(outs GPR:$rd), (ins imm64:$imm), [], "li.d", "$rd, $imm">, Requires<[IsLA64]>; } diff --git a/llvm/test/MC/LoongArch/Macros/macros-li-bad.s b/llvm/test/MC/LoongArch/Macros/macros-li-bad.s index 194b86bfed27..c880a0102005 100644 --- a/llvm/test/MC/LoongArch/Macros/macros-li-bad.s +++ b/llvm/test/MC/LoongArch/Macros/macros-li-bad.s @@ -5,3 +5,9 @@ li.w $a0, 0x100000000 li.d $a0, 0x10000000000000000 # CHECK: :[[#@LINE-1]]:11: error: unknown operand + +li.w $a0, non_const_val +# CHECK: :[[#@LINE-1]]:11: error: operand must be a 32 bit immediate + +li.d $a0, non_const_val +# CHECK: :[[#@LINE-1]]:11: error: operand must be a 64 bit immediate -- GitLab From 2f2f16f32bb2a6c250b19adbc229d9dc3b38640c Mon Sep 17 00:00:00 2001 From: Sergio Afonso <safonsof@amd.com> Date: Tue, 19 Mar 2024 11:49:45 +0000 Subject: [PATCH 056/307] [Flang][OpenMP][Lower] NFC: Move clause processing helpers into the ClauseProcessor (#85258) This patch moves some code in PFT to MLIR OpenMP lowering to the `ClauseProcessor` class. This is so that some behavior that is related to certain clauses stays within the `ClauseProcessor` and it's not the caller the one responsible for always doing this when the clause is present. --- flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 31 +++++++++- flang/lib/Lower/OpenMP/ClauseProcessor.h | 15 +++-- flang/lib/Lower/OpenMP/OpenMP.cpp | 72 +++------------------- flang/lib/Lower/OpenMP/Utils.cpp | 19 ++++++ flang/lib/Lower/OpenMP/Utils.h | 3 + 5 files changed, 66 insertions(+), 74 deletions(-) diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 13347c8cf7b6..81919f2a4896 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -208,6 +208,25 @@ addUseDeviceClause(Fortran::lower::AbstractConverter &converter, useDeviceSymbols.push_back(object.id()); } +static void convertLoopBounds(Fortran::lower::AbstractConverter &converter, + mlir::Location loc, + llvm::SmallVectorImpl<mlir::Value> &lowerBound, + llvm::SmallVectorImpl<mlir::Value> &upperBound, + llvm::SmallVectorImpl<mlir::Value> &step, + std::size_t loopVarTypeSize) { + fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); + // The types of lower bound, upper bound, and step are converted into the + // type of the loop variable if necessary. + mlir::Type loopVarType = getLoopVarType(converter, loopVarTypeSize); + for (unsigned it = 0; it < (unsigned)lowerBound.size(); it++) { + lowerBound[it] = + firOpBuilder.createConvert(loc, loopVarType, lowerBound[it]); + upperBound[it] = + firOpBuilder.createConvert(loc, loopVarType, upperBound[it]); + step[it] = firOpBuilder.createConvert(loc, loopVarType, step[it]); + } +} + //===----------------------------------------------------------------------===// // ClauseProcessor unique clauses //===----------------------------------------------------------------------===// @@ -217,8 +236,7 @@ bool ClauseProcessor::processCollapse( llvm::SmallVectorImpl<mlir::Value> &lowerBound, llvm::SmallVectorImpl<mlir::Value> &upperBound, llvm::SmallVectorImpl<mlir::Value> &step, - llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> &iv, - std::size_t &loopVarTypeSize) const { + llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> &iv) const { bool found = false; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); @@ -236,7 +254,7 @@ bool ClauseProcessor::processCollapse( found = true; } - loopVarTypeSize = 0; + std::size_t loopVarTypeSize = 0; do { Fortran::lower::pft::Evaluation *doLoop = &doConstructEval->getFirstNestedEvaluation(); @@ -267,6 +285,9 @@ bool ClauseProcessor::processCollapse( &*std::next(doConstructEval->getNestedEvaluations().begin()); } while (collapseValue > 0); + convertLoopBounds(converter, currentLocation, lowerBound, upperBound, step, + loopVarTypeSize); + return found; } @@ -907,6 +928,7 @@ bool ClauseProcessor::processMap( bool ClauseProcessor::processReduction( mlir::Location currentLocation, llvm::SmallVectorImpl<mlir::Value> &reductionVars, + llvm::SmallVectorImpl<mlir::Type> &reductionTypes, llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols, llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *reductionSymbols) const { @@ -916,6 +938,9 @@ bool ClauseProcessor::processReduction( ReductionProcessor rp; rp.addReductionDecl(currentLocation, converter, clause, reductionVars, reductionDeclSymbols, reductionSymbols); + reductionTypes.reserve(reductionVars.size()); + llvm::transform(reductionVars, std::back_inserter(reductionTypes), + [](mlir::Value v) { return v.getType(); }); }); } diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index 3f6adcce8ae8..3f50909fe73a 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -56,14 +56,12 @@ public: clauses(makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. - bool - processCollapse(mlir::Location currentLocation, - Fortran::lower::pft::Evaluation &eval, - llvm::SmallVectorImpl<mlir::Value> &lowerBound, - llvm::SmallVectorImpl<mlir::Value> &upperBound, - llvm::SmallVectorImpl<mlir::Value> &step, - llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> &iv, - std::size_t &loopVarTypeSize) const; + bool processCollapse( + mlir::Location currentLocation, Fortran::lower::pft::Evaluation &eval, + llvm::SmallVectorImpl<mlir::Value> &lowerBound, + llvm::SmallVectorImpl<mlir::Value> &upperBound, + llvm::SmallVectorImpl<mlir::Value> &step, + llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> &iv) const; bool processDefault() const; bool processDevice(Fortran::lower::StatementContext &stmtCtx, mlir::Value &result) const; @@ -126,6 +124,7 @@ public: bool processReduction(mlir::Location currentLocation, llvm::SmallVectorImpl<mlir::Value> &reductionVars, + llvm::SmallVectorImpl<mlir::Type> &reductionTypes, llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols, llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *reductionSymbols = nullptr) const; diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index eaaa8fcd165a..dbdb6f1a453b 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -214,24 +214,6 @@ static void threadPrivatizeVars(Fortran::lower::AbstractConverter &converter, firOpBuilder.restoreInsertionPoint(insPt); } -static mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter, - std::size_t loopVarTypeSize) { - // OpenMP runtime requires 32-bit or 64-bit loop variables. - loopVarTypeSize = loopVarTypeSize * 8; - if (loopVarTypeSize < 32) { - loopVarTypeSize = 32; - } else if (loopVarTypeSize > 64) { - loopVarTypeSize = 64; - mlir::emitWarning(converter.getCurrentLocation(), - "OpenMP loop iteration variable cannot have more than 64 " - "bits size and will be narrowed into 64 bits."); - } - assert((loopVarTypeSize == 32 || loopVarTypeSize == 64) && - "OpenMP loop iteration variable size must be transformed into 32-bit " - "or 64-bit"); - return converter.getFirOpBuilder().getIntegerType(loopVarTypeSize); -} - static mlir::Operation * createAndSetPrivatizedLoopVar(Fortran::lower::AbstractConverter &converter, mlir::Location loc, mlir::Value indexVal, @@ -568,6 +550,7 @@ genParallelOp(Fortran::lower::AbstractConverter &converter, mlir::omp::ClauseProcBindKindAttr procBindKindAttr; llvm::SmallVector<mlir::Value> allocateOperands, allocatorOperands, reductionVars; + llvm::SmallVector<mlir::Type> reductionTypes; llvm::SmallVector<mlir::Attribute> reductionDeclSymbols; llvm::SmallVector<const Fortran::semantics::Symbol *> reductionSymbols; @@ -578,13 +561,8 @@ genParallelOp(Fortran::lower::AbstractConverter &converter, cp.processDefault(); cp.processAllocate(allocatorOperands, allocateOperands); if (!outerCombined) - cp.processReduction(currentLocation, reductionVars, reductionDeclSymbols, - &reductionSymbols); - - llvm::SmallVector<mlir::Type> reductionTypes; - reductionTypes.reserve(reductionVars.size()); - llvm::transform(reductionVars, std::back_inserter(reductionTypes), - [](mlir::Value v) { return v.getType(); }); + cp.processReduction(currentLocation, reductionVars, reductionTypes, + reductionDeclSymbols, &reductionSymbols); auto reductionCallback = [&](mlir::Operation *op) { llvm::SmallVector<mlir::Location> locs(reductionVars.size(), @@ -1468,25 +1446,6 @@ genOMP(Fortran::lower::AbstractConverter &converter, standaloneConstruct.u); } -static void convertLoopBounds(Fortran::lower::AbstractConverter &converter, - mlir::Location loc, - llvm::SmallVectorImpl<mlir::Value> &lowerBound, - llvm::SmallVectorImpl<mlir::Value> &upperBound, - llvm::SmallVectorImpl<mlir::Value> &step, - std::size_t loopVarTypeSize) { - fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - // The types of lower bound, upper bound, and step are converted into the - // type of the loop variable if necessary. - mlir::Type loopVarType = getLoopVarType(converter, loopVarTypeSize); - for (unsigned it = 0; it < (unsigned)lowerBound.size(); it++) { - lowerBound[it] = - firOpBuilder.createConvert(loc, loopVarType, lowerBound[it]); - upperBound[it] = - firOpBuilder.createConvert(loc, loopVarType, upperBound[it]); - step[it] = firOpBuilder.createConvert(loc, loopVarType, step[it]); - } -} - static llvm::SmallVector<const Fortran::semantics::Symbol *> genLoopVars(mlir::Operation *op, Fortran::lower::AbstractConverter &converter, mlir::Location &loc, @@ -1582,16 +1541,15 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter, llvm::SmallVector<mlir::Value> lowerBound, upperBound, step, reductionVars; llvm::SmallVector<mlir::Value> alignedVars, nontemporalVars; llvm::SmallVector<const Fortran::semantics::Symbol *> iv; + llvm::SmallVector<mlir::Type> reductionTypes; llvm::SmallVector<mlir::Attribute> reductionDeclSymbols; mlir::omp::ClauseOrderKindAttr orderClauseOperand; mlir::IntegerAttr simdlenClauseOperand, safelenClauseOperand; - std::size_t loopVarTypeSize; ClauseProcessor cp(converter, semaCtx, loopOpClauseList); - cp.processCollapse(loc, eval, lowerBound, upperBound, step, iv, - loopVarTypeSize); + cp.processCollapse(loc, eval, lowerBound, upperBound, step, iv); cp.processScheduleChunk(stmtCtx, scheduleChunkClauseOperand); - cp.processReduction(loc, reductionVars, reductionDeclSymbols); + cp.processReduction(loc, reductionVars, reductionTypes, reductionDeclSymbols); cp.processIf(clause::If::DirectiveNameModifier::Simd, ifClauseOperand); cp.processSimdlen(simdlenClauseOperand); cp.processSafelen(safelenClauseOperand); @@ -1601,9 +1559,6 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter, Fortran::parser::OmpClause::Nontemporal, Fortran::parser::OmpClause::Order>(loc, ompDirective); - convertLoopBounds(converter, loc, lowerBound, upperBound, step, - loopVarTypeSize); - mlir::TypeRange resultType; auto simdLoopOp = firOpBuilder.create<mlir::omp::SimdLoopOp>( loc, resultType, lowerBound, upperBound, step, alignedVars, @@ -1641,6 +1596,7 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, llvm::SmallVector<mlir::Value> lowerBound, upperBound, step, reductionVars; llvm::SmallVector<mlir::Value> linearVars, linearStepVars; llvm::SmallVector<const Fortran::semantics::Symbol *> iv; + llvm::SmallVector<mlir::Type> reductionTypes; llvm::SmallVector<mlir::Attribute> reductionDeclSymbols; llvm::SmallVector<const Fortran::semantics::Symbol *> reductionSymbols; mlir::omp::ClauseOrderKindAttr orderClauseOperand; @@ -1648,20 +1604,15 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, mlir::UnitAttr nowaitClauseOperand, byrefOperand, scheduleSimdClauseOperand; mlir::IntegerAttr orderedClauseOperand; mlir::omp::ScheduleModifierAttr scheduleModClauseOperand; - std::size_t loopVarTypeSize; ClauseProcessor cp(converter, semaCtx, beginClauseList); - cp.processCollapse(loc, eval, lowerBound, upperBound, step, iv, - loopVarTypeSize); + cp.processCollapse(loc, eval, lowerBound, upperBound, step, iv); cp.processScheduleChunk(stmtCtx, scheduleChunkClauseOperand); - cp.processReduction(loc, reductionVars, reductionDeclSymbols, + cp.processReduction(loc, reductionVars, reductionTypes, reductionDeclSymbols, &reductionSymbols); cp.processTODO<Fortran::parser::OmpClause::Linear, Fortran::parser::OmpClause::Order>(loc, ompDirective); - convertLoopBounds(converter, loc, lowerBound, upperBound, step, - loopVarTypeSize); - if (ReductionProcessor::doReductionByRef(reductionVars)) byrefOperand = firOpBuilder.getUnitAttr(); @@ -1702,11 +1653,6 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, auto *nestedEval = getCollapsedLoopEval( eval, Fortran::lower::getCollapseValue(beginClauseList)); - llvm::SmallVector<mlir::Type> reductionTypes; - reductionTypes.reserve(reductionVars.size()); - llvm::transform(reductionVars, std::back_inserter(reductionTypes), - [](mlir::Value v) { return v.getType(); }); - auto ivCallback = [&](mlir::Operation *op) { return genLoopAndReductionVars(op, converter, loc, iv, reductionSymbols, reductionTypes); diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp index fa4a51e33848..b9c0660aa4da 100644 --- a/flang/lib/Lower/OpenMP/Utils.cpp +++ b/flang/lib/Lower/OpenMP/Utils.cpp @@ -15,6 +15,7 @@ #include <flang/Lower/AbstractConverter.h> #include <flang/Lower/ConvertType.h> +#include <flang/Optimizer/Builder/FIRBuilder.h> #include <flang/Parser/parse-tree.h> #include <flang/Parser/tools.h> #include <flang/Semantics/tools.h> @@ -70,6 +71,24 @@ void genObjectList2(const Fortran::parser::OmpObjectList &objectList, } } +mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter, + std::size_t loopVarTypeSize) { + // OpenMP runtime requires 32-bit or 64-bit loop variables. + loopVarTypeSize = loopVarTypeSize * 8; + if (loopVarTypeSize < 32) { + loopVarTypeSize = 32; + } else if (loopVarTypeSize > 64) { + loopVarTypeSize = 64; + mlir::emitWarning(converter.getCurrentLocation(), + "OpenMP loop iteration variable cannot have more than 64 " + "bits size and will be narrowed into 64 bits."); + } + assert((loopVarTypeSize == 32 || loopVarTypeSize == 64) && + "OpenMP loop iteration variable size must be transformed into 32-bit " + "or 64-bit"); + return converter.getFirOpBuilder().getIntegerType(loopVarTypeSize); +} + void gatherFuncAndVarSyms( const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause, llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause) { diff --git a/flang/lib/Lower/OpenMP/Utils.h b/flang/lib/Lower/OpenMP/Utils.h index 3ab0823a4621..4074bf73987d 100644 --- a/flang/lib/Lower/OpenMP/Utils.h +++ b/flang/lib/Lower/OpenMP/Utils.h @@ -51,6 +51,9 @@ createMapInfoOp(fir::FirOpBuilder &builder, mlir::Location loc, mlir::omp::VariableCaptureKind mapCaptureType, mlir::Type retTy, bool isVal = false); +mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter, + std::size_t loopVarTypeSize); + void gatherFuncAndVarSyms( const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause, llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause); -- GitLab From d712c5ed8fab4940ae0480e01fc72a944cbb79e6 Mon Sep 17 00:00:00 2001 From: martinboehme <mboehme@google.com> Date: Tue, 19 Mar 2024 12:53:50 +0100 Subject: [PATCH 057/307] [clang][dataflow] Make optional checker work for types derived from optional. (#84138) `llvm::MaybeAlign` does this, for example. It's not an option to simply ignore these derived classes because they get cast back to the optional classes (for example, simply when calling the optional member functions), and our transfer functions will then run on those optional classes and therefore require them to be properly initialized. --- .../Models/UncheckedOptionalAccessModel.cpp | 188 +++++++++++++----- .../UncheckedOptionalAccessModelTest.cpp | 60 ++++++ 2 files changed, 194 insertions(+), 54 deletions(-) diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp index 1d31b22b6d25..dbf4878622eb 100644 --- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp +++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp @@ -64,39 +64,125 @@ static bool hasOptionalClassName(const CXXRecordDecl &RD) { return false; } +static const CXXRecordDecl *getOptionalBaseClass(const CXXRecordDecl *RD) { + if (RD == nullptr) + return nullptr; + if (hasOptionalClassName(*RD)) + return RD; + + if (!RD->hasDefinition()) + return nullptr; + + for (const CXXBaseSpecifier &Base : RD->bases()) + if (const CXXRecordDecl *BaseClass = + getOptionalBaseClass(Base.getType()->getAsCXXRecordDecl())) + return BaseClass; + + return nullptr; +} + namespace { using namespace ::clang::ast_matchers; using LatticeTransferState = TransferState<NoopLattice>; -AST_MATCHER(CXXRecordDecl, hasOptionalClassNameMatcher) { - return hasOptionalClassName(Node); +AST_MATCHER(CXXRecordDecl, optionalClass) { return hasOptionalClassName(Node); } + +AST_MATCHER(CXXRecordDecl, optionalOrDerivedClass) { + return getOptionalBaseClass(&Node) != nullptr; } -DeclarationMatcher optionalClass() { - return classTemplateSpecializationDecl( - hasOptionalClassNameMatcher(), - hasTemplateArgument(0, refersToType(type().bind("T")))); +auto desugarsToOptionalType() { + return hasUnqualifiedDesugaredType( + recordType(hasDeclaration(cxxRecordDecl(optionalClass())))); } -auto optionalOrAliasType() { +auto desugarsToOptionalOrDerivedType() { return hasUnqualifiedDesugaredType( - recordType(hasDeclaration(optionalClass()))); + recordType(hasDeclaration(cxxRecordDecl(optionalOrDerivedClass())))); +} + +auto hasOptionalType() { return hasType(desugarsToOptionalType()); } + +/// Matches any of the spellings of the optional types and sugar, aliases, +/// derived classes, etc. +auto hasOptionalOrDerivedType() { + return hasType(desugarsToOptionalOrDerivedType()); +} + +QualType getPublicType(const Expr *E) { + auto *Cast = dyn_cast<ImplicitCastExpr>(E->IgnoreParens()); + if (Cast == nullptr || Cast->getCastKind() != CK_UncheckedDerivedToBase) { + QualType Ty = E->getType(); + if (Ty->isPointerType()) + return Ty->getPointeeType(); + return Ty; + } + + // Is the derived type that we're casting from the type of `*this`? In this + // special case, we can upcast to the base class even if the base is + // non-public. + bool CastingFromThis = isa<CXXThisExpr>(Cast->getSubExpr()); + + // Find the least-derived type in the path (i.e. the last entry in the list) + // that we can access. + const CXXBaseSpecifier *PublicBase = nullptr; + for (const CXXBaseSpecifier *Base : Cast->path()) { + if (Base->getAccessSpecifier() != AS_public && !CastingFromThis) + break; + PublicBase = Base; + CastingFromThis = false; + } + + if (PublicBase != nullptr) + return PublicBase->getType(); + + // We didn't find any public type that we could cast to. There may be more + // casts in `getSubExpr()`, so recurse. (If there aren't any more casts, this + // will return the type of `getSubExpr()`.) + return getPublicType(Cast->getSubExpr()); } -/// Matches any of the spellings of the optional types and sugar, aliases, etc. -auto hasOptionalType() { return hasType(optionalOrAliasType()); } +// Returns the least-derived type for the receiver of `MCE` that +// `MCE.getImplicitObjectArgument()->IgnoreParentImpCasts()` can be downcast to. +// Effectively, we upcast until we reach a non-public base class, unless that +// base is a base of `*this`. +// +// This is needed to correctly match methods called on types derived from +// `std::optional`. +// +// Say we have a `struct Derived : public std::optional<int> {} d;` For a call +// `d.has_value()`, the `getImplicitObjectArgument()` looks like this: +// +// ImplicitCastExpr 'const std::__optional_storage_base<int>' lvalue +// | <UncheckedDerivedToBase (optional -> __optional_storage_base)> +// `-DeclRefExpr 'Derived' lvalue Var 'd' 'Derived' +// +// The type of the implicit object argument is `__optional_storage_base` +// (since this is the internal type that `has_value()` is declared on). If we +// call `IgnoreParenImpCasts()` on the implicit object argument, we get the +// `DeclRefExpr`, which has type `Derived`. Neither of these types is +// `optional`, and hence neither is sufficient for querying whether we are +// calling a method on `optional`. +// +// Instead, starting with the most derived type, we need to follow the chain of +// casts +QualType getPublicReceiverType(const CXXMemberCallExpr &MCE) { + return getPublicType(MCE.getImplicitObjectArgument()); +} + +AST_MATCHER_P(CXXMemberCallExpr, publicReceiverType, + ast_matchers::internal::Matcher<QualType>, InnerMatcher) { + return InnerMatcher.matches(getPublicReceiverType(Node), Finder, Builder); +} auto isOptionalMemberCallWithNameMatcher( ast_matchers::internal::Matcher<NamedDecl> matcher, const std::optional<StatementMatcher> &Ignorable = std::nullopt) { - auto Exception = unless(Ignorable ? expr(anyOf(*Ignorable, cxxThisExpr())) - : cxxThisExpr()); - return cxxMemberCallExpr( - on(expr(Exception, - anyOf(hasOptionalType(), - hasType(pointerType(pointee(optionalOrAliasType())))))), - callee(cxxMethodDecl(matcher))); + return cxxMemberCallExpr(Ignorable ? on(expr(unless(*Ignorable))) + : anything(), + publicReceiverType(desugarsToOptionalType()), + callee(cxxMethodDecl(matcher))); } auto isOptionalOperatorCallWithName( @@ -129,49 +215,51 @@ auto inPlaceClass() { auto isOptionalNulloptConstructor() { return cxxConstructExpr( - hasOptionalType(), hasDeclaration(cxxConstructorDecl(parameterCountIs(1), - hasParameter(0, hasNulloptType())))); + hasParameter(0, hasNulloptType()))), + hasOptionalOrDerivedType()); } auto isOptionalInPlaceConstructor() { - return cxxConstructExpr(hasOptionalType(), - hasArgument(0, hasType(inPlaceClass()))); + return cxxConstructExpr(hasArgument(0, hasType(inPlaceClass())), + hasOptionalOrDerivedType()); } auto isOptionalValueOrConversionConstructor() { return cxxConstructExpr( - hasOptionalType(), unless(hasDeclaration( cxxConstructorDecl(anyOf(isCopyConstructor(), isMoveConstructor())))), - argumentCountIs(1), hasArgument(0, unless(hasNulloptType()))); + argumentCountIs(1), hasArgument(0, unless(hasNulloptType())), + hasOptionalOrDerivedType()); } auto isOptionalValueOrConversionAssignment() { return cxxOperatorCallExpr( hasOverloadedOperatorName("="), - callee(cxxMethodDecl(ofClass(optionalClass()))), + callee(cxxMethodDecl(ofClass(optionalOrDerivedClass()))), unless(hasDeclaration(cxxMethodDecl( anyOf(isCopyAssignmentOperator(), isMoveAssignmentOperator())))), argumentCountIs(2), hasArgument(1, unless(hasNulloptType()))); } auto isOptionalNulloptAssignment() { - return cxxOperatorCallExpr(hasOverloadedOperatorName("="), - callee(cxxMethodDecl(ofClass(optionalClass()))), - argumentCountIs(2), - hasArgument(1, hasNulloptType())); + return cxxOperatorCallExpr( + hasOverloadedOperatorName("="), + callee(cxxMethodDecl(ofClass(optionalOrDerivedClass()))), + argumentCountIs(2), hasArgument(1, hasNulloptType())); } auto isStdSwapCall() { return callExpr(callee(functionDecl(hasName("std::swap"))), - argumentCountIs(2), hasArgument(0, hasOptionalType()), - hasArgument(1, hasOptionalType())); + argumentCountIs(2), + hasArgument(0, hasOptionalOrDerivedType()), + hasArgument(1, hasOptionalOrDerivedType())); } auto isStdForwardCall() { return callExpr(callee(functionDecl(hasName("std::forward"))), - argumentCountIs(1), hasArgument(0, hasOptionalType())); + argumentCountIs(1), + hasArgument(0, hasOptionalOrDerivedType())); } constexpr llvm::StringLiteral ValueOrCallID = "ValueOrCall"; @@ -212,8 +300,9 @@ auto isValueOrNotEqX() { } auto isCallReturningOptional() { - return callExpr(hasType(qualType(anyOf( - optionalOrAliasType(), referenceType(pointee(optionalOrAliasType())))))); + return callExpr(hasType(qualType( + anyOf(desugarsToOptionalOrDerivedType(), + referenceType(pointee(desugarsToOptionalOrDerivedType())))))); } template <typename L, typename R> @@ -275,12 +364,9 @@ BoolValue *getHasValue(Environment &Env, RecordStorageLocation *OptionalLoc) { return HasValueVal; } -/// Returns true if and only if `Type` is an optional type. -bool isOptionalType(QualType Type) { - if (!Type->isRecordType()) - return false; - const CXXRecordDecl *D = Type->getAsCXXRecordDecl(); - return D != nullptr && hasOptionalClassName(*D); +QualType valueTypeFromOptionalDecl(const CXXRecordDecl &RD) { + auto &CTSD = cast<ClassTemplateSpecializationDecl>(RD); + return CTSD.getTemplateArgs()[0].getAsType(); } /// Returns the number of optional wrappers in `Type`. @@ -288,15 +374,13 @@ bool isOptionalType(QualType Type) { /// For example, if `Type` is `optional<optional<int>>`, the result of this /// function will be 2. int countOptionalWrappers(const ASTContext &ASTCtx, QualType Type) { - if (!isOptionalType(Type)) + const CXXRecordDecl *Optional = + getOptionalBaseClass(Type->getAsCXXRecordDecl()); + if (Optional == nullptr) return 0; return 1 + countOptionalWrappers( ASTCtx, - cast<ClassTemplateSpecializationDecl>(Type->getAsRecordDecl()) - ->getTemplateArgs() - .get(0) - .getAsType() - .getDesugaredType(ASTCtx)); + valueTypeFromOptionalDecl(*Optional).getDesugaredType(ASTCtx)); } StorageLocation *getLocBehindPossiblePointer(const Expr &E, @@ -843,13 +927,7 @@ auto buildDiagnoseMatchSwitch( ast_matchers::DeclarationMatcher UncheckedOptionalAccessModel::optionalClassDecl() { - return optionalClass(); -} - -static QualType valueTypeFromOptionalType(QualType OptionalTy) { - auto *CTSD = - cast<ClassTemplateSpecializationDecl>(OptionalTy->getAsCXXRecordDecl()); - return CTSD->getTemplateArgs()[0].getAsType(); + return cxxRecordDecl(optionalClass()); } UncheckedOptionalAccessModel::UncheckedOptionalAccessModel(ASTContext &Ctx, @@ -858,9 +936,11 @@ UncheckedOptionalAccessModel::UncheckedOptionalAccessModel(ASTContext &Ctx, TransferMatchSwitch(buildTransferMatchSwitch()) { Env.getDataflowAnalysisContext().setSyntheticFieldCallback( [&Ctx](QualType Ty) -> llvm::StringMap<QualType> { - if (!isOptionalType(Ty)) + const CXXRecordDecl *Optional = + getOptionalBaseClass(Ty->getAsCXXRecordDecl()); + if (Optional == nullptr) return {}; - return {{"value", valueTypeFromOptionalType(Ty)}, + return {{"value", valueTypeFromOptionalDecl(*Optional)}, {"has_value", Ctx.BoolTy}}; }); } diff --git a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp index b6e4973fd7cb..9430730004db 100644 --- a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp @@ -3383,6 +3383,66 @@ TEST_P(UncheckedOptionalAccessTest, LambdaCaptureStateNotPropagated) { } )"); } + +TEST_P(UncheckedOptionalAccessTest, ClassDerivedFromOptional) { + ExpectDiagnosticsFor(R"( + #include "unchecked_optional_access_test.h" + + struct Derived : public $ns::$optional<int> {}; + + void target(Derived opt) { + *opt; // [[unsafe]] + if (opt.has_value()) + *opt; + + // The same thing, but with a pointer receiver. + Derived *popt = &opt; + **popt; // [[unsafe]] + if (popt->has_value()) + **popt; + } + )"); +} + +TEST_P(UncheckedOptionalAccessTest, ClassTemplateDerivedFromOptional) { + ExpectDiagnosticsFor(R"( + #include "unchecked_optional_access_test.h" + + template <class T> + struct Derived : public $ns::$optional<T> {}; + + void target(Derived<int> opt) { + *opt; // [[unsafe]] + if (opt.has_value()) + *opt; + + // The same thing, but with a pointer receiver. + Derived<int> *popt = &opt; + **popt; // [[unsafe]] + if (popt->has_value()) + **popt; + } + )"); +} + +TEST_P(UncheckedOptionalAccessTest, ClassDerivedPrivatelyFromOptional) { + // Classes that derive privately from optional can themselves still call + // member functions of optional. Check that we model the optional correctly + // in this situation. + ExpectDiagnosticsFor(R"( + #include "unchecked_optional_access_test.h" + + struct Derived : private $ns::$optional<int> { + void Method() { + **this; // [[unsafe]] + if (this->has_value()) + **this; + } + }; + )", + ast_matchers::hasName("Method")); +} + // FIXME: Add support for: // - constructors (copy, move) // - assignment operators (default, copy, move) -- GitLab From 4a6bc9fd14bd79f1edf5b651b43bd9bda9b90991 Mon Sep 17 00:00:00 2001 From: Wang Pengcheng <wangpengcheng.pp@bytedance.com> Date: Tue, 19 Mar 2024 15:46:56 +0800 Subject: [PATCH 058/307] [MacroFusion] Add SingleFusion that accepts a single instruction pair We add a common class `SingleFusion` that accepts a single instruction pair to simplify fusion definitions. Pull Request: https://github.com/llvm/llvm-project/pull/85750 --- llvm/include/llvm/Target/TargetMacroFusion.td | 17 ++++++ llvm/test/TableGen/MacroFusion.td | 61 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/llvm/include/llvm/Target/TargetMacroFusion.td b/llvm/include/llvm/Target/TargetMacroFusion.td index 766ba0afbf99..0306794ef50d 100644 --- a/llvm/include/llvm/Target/TargetMacroFusion.td +++ b/llvm/include/llvm/Target/TargetMacroFusion.td @@ -134,3 +134,20 @@ class SimpleFusion<string name, string fieldName, string desc, TieReg<0, 1>, ], epilog)>; + +class SingleFusion<string name, string fieldName, string desc, + Instruction firstInst, Instruction secondInst, + MCInstPredicate firstInstPred = TruePred, + MCInstPredicate secondInstPred = TruePred, + list<FusionPredicate> prolog = [], + list<FusionPredicate> epilog = []> + : SimpleFusion<name, fieldName, desc, + CheckAll<!listconcat( + [CheckOpcode<[firstInst]>], + [firstInstPred])>, + CheckAll<!listconcat( + [CheckOpcode<[secondInst]>], + [secondInstPred])>, + prolog, epilog> { + let IsCommutable = secondInst.isCommutable; +} diff --git a/llvm/test/TableGen/MacroFusion.td b/llvm/test/TableGen/MacroFusion.td index f8d375931ab8..b54b0506c563 100644 --- a/llvm/test/TableGen/MacroFusion.td +++ b/llvm/test/TableGen/MacroFusion.td @@ -33,6 +33,8 @@ let Namespace = "Test" in { def Inst0 : TestInst<0>; def Inst1 : TestInst<1>; +let isCommutable = true in +def Inst2 : TestInst<2>; def BothFusionPredicate: BothFusionPredicateWithMCInstPredicate<CheckRegOperand<0, X0>>; def TestBothFusionPredicate: Fusion<"test-both-fusion-predicate", "HasBothFusionPredicate", @@ -55,6 +57,11 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta CheckRegOperand<0, X0> ]>>; +def TestSingleFusion: SingleFusion<"test-single-fusion", "HasTestSingleFusion", + "Test SingleFusion", + Inst0, Inst2, + secondInstPred=CheckRegOperand<0, X0>>; + // CHECK-PREDICATOR: #ifdef GET_Test_MACRO_FUSION_PRED_DECL // CHECK-PREDICATOR-NEXT: #undef GET_Test_MACRO_FUSION_PRED_DECL // CHECK-PREDICATOR-EMPTY: @@ -62,6 +69,7 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta // CHECK-PREDICATOR-NEXT: bool isTestBothFusionPredicate(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &); // CHECK-PREDICATOR-NEXT: bool isTestCommutableFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &); // CHECK-PREDICATOR-NEXT: bool isTestFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &); +// CHECK-PREDICATOR-NEXT: bool isTestSingleFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &); // CHECK-PREDICATOR-NEXT: } // end namespace llvm // CHECK-PREDICATOR-EMPTY: // CHECK-PREDICATOR-NEXT: #endif @@ -172,6 +180,57 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta // CHECK-PREDICATOR-NEXT: return false; // CHECK-PREDICATOR-NEXT: return true; // CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: bool isTestSingleFusion( +// CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII, +// CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI, +// CHECK-PREDICATOR-NEXT: const MachineInstr *FirstMI, +// CHECK-PREDICATOR-NEXT: const MachineInstr &SecondMI) { +// CHECK-PREDICATOR-NEXT: auto &MRI = SecondMI.getMF()->getRegInfo(); +// CHECK-PREDICATOR-NEXT: { +// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = &SecondMI; +// CHECK-PREDICATOR-NEXT: if (!( +// CHECK-PREDICATOR-NEXT: ( MI->getOpcode() == Test::Inst2 ) +// CHECK-PREDICATOR-NEXT: && MI->getOperand(0).getReg() == Test::X0 +// CHECK-PREDICATOR-NEXT: )) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: if (!FirstMI) +// CHECK-PREDICATOR-NEXT: return true; +// CHECK-PREDICATOR-NEXT: { +// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = FirstMI; +// CHECK-PREDICATOR-NEXT: if (!( +// CHECK-PREDICATOR-NEXT: ( MI->getOpcode() == Test::Inst0 ) +// CHECK-PREDICATOR-NEXT: && true +// CHECK-PREDICATOR-NEXT: )) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: if (!SecondMI.getOperand(0).getReg().isVirtual()) { +// CHECK-PREDICATOR-NEXT: if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg()) { +// CHECK-PREDICATOR-NEXT: if (!SecondMI.getDesc().isCommutable()) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex; +// CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2)) +// CHECK-PREDICATOR-NEXT: if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg()) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: { +// CHECK-PREDICATOR-NEXT: Register FirstDest = FirstMI->getOperand(0).getReg(); +// CHECK-PREDICATOR-NEXT: if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest)) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: if (!(FirstMI->getOperand(0).isReg() && +// CHECK-PREDICATOR-NEXT: SecondMI.getOperand(1).isReg() && +// CHECK-PREDICATOR-NEXT: FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg())) { +// CHECK-PREDICATOR-NEXT: if (!SecondMI.getDesc().isCommutable()) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex; +// CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2)) +// CHECK-PREDICATOR-NEXT: if (FirstMI->getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg()) +// CHECK-PREDICATOR-NEXT: return false; +// CHECK-PREDICATOR-NEXT: } +// CHECK-PREDICATOR-NEXT: return true; +// CHECK-PREDICATOR-NEXT: } // CHECK-PREDICATOR-NEXT: } // end namespace llvm // CHECK-PREDICATOR-EMPTY: // CHECK-PREDICATOR-NEXT: #endif @@ -180,6 +239,7 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta // CHECK-SUBTARGET: { "test-both-fusion-predicate", "Test BothFusionPredicate", Test::TestBothFusionPredicate // CHECK-SUBTARGET: { "test-commutable-fusion", "Test Commutable Fusion", Test::TestCommutableFusion // CHECK-SUBTARGET: { "test-fusion", "Test Fusion", Test::TestFusion +// CHECK-SUBTARGET: { "test-single-fusion", "Test SingleFusion", Test::TestSingleFusion // Check that we have generated `getMacroFusions()` function. // CHECK-SUBTARGET: std::vector<MacroFusionPredTy> getMacroFusions() const override; @@ -189,5 +249,6 @@ def TestCommutableFusion: SimpleFusion<"test-commutable-fusion", "HasTestCommuta // CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestBothFusionPredicate)) Fusions.push_back(llvm::isTestBothFusionPredicate); // CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestCommutableFusion)) Fusions.push_back(llvm::isTestCommutableFusion); // CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFusion)) Fusions.push_back(llvm::isTestFusion); +// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestSingleFusion)) Fusions.push_back(llvm::isTestSingleFusion); // CHECK-SUBTARGET-NEXT: return Fusions; // CHECK-SUBTARGET-NEXT: } -- GitLab From 4f909da6bc880b816e000159ce2bf69862d0936e Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams <orlando.hyams@sony.com> Date: Tue, 19 Mar 2024 12:12:35 +0000 Subject: [PATCH 059/307] [RemoveDIs] Add flag to control loading into new debug mode from bitcode (#85649) --load-bitcode-into-experimental-debuginfo-iterators false: Convert to the old debug mode after reading. true: Upgrade to the new debug info format (*). unset: Same as false (for now). (*) As of this patch it actually just means "don't convert to either mode after loading". Auto-upgrading will be implemented in an upcoming patch. With this flag we can incrementally add support for RemoveDIs by overriding the "unset" behaviour in individual tools. The flag can be removed once all tools support the new debug info mode. --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 24 +++++++++++++----- llvm/test/Bitcode/dbg-record-roundtrip.ll | 31 ++++++++++++++++++++++- llvm/tools/llvm-dis/llvm-dis.cpp | 10 +++++++- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index d284c9823c9e..dd1b3d97f026 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -100,6 +100,15 @@ static cl::opt<bool> ExpandConstantExprs( cl::desc( "Expand constant expressions to instructions for testing purposes")); +/// Load bitcode directly into RemoveDIs format (use debug records instead +/// of debug intrinsics). UNSET is treated as FALSE, so the default action +/// is to do nothing. Individual tools can override this to incrementally add +/// support for the RemoveDIs format. +cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInforFormat( + "load-bitcode-into-experimental-debuginfo-iterators", cl::Hidden, + cl::desc("Load bitcode directly into the new debug info format (regardless " + "of input format)")); + namespace { enum { @@ -4276,9 +4285,11 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( Error BitcodeReader::parseModule(uint64_t ResumeBit, bool ShouldLazyLoadMetadata, ParserCallbacks Callbacks) { - // Force the debug-info mode into the old format for now. - // FIXME: Remove this once all tools support RemoveDIs. - TheModule->IsNewDbgInfoFormat = false; + // Load directly into RemoveDIs format if LoadBitcodeIntoNewDbgInforFormat + // has been set to true (default action: load into the old debug format). + TheModule->IsNewDbgInfoFormat = + UseNewDbgInfoFormat && + LoadBitcodeIntoNewDbgInforFormat == cl::boolOrDefault::BOU_TRUE; this->ValueTypeCallback = std::move(Callbacks.ValueType); if (ResumeBit) { @@ -6762,9 +6773,9 @@ Error BitcodeReader::materialize(GlobalValue *GV) { if (Error JumpFailed = Stream.JumpToBit(DFII->second)) return JumpFailed; - // Set the debug info mode to "new", forcing a mismatch between + // Set the debug info mode to "new", possibly creating a mismatch between // module and function debug modes. This is okay because we'll convert - // everything back to the old mode after parsing. + // everything back to the old mode after parsing if needed. // FIXME: Remove this once all tools support RemoveDIs. F->IsNewDbgInfoFormat = true; @@ -6774,7 +6785,8 @@ Error BitcodeReader::materialize(GlobalValue *GV) { // Convert new debug info records into intrinsics. // FIXME: Remove this once all tools support RemoveDIs. - F->convertFromNewDbgValues(); + if (!F->getParent()->IsNewDbgInfoFormat) + F->convertFromNewDbgValues(); if (StripDebugInfo) stripDebugInfo(*F); diff --git a/llvm/test/Bitcode/dbg-record-roundtrip.ll b/llvm/test/Bitcode/dbg-record-roundtrip.ll index 84606b589e88..251c3d9f4bb7 100644 --- a/llvm/test/Bitcode/dbg-record-roundtrip.ll +++ b/llvm/test/Bitcode/dbg-record-roundtrip.ll @@ -1,5 +1,15 @@ ;; Roundtrip tests. -; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=true %s -o - | llvm-dis | FileCheck %s + +;; Load RemoveDIs mode in llvm-dis but write out debug intrinsics. +; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=true %s -o - \ +; RUN: | llvm-dis --load-bitcode-into-experimental-debuginfo-iterators=true --write-experimental-debuginfo=false \ +; RUN: | FileCheck %s + +;; Load and write RemoveDIs mode in llvm-dis. +; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=true %s -o - \ +; RUN: | llvm-dis --load-bitcode-into-experimental-debuginfo-iterators=true --write-experimental-debuginfo=true \ +; RUN: | FileCheck %s --check-prefixes=RECORDS + ;; Check that verify-uselistorder passes regardless of input format. ; RUN: llvm-as %s --write-experimental-debuginfo-iterators-to-bitcode=true -o - | verify-uselistorder ; RUN: verify-uselistorder %s @@ -39,16 +49,24 @@ entry: ; CHECK-NEXT: dbg.value(metadata ![[empty:[0-9]+]], metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]] ; CHECK-NEXT: dbg.value(metadata i32 poison, metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]] ; CHECK-NEXT: dbg.value(metadata i32 1, metadata ![[f:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]] +; RECORDS: entry: +; RECORDS-NEXT: dbg_value(i32 %p, ![[e:[0-9]+]], !DIExpression(), ![[dbg:[0-9]+]]) +; RECORDS-NEXT: dbg_value(![[empty:[0-9]+]], ![[e]], !DIExpression(), ![[dbg]]) +; RECORDS-NEXT: dbg_value(i32 poison, ![[e]], !DIExpression(), ![[dbg]]) +; RECORDS-NEXT: dbg_value(i32 1, ![[f:[0-9]+]], !DIExpression(), ![[dbg]]) tail call void @llvm.dbg.value(metadata i32 %p, metadata !32, metadata !DIExpression()), !dbg !19 tail call void @llvm.dbg.value(metadata !29, metadata !32, metadata !DIExpression()), !dbg !19 tail call void @llvm.dbg.value(metadata i32 poison, metadata !32, metadata !DIExpression()), !dbg !19 tail call void @llvm.dbg.value(metadata i32 1, metadata !33, metadata !DIExpression()), !dbg !19 ;; Arglist with an argument, constant, local use before def, poison. ; CHECK-NEXT: dbg.value(metadata !DIArgList(i32 %p, i32 0, i32 %0, i32 poison), metadata ![[f]], metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_minus)), !dbg ![[dbg]] +; RECORDS-NEXT: dbg_value(!DIArgList(i32 %p, i32 0, i32 %0, i32 poison), ![[f]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_minus), ![[dbg]]) tail call void @llvm.dbg.value(metadata !DIArgList(i32 %p, i32 0, i32 %0, i32 poison), metadata !33, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_minus)), !dbg !19 ;; Check dbg.assign use before def (value, addr and ID). Check expression order too. ; CHECK: dbg.assign(metadata i32 %0, metadata ![[i:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 0), ; CHECK-SAME: metadata ![[ID:[0-9]+]], metadata ptr %a, metadata !DIExpression(DW_OP_plus_uconst, 1)), !dbg ![[dbg]] +; RECORDS: dbg_assign(i32 %0, ![[i:[0-9]+]], !DIExpression(DW_OP_plus_uconst, 0), +; RECORDS-SAME: ![[ID:[0-9]+]], ptr %a, !DIExpression(DW_OP_plus_uconst, 1), ![[dbg]]) tail call void @llvm.dbg.assign(metadata i32 %0, metadata !36, metadata !DIExpression(DW_OP_plus_uconst, 0), metadata !37, metadata ptr %a, metadata !DIExpression(DW_OP_plus_uconst, 1)), !dbg !19 %a = alloca i32, align 4, !DIAssignID !37 ; CHECK: %a = alloca i32, align 4, !DIAssignID ![[ID]] @@ -58,6 +76,13 @@ entry: ; CHECK-NEXT: dbg.declare(metadata ptr poison, metadata ![[c:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]] ; CHECK-NEXT: dbg.declare(metadata ptr null, metadata ![[d:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]] ; CHECK-NEXT: dbg.declare(metadata ptr @g, metadata ![[h:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]] +; RECORDS: %a = alloca i32, align 4, !DIAssignID ![[ID]] +;; Check dbg.declare configurations. +; RECORDS-NEXT: dbg_declare(ptr %a, ![[a:[0-9]+]], !DIExpression(), ![[dbg]]) +; RECORDS-NEXT: dbg_declare(![[empty:[0-9]+]], ![[b:[0-9]+]], !DIExpression(), ![[dbg]]) +; RECORDS-NEXT: dbg_declare(ptr poison, ![[c:[0-9]+]], !DIExpression(), ![[dbg]]) +; RECORDS-NEXT: dbg_declare(ptr null, ![[d:[0-9]+]], !DIExpression(), ![[dbg]]) +; RECORDS-NEXT: dbg_declare(ptr @g, ![[h:[0-9]+]], !DIExpression(), ![[dbg]]) tail call void @llvm.dbg.declare(metadata ptr %a, metadata !17, metadata !DIExpression()), !dbg !19 tail call void @llvm.dbg.declare(metadata !29, metadata !28, metadata !DIExpression()), !dbg !19 tail call void @llvm.dbg.declare(metadata ptr poison, metadata !30, metadata !DIExpression()), !dbg !19 @@ -65,17 +90,21 @@ entry: tail call void @llvm.dbg.declare(metadata ptr @g, metadata !35, metadata !DIExpression()), !dbg !19 ;; Argument value dbg.declare. ; CHECK: dbg.declare(metadata ptr %storage, metadata ![[g:[0-9]+]], metadata !DIExpression()), !dbg ![[dbg]] +; RECORDS: dbg_declare(ptr %storage, ![[g:[0-9]+]], !DIExpression(), ![[dbg]]) tail call void @llvm.dbg.declare(metadata ptr %storage, metadata !34, metadata !DIExpression()), !dbg !19 ;; Use before def dbg.value. ; CHECK: dbg.value(metadata i32 %0, metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]] +; RECORDS: dbg_value(i32 %0, ![[e]], !DIExpression(), ![[dbg]]) tail call void @llvm.dbg.value(metadata i32 %0, metadata !32, metadata !DIExpression()), !dbg !19 %0 = load i32, ptr @g, align 4, !dbg !20 ;; Non-argument local value dbg.value. ; CHECK: dbg.value(metadata i32 %0, metadata ![[e]], metadata !DIExpression()), !dbg ![[dbg]] +; RECORDS: dbg_value(i32 %0, ![[e]], !DIExpression(), ![[dbg]]) tail call void @llvm.dbg.value(metadata i32 %0, metadata !32, metadata !DIExpression()), !dbg !19 store i32 %0, ptr %a, align 4, !dbg !19 %1 = load i32, ptr %a, align 4, !dbg !25 ; CHECK: dbg.label(metadata ![[label:[0-9]+]]), !dbg ![[dbg]] +; RECORDS: dbg_label(![[label:[0-9]+]], ![[dbg]]) tail call void @llvm.dbg.label(metadata !38), !dbg !19 ret i32 %1, !dbg !27 } diff --git a/llvm/tools/llvm-dis/llvm-dis.cpp b/llvm/tools/llvm-dis/llvm-dis.cpp index 06fc669390bf..8e443318dd7d 100644 --- a/llvm/tools/llvm-dis/llvm-dis.cpp +++ b/llvm/tools/llvm-dis/llvm-dis.cpp @@ -80,6 +80,8 @@ static cl::opt<bool> PrintThinLTOIndexOnly( cl::desc("Only read thinlto index and print the index as LLVM assembly."), cl::init(false), cl::Hidden, cl::cat(DisCategory)); +extern cl::opt<bool> WriteNewDbgInfoFormat; + namespace { static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) { @@ -249,8 +251,14 @@ int main(int argc, char **argv) { // All that llvm-dis does is write the assembly to a file. if (!DontPrint) { - if (M) + if (M) { + bool ChangeDbgFormat = M->IsNewDbgInfoFormat != WriteNewDbgInfoFormat; + if (ChangeDbgFormat) + M->setIsNewDbgInfoFormat(WriteNewDbgInfoFormat); M->print(Out->os(), Annotator.get(), PreserveAssemblyUseListOrder); + if (ChangeDbgFormat) + M->setIsNewDbgInfoFormat(!WriteNewDbgInfoFormat); + } if (Index) Index->print(Out->os()); } -- GitLab From d4fb50d3e5fdf4aba4981371af53aa8fbbd6bf20 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Tue, 19 Mar 2024 13:15:54 +0100 Subject: [PATCH 060/307] [bazel] Split TransformDialect into a header-only lib in prep for PR85221 This lets users use TensorDialect without depending on all dialects transitively. 513cdb82223a106f183b49a40d9acb1f7efbbe7e forces that otherwise. --- .../llvm-project-overlay/mlir/BUILD.bazel | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel index 7f08667d9f78..da1d111b0a94 100644 --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -7382,7 +7382,7 @@ cc_library( ":Support", ":TensorOpsIncGen", ":TilingInterface", - ":TransformDialect", + ":TransformDialectInterfaces", ":ValueBoundsOpInterface", ":ViewLikeInterface", "//llvm:Support", @@ -12064,6 +12064,24 @@ gentbl_cc_library( deps = [":TransformDialectTdFiles"], ) +cc_library( + name = "TransformDialectInterfaces", + # FIXME: Change this once https://github.com/llvm/llvm-project/pull/85221 lands + hdrs = glob(["include/mlir/Dialect/Transform/IR/*.h"]), + deps = [ + ":CastInterfaces", + ":IR", + ":Rewrite", + ":SideEffectInterfaces", + ":Support", + ":TransformDialectInterfacesIncGen", + ":TransformDialectUtils", + ":TransformTypesIncGen", + ":Transforms", + "//llvm:Support", + ], +) + cc_library( name = "TransformDialect", srcs = glob(["lib/Dialect/Transform/IR/*.cpp"]), -- GitLab From 08701e35ed6f29a2fca095a31f1ebbfe059d6d6e Mon Sep 17 00:00:00 2001 From: Pravin Jagtap <prjagtap@amd.com> Date: Tue, 19 Mar 2024 18:00:34 +0530 Subject: [PATCH 061/307] [AMDGPU][NFC] Test clean up. (#85775) Added common check for DPP and Iterative strategies for uniform value case since optimization applied is same. Authored-by: Pravin Jagtap <Pravin.Jagtap@amd.com> --- .../AMDGPU/global_atomic_optimizer_fp_rtn.ll | 307 ++++++------------ .../global_atomics_optimizer_fp_no_rtn.ll | 259 +++++---------- 2 files changed, 184 insertions(+), 382 deletions(-) diff --git a/llvm/test/CodeGen/AMDGPU/global_atomic_optimizer_fp_rtn.ll b/llvm/test/CodeGen/AMDGPU/global_atomic_optimizer_fp_rtn.ll index e3fada3459a0..538ef42121b8 100644 --- a/llvm/test/CodeGen/AMDGPU/global_atomic_optimizer_fp_rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/global_atomic_optimizer_fp_rtn.ll @@ -1,71 +1,43 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -mtriple=amdgcn-- -mcpu=gfx906 -amdgpu-atomic-optimizer-strategy=Iterative -passes='amdgpu-atomic-optimizer,verify<domtree>' %s | FileCheck -check-prefix=IR-ITERATIVE %s -; RUN: opt -S -mtriple=amdgcn-- -mcpu=gfx906 -amdgpu-atomic-optimizer-strategy=DPP -passes='amdgpu-atomic-optimizer,verify<domtree>' %s | FileCheck -check-prefix=IR-DPP %s +; RUN: opt -S -mtriple=amdgcn-- -mcpu=gfx906 -amdgpu-atomic-optimizer-strategy=Iterative -passes='amdgpu-atomic-optimizer,verify<domtree>' %s | FileCheck --check-prefixes=IR,IR-ITERATIVE %s +; RUN: opt -S -mtriple=amdgcn-- -mcpu=gfx906 -amdgpu-atomic-optimizer-strategy=DPP -passes='amdgpu-atomic-optimizer,verify<domtree>' %s | FileCheck --check-prefixes=IR,IR-DPP %s + +; Tests various combinations of uniform/divergent address and uniform/divergent value inputs of various types for atomic operations. +; Optimization remains same for Iterative and DPP strategies when value in uniform. These different scan/reduction +; strategies are valid for only divergent values. This optimization is valid for divergent addresses. Test also covers different scopes. define amdgpu_ps float @global_atomic_fadd_uni_address_uni_value_agent_scope_unsafe(ptr addrspace(1) inreg %ptr, float inreg %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_uni_address_uni_value_agent_scope_unsafe( -; IR-ITERATIVE-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() -; IR-ITERATIVE-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP24:%.*]] -; IR-ITERATIVE: 2: -; IR-ITERATIVE-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) -; IR-ITERATIVE-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 -; IR-ITERATIVE-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 -; IR-ITERATIVE-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 -; IR-ITERATIVE-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) -; IR-ITERATIVE-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) -; IR-ITERATIVE-NEXT: [[TMP9:%.*]] = call i64 @llvm.ctpop.i64(i64 [[TMP3]]) -; IR-ITERATIVE-NEXT: [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32 -; IR-ITERATIVE-NEXT: [[TMP11:%.*]] = uitofp i32 [[TMP10]] to float -; IR-ITERATIVE-NEXT: [[TMP12:%.*]] = fmul float [[VAL:%.*]], [[TMP11]] -; IR-ITERATIVE-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP8]], 0 -; IR-ITERATIVE-NEXT: br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP16:%.*]] -; IR-ITERATIVE: 14: -; IR-ITERATIVE-NEXT: [[TMP15:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[TMP12]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: br label [[TMP16]] -; IR-ITERATIVE: 16: -; IR-ITERATIVE-NEXT: [[TMP17:%.*]] = phi float [ poison, [[TMP2]] ], [ [[TMP15]], [[TMP14]] ] -; IR-ITERATIVE-NEXT: [[TMP18:%.*]] = bitcast float [[TMP17]] to i32 -; IR-ITERATIVE-NEXT: [[TMP19:%.*]] = call i32 @llvm.amdgcn.readfirstlane(i32 [[TMP18]]) -; IR-ITERATIVE-NEXT: [[TMP20:%.*]] = bitcast i32 [[TMP19]] to float -; IR-ITERATIVE-NEXT: [[TMP21:%.*]] = uitofp i32 [[TMP8]] to float -; IR-ITERATIVE-NEXT: [[TMP22:%.*]] = fmul float [[VAL]], [[TMP21]] -; IR-ITERATIVE-NEXT: [[TMP23:%.*]] = fadd float [[TMP20]], [[TMP22]] -; IR-ITERATIVE-NEXT: br label [[TMP24]] -; IR-ITERATIVE: 24: -; IR-ITERATIVE-NEXT: [[TMP25:%.*]] = phi float [ poison, [[TMP0:%.*]] ], [ [[TMP23]], [[TMP16]] ] -; IR-ITERATIVE-NEXT: ret float [[TMP25]] -; -; IR-DPP-LABEL: @global_atomic_fadd_uni_address_uni_value_agent_scope_unsafe( -; IR-DPP-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() -; IR-DPP-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP24:%.*]] -; IR-DPP: 2: -; IR-DPP-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) -; IR-DPP-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 -; IR-DPP-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 -; IR-DPP-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 -; IR-DPP-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) -; IR-DPP-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) -; IR-DPP-NEXT: [[TMP9:%.*]] = call i64 @llvm.ctpop.i64(i64 [[TMP3]]) -; IR-DPP-NEXT: [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32 -; IR-DPP-NEXT: [[TMP11:%.*]] = uitofp i32 [[TMP10]] to float -; IR-DPP-NEXT: [[TMP12:%.*]] = fmul float [[VAL:%.*]], [[TMP11]] -; IR-DPP-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP8]], 0 -; IR-DPP-NEXT: br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP16:%.*]] -; IR-DPP: 14: -; IR-DPP-NEXT: [[TMP15:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[TMP12]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: br label [[TMP16]] -; IR-DPP: 16: -; IR-DPP-NEXT: [[TMP17:%.*]] = phi float [ poison, [[TMP2]] ], [ [[TMP15]], [[TMP14]] ] -; IR-DPP-NEXT: [[TMP18:%.*]] = bitcast float [[TMP17]] to i32 -; IR-DPP-NEXT: [[TMP19:%.*]] = call i32 @llvm.amdgcn.readfirstlane(i32 [[TMP18]]) -; IR-DPP-NEXT: [[TMP20:%.*]] = bitcast i32 [[TMP19]] to float -; IR-DPP-NEXT: [[TMP21:%.*]] = uitofp i32 [[TMP8]] to float -; IR-DPP-NEXT: [[TMP22:%.*]] = fmul float [[VAL]], [[TMP21]] -; IR-DPP-NEXT: [[TMP23:%.*]] = fadd float [[TMP20]], [[TMP22]] -; IR-DPP-NEXT: br label [[TMP24]] -; IR-DPP: 24: -; IR-DPP-NEXT: [[TMP25:%.*]] = phi float [ poison, [[TMP0:%.*]] ], [ [[TMP23]], [[TMP16]] ] -; IR-DPP-NEXT: ret float [[TMP25]] +; IR-LABEL: @global_atomic_fadd_uni_address_uni_value_agent_scope_unsafe( +; IR-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() +; IR-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP24:%.*]] +; IR: 2: +; IR-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) +; IR-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 +; IR-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 +; IR-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 +; IR-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) +; IR-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) +; IR-NEXT: [[TMP9:%.*]] = call i64 @llvm.ctpop.i64(i64 [[TMP3]]) +; IR-NEXT: [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32 +; IR-NEXT: [[TMP11:%.*]] = uitofp i32 [[TMP10]] to float +; IR-NEXT: [[TMP12:%.*]] = fmul float [[VAL:%.*]], [[TMP11]] +; IR-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP8]], 0 +; IR-NEXT: br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP16:%.*]] +; IR: 14: +; IR-NEXT: [[TMP15:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[TMP12]] syncscope("agent") monotonic, align 4 +; IR-NEXT: br label [[TMP16]] +; IR: 16: +; IR-NEXT: [[TMP17:%.*]] = phi float [ poison, [[TMP2]] ], [ [[TMP15]], [[TMP14]] ] +; IR-NEXT: [[TMP18:%.*]] = bitcast float [[TMP17]] to i32 +; IR-NEXT: [[TMP19:%.*]] = call i32 @llvm.amdgcn.readfirstlane(i32 [[TMP18]]) +; IR-NEXT: [[TMP20:%.*]] = bitcast i32 [[TMP19]] to float +; IR-NEXT: [[TMP21:%.*]] = uitofp i32 [[TMP8]] to float +; IR-NEXT: [[TMP22:%.*]] = fmul float [[VAL]], [[TMP21]] +; IR-NEXT: [[TMP23:%.*]] = fadd float [[TMP20]], [[TMP22]] +; IR-NEXT: br label [[TMP24]] +; IR: 24: +; IR-NEXT: [[TMP25:%.*]] = phi float [ poison, [[TMP0:%.*]] ], [ [[TMP23]], [[TMP16]] ] +; IR-NEXT: ret float [[TMP25]] ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic, align 4 ret float %result @@ -411,7 +383,6 @@ define amdgpu_ps float @global_atomic_fsub_uni_address_uni_value_agent_scope_str ret float %result } - define amdgpu_ps float @global_atomic_fsub_uni_address_div_value_agent_scope_strictfp(ptr addrspace(1) inreg %ptr, float %val) #2 { ; IR-ITERATIVE-LABEL: @global_atomic_fsub_uni_address_div_value_agent_scope_strictfp( ; IR-ITERATIVE-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() #[[ATTR7]] @@ -514,61 +485,33 @@ define amdgpu_ps float @global_atomic_fsub_uni_address_div_value_agent_scope_str } define amdgpu_ps float @global_atomic_fmin_uni_address_uni_value_agent_scope_unsafe(ptr addrspace(1) inreg %ptr, float inreg %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fmin_uni_address_uni_value_agent_scope_unsafe( -; IR-ITERATIVE-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() -; IR-ITERATIVE-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP20:%.*]] -; IR-ITERATIVE: 2: -; IR-ITERATIVE-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) -; IR-ITERATIVE-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 -; IR-ITERATIVE-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 -; IR-ITERATIVE-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 -; IR-ITERATIVE-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) -; IR-ITERATIVE-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) -; IR-ITERATIVE-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0 -; IR-ITERATIVE-NEXT: br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP12:%.*]] -; IR-ITERATIVE: 10: -; IR-ITERATIVE-NEXT: [[TMP11:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: br label [[TMP12]] -; IR-ITERATIVE: 12: -; IR-ITERATIVE-NEXT: [[TMP13:%.*]] = phi float [ poison, [[TMP2]] ], [ [[TMP11]], [[TMP10]] ] -; IR-ITERATIVE-NEXT: [[TMP14:%.*]] = bitcast float [[TMP13]] to i32 -; IR-ITERATIVE-NEXT: [[TMP15:%.*]] = call i32 @llvm.amdgcn.readfirstlane(i32 [[TMP14]]) -; IR-ITERATIVE-NEXT: [[TMP16:%.*]] = bitcast i32 [[TMP15]] to float -; IR-ITERATIVE-NEXT: [[TMP17:%.*]] = uitofp i32 [[TMP8]] to float -; IR-ITERATIVE-NEXT: [[TMP18:%.*]] = select i1 [[TMP9]], float 0x7FF0000000000000, float [[VAL]] -; IR-ITERATIVE-NEXT: [[TMP19:%.*]] = call float @llvm.minnum.f32(float [[TMP16]], float [[TMP18]]) -; IR-ITERATIVE-NEXT: br label [[TMP20]] -; IR-ITERATIVE: 20: -; IR-ITERATIVE-NEXT: [[TMP21:%.*]] = phi float [ poison, [[TMP0:%.*]] ], [ [[TMP19]], [[TMP12]] ] -; IR-ITERATIVE-NEXT: ret float [[TMP21]] -; -; IR-DPP-LABEL: @global_atomic_fmin_uni_address_uni_value_agent_scope_unsafe( -; IR-DPP-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() -; IR-DPP-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP20:%.*]] -; IR-DPP: 2: -; IR-DPP-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) -; IR-DPP-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 -; IR-DPP-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 -; IR-DPP-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 -; IR-DPP-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) -; IR-DPP-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) -; IR-DPP-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0 -; IR-DPP-NEXT: br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP12:%.*]] -; IR-DPP: 10: -; IR-DPP-NEXT: [[TMP11:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: br label [[TMP12]] -; IR-DPP: 12: -; IR-DPP-NEXT: [[TMP13:%.*]] = phi float [ poison, [[TMP2]] ], [ [[TMP11]], [[TMP10]] ] -; IR-DPP-NEXT: [[TMP14:%.*]] = bitcast float [[TMP13]] to i32 -; IR-DPP-NEXT: [[TMP15:%.*]] = call i32 @llvm.amdgcn.readfirstlane(i32 [[TMP14]]) -; IR-DPP-NEXT: [[TMP16:%.*]] = bitcast i32 [[TMP15]] to float -; IR-DPP-NEXT: [[TMP17:%.*]] = uitofp i32 [[TMP8]] to float -; IR-DPP-NEXT: [[TMP18:%.*]] = select i1 [[TMP9]], float 0x7FF0000000000000, float [[VAL]] -; IR-DPP-NEXT: [[TMP19:%.*]] = call float @llvm.minnum.f32(float [[TMP16]], float [[TMP18]]) -; IR-DPP-NEXT: br label [[TMP20]] -; IR-DPP: 20: -; IR-DPP-NEXT: [[TMP21:%.*]] = phi float [ poison, [[TMP0:%.*]] ], [ [[TMP19]], [[TMP12]] ] -; IR-DPP-NEXT: ret float [[TMP21]] +; IR-LABEL: @global_atomic_fmin_uni_address_uni_value_agent_scope_unsafe( +; IR-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() +; IR-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP20:%.*]] +; IR: 2: +; IR-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) +; IR-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 +; IR-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 +; IR-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 +; IR-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) +; IR-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) +; IR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0 +; IR-NEXT: br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP12:%.*]] +; IR: 10: +; IR-NEXT: [[TMP11:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: br label [[TMP12]] +; IR: 12: +; IR-NEXT: [[TMP13:%.*]] = phi float [ poison, [[TMP2]] ], [ [[TMP11]], [[TMP10]] ] +; IR-NEXT: [[TMP14:%.*]] = bitcast float [[TMP13]] to i32 +; IR-NEXT: [[TMP15:%.*]] = call i32 @llvm.amdgcn.readfirstlane(i32 [[TMP14]]) +; IR-NEXT: [[TMP16:%.*]] = bitcast i32 [[TMP15]] to float +; IR-NEXT: [[TMP17:%.*]] = uitofp i32 [[TMP8]] to float +; IR-NEXT: [[TMP18:%.*]] = select i1 [[TMP9]], float 0x7FF0000000000000, float [[VAL]] +; IR-NEXT: [[TMP19:%.*]] = call float @llvm.minnum.f32(float [[TMP16]], float [[TMP18]]) +; IR-NEXT: br label [[TMP20]] +; IR: 20: +; IR-NEXT: [[TMP21:%.*]] = phi float [ poison, [[TMP0:%.*]] ], [ [[TMP19]], [[TMP12]] ] +; IR-NEXT: ret float [[TMP21]] ; %result = atomicrmw fmin ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret float %result @@ -1007,159 +950,109 @@ define amdgpu_ps float @global_atomic_fadd_uni_address_div_value_system_scope_st ret float %result } - define amdgpu_ps float @global_atomic_fadd_div_address_uni_value_agent_scope_unsafe(ptr addrspace(1) %ptr, float inreg %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_uni_value_agent_scope_unsafe( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_uni_value_agent_scope_unsafe( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fadd_div_address_uni_value_agent_scope_unsafe( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic, align 4 ret float %result } define amdgpu_ps float @global_atomic_fadd_div_address_div_value_agent_scope_unsafe(ptr addrspace(1) %ptr, float %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_div_value_agent_scope_unsafe( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_div_value_agent_scope_unsafe( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fadd_div_address_div_value_agent_scope_unsafe( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic, align 4 ret float %result } define amdgpu_ps float @global_atomic_fadd_div_address_uni_value_one_as_scope_unsafe_structfp(ptr addrspace(1) %ptr, float inreg %val) #1 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_uni_value_one_as_scope_unsafe_structfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_uni_value_one_as_scope_unsafe_structfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fadd_div_address_uni_value_one_as_scope_unsafe_structfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("one-as") monotonic ret float %result } define amdgpu_ps float @global_atomic_fadd_div_address_div_value_one_as_scope_unsafe_structfp(ptr addrspace(1) %ptr, float %val) #1 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_div_value_one_as_scope_unsafe_structfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_div_value_one_as_scope_unsafe_structfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fadd_div_address_div_value_one_as_scope_unsafe_structfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("one-as") monotonic ret float %result } define amdgpu_ps float @global_atomic_fsub_div_address_uni_value_agent_scope_strictfp(ptr addrspace(1) %ptr, float inreg %val) #2 { -; IR-ITERATIVE-LABEL: @global_atomic_fsub_div_address_uni_value_agent_scope_strictfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fsub_div_address_uni_value_agent_scope_strictfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fsub_div_address_uni_value_agent_scope_strictfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret float %result } - define amdgpu_ps float @global_atomic_fsub_div_address_div_value_agent_scope_strictfp(ptr addrspace(1) %ptr, float %val) #2 { -; IR-ITERATIVE-LABEL: @global_atomic_fsub_div_address_div_value_agent_scope_strictfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fsub ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fsub_div_address_div_value_agent_scope_strictfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fsub ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fsub_div_address_div_value_agent_scope_strictfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fsub ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fsub ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret float %result } define amdgpu_ps float @global_atomic_fmin_div_address_uni_value_agent_scope(ptr addrspace(1) %ptr, float inreg %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fmin_div_address_uni_value_agent_scope( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fmin_div_address_uni_value_agent_scope( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fmin_div_address_uni_value_agent_scope( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fmin ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret float %result } define amdgpu_ps float @global_atomic_fmin_div_address_div_value_agent_scope(ptr addrspace(1) %ptr, float %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fmin_div_address_div_value_agent_scope( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fmin_div_address_div_value_agent_scope( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fmin_div_address_div_value_agent_scope( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fmin ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret float %result } define amdgpu_ps float @global_atomic_fmax_div_address_uni_value_agent_scope_unsafe_structfp(ptr addrspace(1) %ptr, float inreg %val) #1{ -; IR-ITERATIVE-LABEL: @global_atomic_fmax_div_address_uni_value_agent_scope_unsafe_structfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fmax_div_address_uni_value_agent_scope_unsafe_structfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fmax_div_address_uni_value_agent_scope_unsafe_structfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fmax ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret float %result } define amdgpu_ps float @global_atomic_fmax_div_address_div_value_agent_scope_unsafe_structfp(ptr addrspace(1) %ptr, float %val) #1{ -; IR-ITERATIVE-LABEL: @global_atomic_fmax_div_address_div_value_agent_scope_unsafe_structfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fmax_div_address_div_value_agent_scope_unsafe_structfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fmax_div_address_div_value_agent_scope_unsafe_structfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fmax ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret float %result } define amdgpu_ps float @global_atomic_fadd_div_address_uni_value_system_scope_strictfp(ptr addrspace(1) %ptr, float inreg %val) #2 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_uni_value_system_scope_strictfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_uni_value_system_scope_strictfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fadd_div_address_uni_value_system_scope_strictfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val monotonic, align 4 ret float %result } define amdgpu_ps float @global_atomic_fadd_div_address_div_value_system_scope_strictfp(ptr addrspace(1) %ptr, float %val) #2 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_div_value_system_scope_strictfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 -; IR-ITERATIVE-NEXT: ret float [[RESULT]] -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_div_value_system_scope_strictfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 -; IR-DPP-NEXT: ret float [[RESULT]] +; IR-LABEL: @global_atomic_fadd_div_address_div_value_system_scope_strictfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 +; IR-NEXT: ret float [[RESULT]] ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val monotonic, align 4 ret float %result diff --git a/llvm/test/CodeGen/AMDGPU/global_atomics_optimizer_fp_no_rtn.ll b/llvm/test/CodeGen/AMDGPU/global_atomics_optimizer_fp_no_rtn.ll index f87932b9361e..cc7a45cbb6e3 100644 --- a/llvm/test/CodeGen/AMDGPU/global_atomics_optimizer_fp_no_rtn.ll +++ b/llvm/test/CodeGen/AMDGPU/global_atomics_optimizer_fp_no_rtn.ll @@ -1,55 +1,35 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -mtriple=amdgcn-- -mcpu=gfx906 -amdgpu-atomic-optimizer-strategy=Iterative -passes='amdgpu-atomic-optimizer,verify<domtree>' %s | FileCheck -check-prefix=IR-ITERATIVE %s -; RUN: opt -S -mtriple=amdgcn-- -mcpu=gfx906 -amdgpu-atomic-optimizer-strategy=DPP -passes='amdgpu-atomic-optimizer,verify<domtree>' %s | FileCheck -check-prefix=IR-DPP %s +; RUN: opt -S -mtriple=amdgcn-- -mcpu=gfx906 -amdgpu-atomic-optimizer-strategy=Iterative -passes='amdgpu-atomic-optimizer,verify<domtree>' %s | FileCheck --check-prefixes=IR,IR-ITERATIVE %s +; RUN: opt -S -mtriple=amdgcn-- -mcpu=gfx906 -amdgpu-atomic-optimizer-strategy=DPP -passes='amdgpu-atomic-optimizer,verify<domtree>' %s | FileCheck --check-prefixes=IR,IR-DPP %s + +; Tests various combinations of uniform/divergent address and uniform/divergent value inputs of various types for atomic operations. +; Optimization remains same for Iterative and DPP strategies when value in uniform. These different scan/reduction +; strategies are valid for only divergent values. This optimization is valid for divergent addresses. Test also covers different scopes. define amdgpu_ps void @global_atomic_fadd_uni_address_uni_value_agent_scope_unsafe(ptr addrspace(1) inreg %ptr, float inreg %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_uni_address_uni_value_agent_scope_unsafe( -; IR-ITERATIVE-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() -; IR-ITERATIVE-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP17:%.*]] -; IR-ITERATIVE: 2: -; IR-ITERATIVE-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) -; IR-ITERATIVE-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 -; IR-ITERATIVE-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 -; IR-ITERATIVE-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 -; IR-ITERATIVE-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) -; IR-ITERATIVE-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) -; IR-ITERATIVE-NEXT: [[TMP9:%.*]] = call i64 @llvm.ctpop.i64(i64 [[TMP3]]) -; IR-ITERATIVE-NEXT: [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32 -; IR-ITERATIVE-NEXT: [[TMP11:%.*]] = uitofp i32 [[TMP10]] to float -; IR-ITERATIVE-NEXT: [[TMP12:%.*]] = fmul float [[VAL:%.*]], [[TMP11]] -; IR-ITERATIVE-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP8]], 0 -; IR-ITERATIVE-NEXT: br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP16:%.*]] -; IR-ITERATIVE: 14: -; IR-ITERATIVE-NEXT: [[TMP15:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[TMP12]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: br label [[TMP16]] -; IR-ITERATIVE: 16: -; IR-ITERATIVE-NEXT: br label [[TMP17]] -; IR-ITERATIVE: 17: -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fadd_uni_address_uni_value_agent_scope_unsafe( -; IR-DPP-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() -; IR-DPP-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP17:%.*]] -; IR-DPP: 2: -; IR-DPP-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) -; IR-DPP-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 -; IR-DPP-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 -; IR-DPP-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 -; IR-DPP-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) -; IR-DPP-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) -; IR-DPP-NEXT: [[TMP9:%.*]] = call i64 @llvm.ctpop.i64(i64 [[TMP3]]) -; IR-DPP-NEXT: [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32 -; IR-DPP-NEXT: [[TMP11:%.*]] = uitofp i32 [[TMP10]] to float -; IR-DPP-NEXT: [[TMP12:%.*]] = fmul float [[VAL:%.*]], [[TMP11]] -; IR-DPP-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP8]], 0 -; IR-DPP-NEXT: br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP16:%.*]] -; IR-DPP: 14: -; IR-DPP-NEXT: [[TMP15:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[TMP12]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: br label [[TMP16]] -; IR-DPP: 16: -; IR-DPP-NEXT: br label [[TMP17]] -; IR-DPP: 17: -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fadd_uni_address_uni_value_agent_scope_unsafe( +; IR-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() +; IR-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP17:%.*]] +; IR: 2: +; IR-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) +; IR-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 +; IR-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 +; IR-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 +; IR-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) +; IR-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) +; IR-NEXT: [[TMP9:%.*]] = call i64 @llvm.ctpop.i64(i64 [[TMP3]]) +; IR-NEXT: [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32 +; IR-NEXT: [[TMP11:%.*]] = uitofp i32 [[TMP10]] to float +; IR-NEXT: [[TMP12:%.*]] = fmul float [[VAL:%.*]], [[TMP11]] +; IR-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP8]], 0 +; IR-NEXT: br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP16:%.*]] +; IR: 14: +; IR-NEXT: [[TMP15:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[TMP12]] syncscope("agent") monotonic, align 4 +; IR-NEXT: br label [[TMP16]] +; IR: 16: +; IR-NEXT: br label [[TMP17]] +; IR: 17: +; IR-NEXT: ret void ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic, align 4 ret void @@ -325,7 +305,6 @@ define amdgpu_ps void @global_atomic_fsub_uni_address_uni_value_agent_scope_stri ret void } - define amdgpu_ps void @global_atomic_fsub_uni_address_div_value_agent_scope_strictfp(ptr addrspace(1) inreg %ptr, float %val) #2 { ; IR-ITERATIVE-LABEL: @global_atomic_fsub_uni_address_div_value_agent_scope_strictfp( ; IR-ITERATIVE-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() #[[ATTR7]] @@ -409,45 +388,25 @@ define amdgpu_ps void @global_atomic_fsub_uni_address_div_value_agent_scope_stri } define amdgpu_ps void @global_atomic_fmin_uni_address_uni_value_agent_scope_unsafe(ptr addrspace(1) inreg %ptr, float inreg %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fmin_uni_address_uni_value_agent_scope_unsafe( -; IR-ITERATIVE-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() -; IR-ITERATIVE-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP13:%.*]] -; IR-ITERATIVE: 2: -; IR-ITERATIVE-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) -; IR-ITERATIVE-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 -; IR-ITERATIVE-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 -; IR-ITERATIVE-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 -; IR-ITERATIVE-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) -; IR-ITERATIVE-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) -; IR-ITERATIVE-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0 -; IR-ITERATIVE-NEXT: br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP12:%.*]] -; IR-ITERATIVE: 10: -; IR-ITERATIVE-NEXT: [[TMP11:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: br label [[TMP12]] -; IR-ITERATIVE: 12: -; IR-ITERATIVE-NEXT: br label [[TMP13]] -; IR-ITERATIVE: 13: -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fmin_uni_address_uni_value_agent_scope_unsafe( -; IR-DPP-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() -; IR-DPP-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP13:%.*]] -; IR-DPP: 2: -; IR-DPP-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) -; IR-DPP-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 -; IR-DPP-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 -; IR-DPP-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 -; IR-DPP-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) -; IR-DPP-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) -; IR-DPP-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0 -; IR-DPP-NEXT: br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP12:%.*]] -; IR-DPP: 10: -; IR-DPP-NEXT: [[TMP11:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: br label [[TMP12]] -; IR-DPP: 12: -; IR-DPP-NEXT: br label [[TMP13]] -; IR-DPP: 13: -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fmin_uni_address_uni_value_agent_scope_unsafe( +; IR-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.ps.live() +; IR-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP13:%.*]] +; IR: 2: +; IR-NEXT: [[TMP3:%.*]] = call i64 @llvm.amdgcn.ballot.i64(i1 true) +; IR-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32 +; IR-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP3]], 32 +; IR-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32 +; IR-NEXT: [[TMP7:%.*]] = call i32 @llvm.amdgcn.mbcnt.lo(i32 [[TMP4]], i32 0) +; IR-NEXT: [[TMP8:%.*]] = call i32 @llvm.amdgcn.mbcnt.hi(i32 [[TMP6]], i32 [[TMP7]]) +; IR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0 +; IR-NEXT: br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP12:%.*]] +; IR: 10: +; IR-NEXT: [[TMP11:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: br label [[TMP12]] +; IR: 12: +; IR-NEXT: br label [[TMP13]] +; IR: 13: +; IR-NEXT: ret void ; %result = atomicrmw fmin ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret void @@ -797,159 +756,109 @@ define amdgpu_ps void @global_atomic_fadd_uni_address_div_value_system_scope_str ret void } - define amdgpu_ps void @global_atomic_fadd_div_address_uni_value_agent_scope_unsafe(ptr addrspace(1) %ptr, float inreg %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_uni_value_agent_scope_unsafe( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_uni_value_agent_scope_unsafe( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fadd_div_address_uni_value_agent_scope_unsafe( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic, align 4 ret void } define amdgpu_ps void @global_atomic_fadd_div_address_div_value_agent_scope_unsafe(ptr addrspace(1) %ptr, float %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_div_value_agent_scope_unsafe( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_div_value_agent_scope_unsafe( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fadd_div_address_div_value_agent_scope_unsafe( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic, align 4 ret void } define amdgpu_ps void @global_atomic_fadd_div_address_uni_value_one_as_scope_unsafe_structfp(ptr addrspace(1) %ptr, float inreg %val) #1 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_uni_value_one_as_scope_unsafe_structfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_uni_value_one_as_scope_unsafe_structfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fadd_div_address_uni_value_one_as_scope_unsafe_structfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("one-as") monotonic ret void } define amdgpu_ps void @global_atomic_fadd_div_address_div_value_one_as_scope_unsafe_structfp(ptr addrspace(1) %ptr, float %val) #1 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_div_value_one_as_scope_unsafe_structfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_div_value_one_as_scope_unsafe_structfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fadd_div_address_div_value_one_as_scope_unsafe_structfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("one-as") monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("one-as") monotonic ret void } define amdgpu_ps void @global_atomic_fsub_div_address_uni_value_agent_scope_strictfp(ptr addrspace(1) %ptr, float inreg %val) #2 { -; IR-ITERATIVE-LABEL: @global_atomic_fsub_div_address_uni_value_agent_scope_strictfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fsub_div_address_uni_value_agent_scope_strictfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fsub_div_address_uni_value_agent_scope_strictfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret void } - define amdgpu_ps void @global_atomic_fsub_div_address_div_value_agent_scope_strictfp(ptr addrspace(1) %ptr, float %val) #2 { -; IR-ITERATIVE-LABEL: @global_atomic_fsub_div_address_div_value_agent_scope_strictfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fsub ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fsub_div_address_div_value_agent_scope_strictfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fsub ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fsub_div_address_div_value_agent_scope_strictfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fsub ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fsub ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret void } define amdgpu_ps void @global_atomic_fmin_div_address_uni_value_agent_scope(ptr addrspace(1) %ptr, float inreg %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fmin_div_address_uni_value_agent_scope( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fmin_div_address_uni_value_agent_scope( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fmin_div_address_uni_value_agent_scope( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fmin ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret void } define amdgpu_ps void @global_atomic_fmin_div_address_div_value_agent_scope(ptr addrspace(1) %ptr, float %val) #0 { -; IR-ITERATIVE-LABEL: @global_atomic_fmin_div_address_div_value_agent_scope( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fmin_div_address_div_value_agent_scope( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fmin_div_address_div_value_agent_scope( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fmin ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fmin ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret void } define amdgpu_ps void @global_atomic_fmax_div_address_uni_value_agent_scope_unsafe_structfp(ptr addrspace(1) %ptr, float inreg %val) #1{ -; IR-ITERATIVE-LABEL: @global_atomic_fmax_div_address_uni_value_agent_scope_unsafe_structfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fmax_div_address_uni_value_agent_scope_unsafe_structfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fmax_div_address_uni_value_agent_scope_unsafe_structfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fmax ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret void } define amdgpu_ps void @global_atomic_fmax_div_address_div_value_agent_scope_unsafe_structfp(ptr addrspace(1) %ptr, float %val) #1{ -; IR-ITERATIVE-LABEL: @global_atomic_fmax_div_address_div_value_agent_scope_unsafe_structfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fmax_div_address_div_value_agent_scope_unsafe_structfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fmax_div_address_div_value_agent_scope_unsafe_structfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fmax ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] syncscope("agent") monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fmax ptr addrspace(1) %ptr, float %val syncscope("agent") monotonic ret void } define amdgpu_ps void @global_atomic_fadd_div_address_uni_value_system_scope_strictfp(ptr addrspace(1) %ptr, float inreg %val) #2 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_uni_value_system_scope_strictfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_uni_value_system_scope_strictfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fadd_div_address_uni_value_system_scope_strictfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val monotonic, align 4 ret void } define amdgpu_ps void @global_atomic_fadd_div_address_div_value_system_scope_strictfp(ptr addrspace(1) %ptr, float %val) #2 { -; IR-ITERATIVE-LABEL: @global_atomic_fadd_div_address_div_value_system_scope_strictfp( -; IR-ITERATIVE-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 -; IR-ITERATIVE-NEXT: ret void -; -; IR-DPP-LABEL: @global_atomic_fadd_div_address_div_value_system_scope_strictfp( -; IR-DPP-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 -; IR-DPP-NEXT: ret void +; IR-LABEL: @global_atomic_fadd_div_address_div_value_system_scope_strictfp( +; IR-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr addrspace(1) [[PTR:%.*]], float [[VAL:%.*]] monotonic, align 4 +; IR-NEXT: ret void ; %result = atomicrmw fadd ptr addrspace(1) %ptr, float %val monotonic, align 4 ret void -- GitLab From afec08ef9f1015ea3fe8d67b92acfbb7837c6e9f Mon Sep 17 00:00:00 2001 From: Max Winkler <max.enrico.winkler@gmail.com> Date: Tue, 19 Mar 2024 08:30:54 -0400 Subject: [PATCH 062/307] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (#75711) Fixes https://github.com/llvm/llvm-project/issues/53520. #### Description #### Provide `intrin0.h` to be the minimal set of intrinsics that the MSVC STL requires. The `intrin0.h` header matches the latest header provided by MSVC 1939 which does include some extra intrinsics that the MSVC STL does not use. Inside `BuiltinHeaders.def` I kept the header description as `intrin.h`. If you want me to change those to `intrin0.h` for the moved intrinsics let me know. This should now allow `immintrin.h` to be used with function targets for runtime cpu detection of simd instruction sets without worrying about the compile-time overhead from MSVC STL including `intrin.h` on clang. I still need to figure out how to best update MSVC STL to detect for the presence of `intrin0.h` from clang and to use this header over `intrin.h`. #### Testing #### Built clang locally and ran the test suite. I still need to do a pass over the existing unit tests for the ms intrinsics to make sure there aren't any gaps. Wanted to get this PR up for discussion first. Modified latest MSVC STL from github to point to `intrin0.h` for clang. Wrote some test files that included MSVC STL headers that rely on intrinsics such as `atomic`, `bit` and `vector`. Built the unit tests against x86, arm, aarch64, and x64. #### Benchmarks #### The following include times are based on the x64 target with the modified headers in this PR. These timings were done by using `clang-cl.exe -ftime-trace` and taking the wall time for parsing `intrin.h` and `intrin0.h`. `intrin.h` takes ~897ms to parse. `intrin0.h` takes ~1ms to parse. If there is anything required or a different approach is preferred let me know. I would very much like to move this over the finish line so we can use function targets with clang-cl. --- clang/docs/ReleaseNotes.rst | 20 +++ clang/lib/Headers/CMakeLists.txt | 2 + clang/lib/Headers/bmiintrin.h | 6 +- clang/lib/Headers/immintrin.h | 240 ++++++++++----------------- clang/lib/Headers/intrin.h | 217 +----------------------- clang/lib/Headers/intrin0.h | 247 ++++++++++++++++++++++++++++ clang/lib/Headers/keylockerintrin.h | 13 +- clang/lib/Headers/x86gprintrin.h | 21 +-- clang/lib/Headers/x86intrin.h | 30 ++-- clang/lib/Headers/yvals_core.h | 25 +++ 10 files changed, 408 insertions(+), 413 deletions(-) create mode 100644 clang/lib/Headers/intrin0.h create mode 100644 clang/lib/Headers/yvals_core.h diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index dab7e1bf3697..5372a575071c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -454,6 +454,26 @@ Android Support Windows Support ^^^^^^^^^^^^^^^ +- Clang-cl now supports function targets with intrinsic headers. This allows + for runtime feature detection of intrinsics. Previously under clang-cl + ``immintrin.h`` and similar intrinsic headers would only include the intrinsics + if building with that feature enabled at compile time, e.g. ``avxintrin.h`` + would only be included if AVX was enabled at compile time. This was done to work + around include times from MSVC STL including ``intrin.h`` under clang-cl. + Clang-cl now provides ``intrin0.h`` for MSVC STL and therefore all intrinsic + features without requiring enablement at compile time. + Fixes: (`#53520 <https://github.com/llvm/llvm-project/issues/53520>`_) + +- Improved compile times with MSVC STL. MSVC provides ``intrin0.h`` which is a + header that only includes intrinsics that are used by MSVC STL to avoid the + use of ``intrin.h``. MSVC STL when compiled under clang uses ``intrin.h`` + instead. Clang-cl now provides ``intrin0.h`` for the same compiler throughput + purposes as MSVC. Clang-cl also provides ``yvals_core.h`` to redefine + ``_STL_INTRIN_HEADER`` to expand to ``intrin0.h`` instead of ``intrin.h``. + This also means that if all intrinsic features are enabled at compile time + including STL headers will no longer slow down compile times since ``intrin.h`` + is not included from MSVC STL. + LoongArch Support ^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 902e33bb9589..97104ccd8db5 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -254,8 +254,10 @@ set(x86_files ) set(windows_only_files + intrin0.h intrin.h vadefs.h + yvals_core.h ) set(utility_files diff --git a/clang/lib/Headers/bmiintrin.h b/clang/lib/Headers/bmiintrin.h index d8e57c0cb494..78bffe68e221 100644 --- a/clang/lib/Headers/bmiintrin.h +++ b/clang/lib/Headers/bmiintrin.h @@ -161,8 +161,7 @@ _mm_tzcnt_64(unsigned long long __X) #undef __RELAXED_FN_ATTRS -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__BMI__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__BMI__) /* Define the default attributes for the functions in this file. */ #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("bmi"))) @@ -610,7 +609,6 @@ __blsr_u64(unsigned long long __X) #undef __DEFAULT_FN_ATTRS -#endif /* !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) \ - || defined(__BMI__) */ +#endif /* !defined(__SCE__) || __has_feature(modules) || defined(__BMI__) */ #endif /* __BMIINTRIN_H */ diff --git a/clang/lib/Headers/immintrin.h b/clang/lib/Headers/immintrin.h index 27800f7a8202..508696d3725b 100644 --- a/clang/lib/Headers/immintrin.h +++ b/clang/lib/Headers/immintrin.h @@ -16,281 +16,239 @@ #include <x86gprintrin.h> -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__MMX__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__MMX__) #include <mmintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SSE__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SSE__) #include <xmmintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SSE2__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SSE2__) #include <emmintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SSE3__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SSE3__) #include <pmmintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SSSE3__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SSSE3__) #include <tmmintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__SSE4_2__) || defined(__SSE4_1__)) #include <smmintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AES__) || defined(__PCLMUL__)) #include <wmmintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__CLFLUSHOPT__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__CLFLUSHOPT__) #include <clflushoptintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__CLWB__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__CLWB__) #include <clwbintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX__) #include <avxintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX2__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX2__) #include <avx2intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__F16C__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__F16C__) #include <f16cintrin.h> #endif /* No feature check desired due to internal checks */ #include <bmiintrin.h> -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__BMI2__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__BMI2__) #include <bmi2intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__LZCNT__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__LZCNT__) #include <lzcntintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__POPCNT__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__POPCNT__) #include <popcntintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__FMA__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__FMA__) #include <fmaintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512F__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512F__) #include <avx512fintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512VL__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VL__) #include <avx512vlintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512BW__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512BW__) #include <avx512bwintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512BITALG__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512BITALG__) #include <avx512bitalgintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512CD__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512CD__) #include <avx512cdintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512VPOPCNTDQ__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VPOPCNTDQ__) #include <avx512vpopcntdqintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512VL__) && defined(__AVX512VPOPCNTDQ__)) #include <avx512vpopcntdqvlintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512VNNI__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VNNI__) #include <avx512vnniintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512VL__) && defined(__AVX512VNNI__)) #include <avx512vlvnniintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVXVNNI__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVXVNNI__) #include <avxvnniintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512DQ__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512DQ__) #include <avx512dqintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512VL__) && defined(__AVX512BITALG__)) #include <avx512vlbitalgintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512VL__) && defined(__AVX512BW__)) #include <avx512vlbwintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512VL__) && defined(__AVX512CD__)) #include <avx512vlcdintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512VL__) && defined(__AVX512DQ__)) #include <avx512vldqintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512ER__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512ER__) #include <avx512erintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512IFMA__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512IFMA__) #include <avx512ifmaintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512IFMA__) && defined(__AVX512VL__)) #include <avx512ifmavlintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVXIFMA__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVXIFMA__) #include <avxifmaintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512VBMI__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VBMI__) #include <avx512vbmiintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512VBMI__) && defined(__AVX512VL__)) #include <avx512vbmivlintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512VBMI2__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VBMI2__) #include <avx512vbmi2intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512VBMI2__) && defined(__AVX512VL__)) #include <avx512vlvbmi2intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512PF__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512PF__) #include <avx512pfintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512FP16__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512FP16__) #include <avx512fp16intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512VL__) && defined(__AVX512FP16__)) #include <avx512vlfp16intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVX512BF16__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512BF16__) #include <avx512bf16intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512VL__) && defined(__AVX512BF16__)) #include <avx512vlbf16intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__PKU__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__PKU__) #include <pkuintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__VPCLMULQDQ__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__VPCLMULQDQ__) #include <vpclmulqdqintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__VAES__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__VAES__) #include <vaesintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__GFNI__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__GFNI__) #include <gfniintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVXVNNIINT8__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVXVNNIINT8__) #include <avxvnniint8intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVXNECONVERT__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVXNECONVERT__) #include <avxneconvertintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SHA512__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SHA512__) #include <sha512intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SM3__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SM3__) #include <sm3intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SM4__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SM4__) #include <sm4intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AVXVNNIINT16__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AVXVNNIINT16__) #include <avxvnniint16intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__RDPID__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__RDPID__) /// Reads the value of the IA32_TSC_AUX MSR (0xc0000103). /// /// \headerfile <immintrin.h> @@ -304,8 +262,7 @@ _rdpid_u32(void) { } #endif // __RDPID__ -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__RDRND__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__RDRND__) /// Returns a 16-bit hardware-generated random value. /// /// \headerfile <immintrin.h> @@ -367,8 +324,7 @@ _rdrand64_step(unsigned long long *__p) } #endif /* __RDRND__ */ -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__FSGSBASE__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__FSGSBASE__) #ifdef __x86_64__ /// Reads the FS base register. /// @@ -481,8 +437,7 @@ _writegsbase_u64(unsigned long long __V) #endif #endif /* __FSGSBASE__ */ -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__MOVBE__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__MOVBE__) /* The structs used below are to force the load/store to be unaligned. This * is accomplished with the __packed__ attribute. The __may_alias__ prevents @@ -598,139 +553,118 @@ _storebe_i64(void * __P, long long __D) { #endif #endif /* __MOVBE */ -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__RTM__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__RTM__) #include <rtmintrin.h> #include <xtestintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SHA__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SHA__) #include <shaintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__FXSR__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__FXSR__) #include <fxsrintrin.h> #endif /* No feature check desired due to internal MSC_VER checks */ #include <xsaveintrin.h> -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__XSAVEOPT__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__XSAVEOPT__) #include <xsaveoptintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__XSAVEC__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__XSAVEC__) #include <xsavecintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__XSAVES__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__XSAVES__) #include <xsavesintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SHSTK__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SHSTK__) #include <cetintrin.h> #endif /* Intrinsics inside adcintrin.h are available at all times. */ #include <adcintrin.h> -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__ADX__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__ADX__) #include <adxintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__RDSEED__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__RDSEED__) #include <rdseedintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__WBNOINVD__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__WBNOINVD__) #include <wbnoinvdintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__CLDEMOTE__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__CLDEMOTE__) #include <cldemoteintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__WAITPKG__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__WAITPKG__) #include <waitpkgintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__MOVDIRI__) || defined(__MOVDIR64B__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__MOVDIRI__) || \ + defined(__MOVDIR64B__) #include <movdirintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__PCONFIG__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__PCONFIG__) #include <pconfigintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SGX__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SGX__) #include <sgxintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__PTWRITE__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__PTWRITE__) #include <ptwriteintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__INVPCID__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__INVPCID__) #include <invpcidintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AMX_FP16__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_FP16__) #include <amxfp16intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__KL__) || defined(__WIDEKL__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__KL__) || \ + defined(__WIDEKL__) #include <keylockerintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AMX_TILE__) || defined(__AMX_INT8__) || defined(__AMX_BF16__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_TILE__) || \ + defined(__AMX_INT8__) || defined(__AMX_BF16__) #include <amxintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__AMX_COMPLEX__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_COMPLEX__) #include <amxcomplexintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ defined(__AVX512VP2INTERSECT__) #include <avx512vp2intersectintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ +#if !defined(__SCE__) || __has_feature(modules) || \ (defined(__AVX512VL__) && defined(__AVX512VP2INTERSECT__)) #include <avx512vlvp2intersectintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__ENQCMD__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__ENQCMD__) #include <enqcmdintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SERIALIZE__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SERIALIZE__) #include <serializeintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__TSXLDTRK__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__TSXLDTRK__) #include <tsxldtrkintrin.h> #endif diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h index a6395143db54..fd27955fbe00 100644 --- a/clang/lib/Headers/intrin.h +++ b/clang/lib/Headers/intrin.h @@ -15,6 +15,8 @@ #ifndef __INTRIN_H #define __INTRIN_H +#include <intrin0.h> + /* First include the standard intrinsics. */ #if defined(__i386__) || defined(__x86_64__) #include <x86intrin.h> @@ -131,8 +133,6 @@ void __writefsqword(unsigned long, unsigned __int64); void __writefsword(unsigned long, unsigned short); void __writemsr(unsigned long, unsigned __int64); void *_AddressOfReturnAddress(void); -unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask); -unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask); unsigned char _bittest(long const *, long); unsigned char _bittestandcomplement(long *, long); unsigned char _bittestandreset(long *, long); @@ -151,7 +151,6 @@ long _InterlockedExchangeAdd_HLERelease(long volatile *, long); __int64 _InterlockedExchangeAdd64_HLEAcquire(__int64 volatile *, __int64); __int64 _InterlockedExchangeAdd64_HLERelease(__int64 volatile *, __int64); void _ReadBarrier(void); -void _ReadWriteBarrier(void); unsigned int _rorx_u32(unsigned int, const unsigned int); int _sarx_i32(int, unsigned int); #if __STDC_HOSTED__ @@ -182,12 +181,6 @@ unsigned char __readgsbyte(unsigned long); unsigned long __readgsdword(unsigned long); unsigned __int64 __readgsqword(unsigned long); unsigned short __readgsword(unsigned long); -unsigned __int64 __shiftleft128(unsigned __int64 _LowPart, - unsigned __int64 _HighPart, - unsigned char _Shift); -unsigned __int64 __shiftright128(unsigned __int64 _LowPart, - unsigned __int64 _HighPart, - unsigned char _Shift); void __stosq(unsigned __int64 *, unsigned __int64, size_t); unsigned char __vmx_on(unsigned __int64 *); unsigned char __vmx_vmclear(unsigned __int64 *); @@ -236,212 +229,10 @@ unsigned __int64 _shlx_u64(unsigned __int64, unsigned int); unsigned __int64 _shrx_u64(unsigned __int64, unsigned int); __int64 __mulh(__int64, __int64); unsigned __int64 __umulh(unsigned __int64, unsigned __int64); -__int64 _mul128(__int64, __int64, __int64*); -unsigned __int64 _umul128(unsigned __int64, - unsigned __int64, - unsigned __int64*); +__int64 _mul128(__int64, __int64, __int64 *); #endif /* __x86_64__ */ -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) - -unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask); -unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask); - -#endif - -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) -__int64 _InterlockedDecrement64(__int64 volatile *_Addend); -__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value); -__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value); -__int64 _InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value); -__int64 _InterlockedIncrement64(__int64 volatile *_Addend); -__int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask); -__int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask); -__int64 _InterlockedAnd64(__int64 volatile *_Value, __int64 _Mask); - -#endif - -/*----------------------------------------------------------------------------*\ -|* Interlocked Exchange Add -\*----------------------------------------------------------------------------*/ -#if defined(__arm__) || defined(__aarch64__) -char _InterlockedExchangeAdd8_acq(char volatile *_Addend, char _Value); -char _InterlockedExchangeAdd8_nf(char volatile *_Addend, char _Value); -char _InterlockedExchangeAdd8_rel(char volatile *_Addend, char _Value); -short _InterlockedExchangeAdd16_acq(short volatile *_Addend, short _Value); -short _InterlockedExchangeAdd16_nf(short volatile *_Addend, short _Value); -short _InterlockedExchangeAdd16_rel(short volatile *_Addend, short _Value); -long _InterlockedExchangeAdd_acq(long volatile *_Addend, long _Value); -long _InterlockedExchangeAdd_nf(long volatile *_Addend, long _Value); -long _InterlockedExchangeAdd_rel(long volatile *_Addend, long _Value); -__int64 _InterlockedExchangeAdd64_acq(__int64 volatile *_Addend, __int64 _Value); -__int64 _InterlockedExchangeAdd64_nf(__int64 volatile *_Addend, __int64 _Value); -__int64 _InterlockedExchangeAdd64_rel(__int64 volatile *_Addend, __int64 _Value); -#endif -/*----------------------------------------------------------------------------*\ -|* Interlocked Increment -\*----------------------------------------------------------------------------*/ -#if defined(__arm__) || defined(__aarch64__) -short _InterlockedIncrement16_acq(short volatile *_Value); -short _InterlockedIncrement16_nf(short volatile *_Value); -short _InterlockedIncrement16_rel(short volatile *_Value); -long _InterlockedIncrement_acq(long volatile *_Value); -long _InterlockedIncrement_nf(long volatile *_Value); -long _InterlockedIncrement_rel(long volatile *_Value); -__int64 _InterlockedIncrement64_acq(__int64 volatile *_Value); -__int64 _InterlockedIncrement64_nf(__int64 volatile *_Value); -__int64 _InterlockedIncrement64_rel(__int64 volatile *_Value); -#endif -/*----------------------------------------------------------------------------*\ -|* Interlocked Decrement -\*----------------------------------------------------------------------------*/ -#if defined(__arm__) || defined(__aarch64__) -short _InterlockedDecrement16_acq(short volatile *_Value); -short _InterlockedDecrement16_nf(short volatile *_Value); -short _InterlockedDecrement16_rel(short volatile *_Value); -long _InterlockedDecrement_acq(long volatile *_Value); -long _InterlockedDecrement_nf(long volatile *_Value); -long _InterlockedDecrement_rel(long volatile *_Value); -__int64 _InterlockedDecrement64_acq(__int64 volatile *_Value); -__int64 _InterlockedDecrement64_nf(__int64 volatile *_Value); -__int64 _InterlockedDecrement64_rel(__int64 volatile *_Value); -#endif -/*----------------------------------------------------------------------------*\ -|* Interlocked And -\*----------------------------------------------------------------------------*/ -#if defined(__arm__) || defined(__aarch64__) -char _InterlockedAnd8_acq(char volatile *_Value, char _Mask); -char _InterlockedAnd8_nf(char volatile *_Value, char _Mask); -char _InterlockedAnd8_rel(char volatile *_Value, char _Mask); -short _InterlockedAnd16_acq(short volatile *_Value, short _Mask); -short _InterlockedAnd16_nf(short volatile *_Value, short _Mask); -short _InterlockedAnd16_rel(short volatile *_Value, short _Mask); -long _InterlockedAnd_acq(long volatile *_Value, long _Mask); -long _InterlockedAnd_nf(long volatile *_Value, long _Mask); -long _InterlockedAnd_rel(long volatile *_Value, long _Mask); -__int64 _InterlockedAnd64_acq(__int64 volatile *_Value, __int64 _Mask); -__int64 _InterlockedAnd64_nf(__int64 volatile *_Value, __int64 _Mask); -__int64 _InterlockedAnd64_rel(__int64 volatile *_Value, __int64 _Mask); -#endif -/*----------------------------------------------------------------------------*\ -|* Bit Counting and Testing -\*----------------------------------------------------------------------------*/ -#if defined(__arm__) || defined(__aarch64__) -unsigned char _interlockedbittestandset_acq(long volatile *_BitBase, - long _BitPos); -unsigned char _interlockedbittestandset_nf(long volatile *_BitBase, - long _BitPos); -unsigned char _interlockedbittestandset_rel(long volatile *_BitBase, - long _BitPos); -unsigned char _interlockedbittestandreset_acq(long volatile *_BitBase, - long _BitPos); -unsigned char _interlockedbittestandreset_nf(long volatile *_BitBase, - long _BitPos); -unsigned char _interlockedbittestandreset_rel(long volatile *_BitBase, - long _BitPos); -#endif -/*----------------------------------------------------------------------------*\ -|* Interlocked Or -\*----------------------------------------------------------------------------*/ -#if defined(__arm__) || defined(__aarch64__) -char _InterlockedOr8_acq(char volatile *_Value, char _Mask); -char _InterlockedOr8_nf(char volatile *_Value, char _Mask); -char _InterlockedOr8_rel(char volatile *_Value, char _Mask); -short _InterlockedOr16_acq(short volatile *_Value, short _Mask); -short _InterlockedOr16_nf(short volatile *_Value, short _Mask); -short _InterlockedOr16_rel(short volatile *_Value, short _Mask); -long _InterlockedOr_acq(long volatile *_Value, long _Mask); -long _InterlockedOr_nf(long volatile *_Value, long _Mask); -long _InterlockedOr_rel(long volatile *_Value, long _Mask); -__int64 _InterlockedOr64_acq(__int64 volatile *_Value, __int64 _Mask); -__int64 _InterlockedOr64_nf(__int64 volatile *_Value, __int64 _Mask); -__int64 _InterlockedOr64_rel(__int64 volatile *_Value, __int64 _Mask); -#endif -/*----------------------------------------------------------------------------*\ -|* Interlocked Xor -\*----------------------------------------------------------------------------*/ -#if defined(__arm__) || defined(__aarch64__) -char _InterlockedXor8_acq(char volatile *_Value, char _Mask); -char _InterlockedXor8_nf(char volatile *_Value, char _Mask); -char _InterlockedXor8_rel(char volatile *_Value, char _Mask); -short _InterlockedXor16_acq(short volatile *_Value, short _Mask); -short _InterlockedXor16_nf(short volatile *_Value, short _Mask); -short _InterlockedXor16_rel(short volatile *_Value, short _Mask); -long _InterlockedXor_acq(long volatile *_Value, long _Mask); -long _InterlockedXor_nf(long volatile *_Value, long _Mask); -long _InterlockedXor_rel(long volatile *_Value, long _Mask); -__int64 _InterlockedXor64_acq(__int64 volatile *_Value, __int64 _Mask); -__int64 _InterlockedXor64_nf(__int64 volatile *_Value, __int64 _Mask); -__int64 _InterlockedXor64_rel(__int64 volatile *_Value, __int64 _Mask); -#endif -/*----------------------------------------------------------------------------*\ -|* Interlocked Exchange -\*----------------------------------------------------------------------------*/ -#if defined(__arm__) || defined(__aarch64__) -char _InterlockedExchange8_acq(char volatile *_Target, char _Value); -char _InterlockedExchange8_nf(char volatile *_Target, char _Value); -char _InterlockedExchange8_rel(char volatile *_Target, char _Value); -short _InterlockedExchange16_acq(short volatile *_Target, short _Value); -short _InterlockedExchange16_nf(short volatile *_Target, short _Value); -short _InterlockedExchange16_rel(short volatile *_Target, short _Value); -long _InterlockedExchange_acq(long volatile *_Target, long _Value); -long _InterlockedExchange_nf(long volatile *_Target, long _Value); -long _InterlockedExchange_rel(long volatile *_Target, long _Value); -__int64 _InterlockedExchange64_acq(__int64 volatile *_Target, __int64 _Value); -__int64 _InterlockedExchange64_nf(__int64 volatile *_Target, __int64 _Value); -__int64 _InterlockedExchange64_rel(__int64 volatile *_Target, __int64 _Value); -#endif -/*----------------------------------------------------------------------------*\ -|* Interlocked Compare Exchange -\*----------------------------------------------------------------------------*/ -#if defined(__arm__) || defined(__aarch64__) -char _InterlockedCompareExchange8_acq(char volatile *_Destination, - char _Exchange, char _Comparand); -char _InterlockedCompareExchange8_nf(char volatile *_Destination, - char _Exchange, char _Comparand); -char _InterlockedCompareExchange8_rel(char volatile *_Destination, - char _Exchange, char _Comparand); -short _InterlockedCompareExchange16_acq(short volatile *_Destination, - short _Exchange, short _Comparand); -short _InterlockedCompareExchange16_nf(short volatile *_Destination, - short _Exchange, short _Comparand); -short _InterlockedCompareExchange16_rel(short volatile *_Destination, - short _Exchange, short _Comparand); -long _InterlockedCompareExchange_acq(long volatile *_Destination, - long _Exchange, long _Comparand); -long _InterlockedCompareExchange_nf(long volatile *_Destination, - long _Exchange, long _Comparand); -long _InterlockedCompareExchange_rel(long volatile *_Destination, - long _Exchange, long _Comparand); -__int64 _InterlockedCompareExchange64_acq(__int64 volatile *_Destination, - __int64 _Exchange, __int64 _Comparand); -__int64 _InterlockedCompareExchange64_nf(__int64 volatile *_Destination, - __int64 _Exchange, __int64 _Comparand); -__int64 _InterlockedCompareExchange64_rel(__int64 volatile *_Destination, - __int64 _Exchange, __int64 _Comparand); -#endif -#if defined(__x86_64__) || defined(__aarch64__) -unsigned char _InterlockedCompareExchange128(__int64 volatile *_Destination, - __int64 _ExchangeHigh, - __int64 _ExchangeLow, - __int64 *_ComparandResult); -#endif -#if defined(__aarch64__) -unsigned char _InterlockedCompareExchange128_acq(__int64 volatile *_Destination, - __int64 _ExchangeHigh, - __int64 _ExchangeLow, - __int64 *_ComparandResult); -unsigned char _InterlockedCompareExchange128_nf(__int64 volatile *_Destination, - __int64 _ExchangeHigh, - __int64 _ExchangeLow, - __int64 *_ComparandResult); -unsigned char _InterlockedCompareExchange128_rel(__int64 volatile *_Destination, - __int64 _ExchangeHigh, - __int64 _ExchangeLow, - __int64 *_ComparandResult); -#endif - /*----------------------------------------------------------------------------*\ |* movs, stos \*----------------------------------------------------------------------------*/ @@ -583,8 +374,6 @@ unsigned int _CountLeadingOnes(unsigned long); unsigned int _CountLeadingOnes64(unsigned __int64); unsigned int _CountLeadingSigns(long); unsigned int _CountLeadingSigns64(__int64); -unsigned int _CountLeadingZeros(unsigned long); -unsigned int _CountLeadingZeros64(unsigned _int64); unsigned int _CountOneBits(unsigned long); unsigned int _CountOneBits64(unsigned __int64); diff --git a/clang/lib/Headers/intrin0.h b/clang/lib/Headers/intrin0.h new file mode 100644 index 000000000000..31f362ec84d5 --- /dev/null +++ b/clang/lib/Headers/intrin0.h @@ -0,0 +1,247 @@ +/* ===-------- intrin.h ---------------------------------------------------=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===-----------------------------------------------------------------------=== + */ + +/* Only include this if we're compiling for the windows platform. */ +#ifndef _MSC_VER +#include_next <intrin0.h> +#else + +#ifndef __INTRIN0_H +#define __INTRIN0_H + +#ifdef __x86_64__ +#include <adcintrin.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask); +unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask); +void _ReadWriteBarrier(void); + +#if defined(__aarch64__) +unsigned int _CountLeadingZeros(unsigned long); +unsigned int _CountLeadingZeros64(unsigned _int64); +unsigned char _InterlockedCompareExchange128_acq(__int64 volatile *_Destination, + __int64 _ExchangeHigh, + __int64 _ExchangeLow, + __int64 *_ComparandResult); +unsigned char _InterlockedCompareExchange128_nf(__int64 volatile *_Destination, + __int64 _ExchangeHigh, + __int64 _ExchangeLow, + __int64 *_ComparandResult); +unsigned char _InterlockedCompareExchange128_rel(__int64 volatile *_Destination, + __int64 _ExchangeHigh, + __int64 _ExchangeLow, + __int64 *_ComparandResult); +#endif + +#ifdef __x86_64__ +unsigned __int64 _umul128(unsigned __int64, unsigned __int64, + unsigned __int64 *); +unsigned __int64 __shiftleft128(unsigned __int64 _LowPart, + unsigned __int64 _HighPart, + unsigned char _Shift); +unsigned __int64 __shiftright128(unsigned __int64 _LowPart, + unsigned __int64 _HighPart, + unsigned char _Shift); +#endif + +#if defined(__x86_64__) || defined(__i386__) +void _mm_pause(void); +#endif + +#if defined(__x86_64__) || defined(__aarch64__) +unsigned char _InterlockedCompareExchange128(__int64 volatile *_Destination, + __int64 _ExchangeHigh, + __int64 _ExchangeLow, + __int64 *_ComparandResult); +#endif + +#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) +unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask); +unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask); +#endif + +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \ + defined(__aarch64__) +__int64 _InterlockedDecrement64(__int64 volatile *_Addend); +__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value); +__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value); +__int64 _InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value); +__int64 _InterlockedIncrement64(__int64 volatile *_Addend); +__int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask); +__int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask); +__int64 _InterlockedAnd64(__int64 volatile *_Value, __int64 _Mask); +#endif + +#if defined(__arm__) || defined(__aarch64__) +/*----------------------------------------------------------------------------*\ +|* Interlocked Exchange Add +\*----------------------------------------------------------------------------*/ +char _InterlockedExchangeAdd8_acq(char volatile *_Addend, char _Value); +char _InterlockedExchangeAdd8_nf(char volatile *_Addend, char _Value); +char _InterlockedExchangeAdd8_rel(char volatile *_Addend, char _Value); +short _InterlockedExchangeAdd16_acq(short volatile *_Addend, short _Value); +short _InterlockedExchangeAdd16_nf(short volatile *_Addend, short _Value); +short _InterlockedExchangeAdd16_rel(short volatile *_Addend, short _Value); +long _InterlockedExchangeAdd_acq(long volatile *_Addend, long _Value); +long _InterlockedExchangeAdd_nf(long volatile *_Addend, long _Value); +long _InterlockedExchangeAdd_rel(long volatile *_Addend, long _Value); +__int64 _InterlockedExchangeAdd64_acq(__int64 volatile *_Addend, + __int64 _Value); +__int64 _InterlockedExchangeAdd64_nf(__int64 volatile *_Addend, __int64 _Value); +__int64 _InterlockedExchangeAdd64_rel(__int64 volatile *_Addend, + __int64 _Value); + +/*----------------------------------------------------------------------------*\ +|* Interlocked Increment +\*----------------------------------------------------------------------------*/ +short _InterlockedIncrement16_acq(short volatile *_Value); +short _InterlockedIncrement16_nf(short volatile *_Value); +short _InterlockedIncrement16_rel(short volatile *_Value); +long _InterlockedIncrement_acq(long volatile *_Value); +long _InterlockedIncrement_nf(long volatile *_Value); +long _InterlockedIncrement_rel(long volatile *_Value); +__int64 _InterlockedIncrement64_acq(__int64 volatile *_Value); +__int64 _InterlockedIncrement64_nf(__int64 volatile *_Value); +__int64 _InterlockedIncrement64_rel(__int64 volatile *_Value); + +/*----------------------------------------------------------------------------*\ +|* Interlocked Decrement +\*----------------------------------------------------------------------------*/ +short _InterlockedDecrement16_acq(short volatile *_Value); +short _InterlockedDecrement16_nf(short volatile *_Value); +short _InterlockedDecrement16_rel(short volatile *_Value); +long _InterlockedDecrement_acq(long volatile *_Value); +long _InterlockedDecrement_nf(long volatile *_Value); +long _InterlockedDecrement_rel(long volatile *_Value); +__int64 _InterlockedDecrement64_acq(__int64 volatile *_Value); +__int64 _InterlockedDecrement64_nf(__int64 volatile *_Value); +__int64 _InterlockedDecrement64_rel(__int64 volatile *_Value); + +/*----------------------------------------------------------------------------*\ +|* Interlocked And +\*----------------------------------------------------------------------------*/ +char _InterlockedAnd8_acq(char volatile *_Value, char _Mask); +char _InterlockedAnd8_nf(char volatile *_Value, char _Mask); +char _InterlockedAnd8_rel(char volatile *_Value, char _Mask); +short _InterlockedAnd16_acq(short volatile *_Value, short _Mask); +short _InterlockedAnd16_nf(short volatile *_Value, short _Mask); +short _InterlockedAnd16_rel(short volatile *_Value, short _Mask); +long _InterlockedAnd_acq(long volatile *_Value, long _Mask); +long _InterlockedAnd_nf(long volatile *_Value, long _Mask); +long _InterlockedAnd_rel(long volatile *_Value, long _Mask); +__int64 _InterlockedAnd64_acq(__int64 volatile *_Value, __int64 _Mask); +__int64 _InterlockedAnd64_nf(__int64 volatile *_Value, __int64 _Mask); +__int64 _InterlockedAnd64_rel(__int64 volatile *_Value, __int64 _Mask); + +/*----------------------------------------------------------------------------*\ +|* Bit Counting and Testing +\*----------------------------------------------------------------------------*/ +unsigned char _interlockedbittestandset_acq(long volatile *_BitBase, + long _BitPos); +unsigned char _interlockedbittestandset_nf(long volatile *_BitBase, + long _BitPos); +unsigned char _interlockedbittestandset_rel(long volatile *_BitBase, + long _BitPos); +unsigned char _interlockedbittestandreset_acq(long volatile *_BitBase, + long _BitPos); +unsigned char _interlockedbittestandreset_nf(long volatile *_BitBase, + long _BitPos); +unsigned char _interlockedbittestandreset_rel(long volatile *_BitBase, + long _BitPos); + +/*----------------------------------------------------------------------------*\ +|* Interlocked Or +\*----------------------------------------------------------------------------*/ +char _InterlockedOr8_acq(char volatile *_Value, char _Mask); +char _InterlockedOr8_nf(char volatile *_Value, char _Mask); +char _InterlockedOr8_rel(char volatile *_Value, char _Mask); +short _InterlockedOr16_acq(short volatile *_Value, short _Mask); +short _InterlockedOr16_nf(short volatile *_Value, short _Mask); +short _InterlockedOr16_rel(short volatile *_Value, short _Mask); +long _InterlockedOr_acq(long volatile *_Value, long _Mask); +long _InterlockedOr_nf(long volatile *_Value, long _Mask); +long _InterlockedOr_rel(long volatile *_Value, long _Mask); +__int64 _InterlockedOr64_acq(__int64 volatile *_Value, __int64 _Mask); +__int64 _InterlockedOr64_nf(__int64 volatile *_Value, __int64 _Mask); +__int64 _InterlockedOr64_rel(__int64 volatile *_Value, __int64 _Mask); + +/*----------------------------------------------------------------------------*\ +|* Interlocked Xor +\*----------------------------------------------------------------------------*/ +char _InterlockedXor8_acq(char volatile *_Value, char _Mask); +char _InterlockedXor8_nf(char volatile *_Value, char _Mask); +char _InterlockedXor8_rel(char volatile *_Value, char _Mask); +short _InterlockedXor16_acq(short volatile *_Value, short _Mask); +short _InterlockedXor16_nf(short volatile *_Value, short _Mask); +short _InterlockedXor16_rel(short volatile *_Value, short _Mask); +long _InterlockedXor_acq(long volatile *_Value, long _Mask); +long _InterlockedXor_nf(long volatile *_Value, long _Mask); +long _InterlockedXor_rel(long volatile *_Value, long _Mask); +__int64 _InterlockedXor64_acq(__int64 volatile *_Value, __int64 _Mask); +__int64 _InterlockedXor64_nf(__int64 volatile *_Value, __int64 _Mask); +__int64 _InterlockedXor64_rel(__int64 volatile *_Value, __int64 _Mask); + +/*----------------------------------------------------------------------------*\ +|* Interlocked Exchange +\*----------------------------------------------------------------------------*/ +char _InterlockedExchange8_acq(char volatile *_Target, char _Value); +char _InterlockedExchange8_nf(char volatile *_Target, char _Value); +char _InterlockedExchange8_rel(char volatile *_Target, char _Value); +short _InterlockedExchange16_acq(short volatile *_Target, short _Value); +short _InterlockedExchange16_nf(short volatile *_Target, short _Value); +short _InterlockedExchange16_rel(short volatile *_Target, short _Value); +long _InterlockedExchange_acq(long volatile *_Target, long _Value); +long _InterlockedExchange_nf(long volatile *_Target, long _Value); +long _InterlockedExchange_rel(long volatile *_Target, long _Value); +__int64 _InterlockedExchange64_acq(__int64 volatile *_Target, __int64 _Value); +__int64 _InterlockedExchange64_nf(__int64 volatile *_Target, __int64 _Value); +__int64 _InterlockedExchange64_rel(__int64 volatile *_Target, __int64 _Value); + +/*----------------------------------------------------------------------------*\ +|* Interlocked Compare Exchange +\*----------------------------------------------------------------------------*/ +char _InterlockedCompareExchange8_acq(char volatile *_Destination, + char _Exchange, char _Comparand); +char _InterlockedCompareExchange8_nf(char volatile *_Destination, + char _Exchange, char _Comparand); +char _InterlockedCompareExchange8_rel(char volatile *_Destination, + char _Exchange, char _Comparand); +short _InterlockedCompareExchange16_acq(short volatile *_Destination, + short _Exchange, short _Comparand); +short _InterlockedCompareExchange16_nf(short volatile *_Destination, + short _Exchange, short _Comparand); +short _InterlockedCompareExchange16_rel(short volatile *_Destination, + short _Exchange, short _Comparand); +long _InterlockedCompareExchange_acq(long volatile *_Destination, + long _Exchange, long _Comparand); +long _InterlockedCompareExchange_nf(long volatile *_Destination, long _Exchange, + long _Comparand); +long _InterlockedCompareExchange_rel(long volatile *_Destination, + long _Exchange, long _Comparand); +__int64 _InterlockedCompareExchange64_acq(__int64 volatile *_Destination, + __int64 _Exchange, + __int64 _Comparand); +__int64 _InterlockedCompareExchange64_nf(__int64 volatile *_Destination, + __int64 _Exchange, __int64 _Comparand); +__int64 _InterlockedCompareExchange64_rel(__int64 volatile *_Destination, + __int64 _Exchange, + __int64 _Comparand); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __INTRIN0_H */ +#endif /* _MSC_VER */ diff --git a/clang/lib/Headers/keylockerintrin.h b/clang/lib/Headers/keylockerintrin.h index 1994ac42070a..f76e91b4d4b3 100644 --- a/clang/lib/Headers/keylockerintrin.h +++ b/clang/lib/Headers/keylockerintrin.h @@ -28,8 +28,7 @@ #ifndef _KEYLOCKERINTRIN_H #define _KEYLOCKERINTRIN_H -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__KL__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__KL__) /* Define the default attributes for the functions in this file. */ #define __DEFAULT_FN_ATTRS \ @@ -327,11 +326,9 @@ _mm_aesdec256kl_u8(__m128i* __odata, __m128i __idata, const void *__h) { #undef __DEFAULT_FN_ATTRS -#endif /* !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) \ - || defined(__KL__) */ +#endif /* !defined(__SCE__ || __has_feature(modules) || defined(__KL__) */ -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__WIDEKL__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__WIDEKL__) /* Define the default attributes for the functions in this file. */ #define __DEFAULT_FN_ATTRS \ @@ -524,7 +521,7 @@ _mm_aesdecwide256kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* #undef __DEFAULT_FN_ATTRS -#endif /* !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) \ - || defined(__WIDEKL__) */ +#endif /* !defined(__SCE__) || __has_feature(modules) || defined(__WIDEKL__) \ + */ #endif /* _KEYLOCKERINTRIN_H */ diff --git a/clang/lib/Headers/x86gprintrin.h b/clang/lib/Headers/x86gprintrin.h index ed141879fbc7..3d5cc606d7e6 100644 --- a/clang/lib/Headers/x86gprintrin.h +++ b/clang/lib/Headers/x86gprintrin.h @@ -10,38 +10,31 @@ #ifndef __X86GPRINTRIN_H #define __X86GPRINTRIN_H -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__HRESET__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__HRESET__) #include <hresetintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__UINTR__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__UINTR__) #include <uintrintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__USERMSR__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__USERMSR__) #include <usermsrintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__CRC32__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__CRC32__) #include <crc32intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__PRFCHI__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__PRFCHI__) #include <prfchiintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__RAOINT__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__RAOINT__) #include <raointintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__CMPCCXADD__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__CMPCCXADD__) #include <cmpccxaddintrin.h> #endif diff --git a/clang/lib/Headers/x86intrin.h b/clang/lib/Headers/x86intrin.h index 450fd008dab9..c20bfbb8fe46 100644 --- a/clang/lib/Headers/x86intrin.h +++ b/clang/lib/Headers/x86intrin.h @@ -14,53 +14,43 @@ #include <immintrin.h> -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__3dNOW__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__3dNOW__) #include <mm3dnow.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__PRFCHW__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__PRFCHW__) #include <prfchwintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__SSE4A__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__SSE4A__) #include <ammintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__FMA4__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__FMA4__) #include <fma4intrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__XOP__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__XOP__) #include <xopintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__TBM__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__TBM__) #include <tbmintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__LWP__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__LWP__) #include <lwpintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__MWAITX__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__MWAITX__) #include <mwaitxintrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__CLZERO__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__CLZERO__) #include <clzerointrin.h> #endif -#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ - defined(__RDPRU__) +#if !defined(__SCE__) || __has_feature(modules) || defined(__RDPRU__) #include <rdpruintrin.h> #endif diff --git a/clang/lib/Headers/yvals_core.h b/clang/lib/Headers/yvals_core.h new file mode 100644 index 000000000000..5ee194a3e5f5 --- /dev/null +++ b/clang/lib/Headers/yvals_core.h @@ -0,0 +1,25 @@ +//===----- yvals_core.h - Internal MSVC STL core header -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// Only include this if we are aiming for MSVC compatibility. +#ifndef _MSC_VER +#include_next <yvals_core.h> +#else + +#ifndef __clang_yvals_core_h +#define __clang_yvals_core_h + +#include_next <yvals_core.h> + +#ifdef _STL_INTRIN_HEADER +#undef _STL_INTRIN_HEADER +#define _STL_INTRIN_HEADER <intrin0.h> +#endif + +#endif +#endif -- GitLab From 4e612a62bd0f3c4f182ecd7652f92d288fc06894 Mon Sep 17 00:00:00 2001 From: LLVM GN Syncbot <llvmgnsyncbot@gmail.com> Date: Tue, 19 Mar 2024 12:33:31 +0000 Subject: [PATCH 063/307] [gn build] Port afec08ef9f10 --- llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn index 93976d3bd5ef..25fcdc4d0015 100644 --- a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn @@ -205,6 +205,7 @@ copy("Headers") { "ia32intrin.h", "immintrin.h", "intrin.h", + "intrin0.h", "inttypes.h", "invpcidintrin.h", "iso646.h", @@ -310,6 +311,7 @@ copy("Headers") { "xsaveoptintrin.h", "xsavesintrin.h", "xtestintrin.h", + "yvals_core.h", ] outputs = [ "$clang_resource_dir/include/{{source_target_relative}}" ] } -- GitLab From 97fc16e14b16bd44dee1e1bf7211b4688b67027d Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <llvm-dev@redking.me.uk> Date: Tue, 19 Mar 2024 12:19:30 +0000 Subject: [PATCH 064/307] [DAG] visitEXTRACT_VECTOR_ELT - share the same SDLoc instead of recreating it. NFC. --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d6d0bf02c639..cce765c7c310 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -22443,17 +22443,16 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) { // -> extract_vector_elt b, 0 // extract_vector_elt (concat_vectors v2i16:a, v2i16:b), 3 // -> extract_vector_elt b, 1 - SDLoc SL(N); EVT ConcatVT = VecOp.getOperand(0).getValueType(); unsigned ConcatNumElts = ConcatVT.getVectorNumElements(); - SDValue NewIdx = DAG.getConstant(Elt % ConcatNumElts, SL, + SDValue NewIdx = DAG.getConstant(Elt % ConcatNumElts, DL, Index.getValueType()); SDValue ConcatOp = VecOp.getOperand(Elt / ConcatNumElts); - SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, + SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ConcatVT.getVectorElementType(), ConcatOp, NewIdx); - return DAG.getNode(ISD::BITCAST, SL, ScalarVT, Elt); + return DAG.getNode(ISD::BITCAST, DL, ScalarVT, Elt); } // Make sure we found a non-volatile load and the extractelement is -- GitLab From 9f433bf8cada5855669b43ff70263a1b61128ca4 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <llvm-dev@redking.me.uk> Date: Tue, 19 Mar 2024 12:39:01 +0000 Subject: [PATCH 065/307] [X86] Add PAVG(0,x) test coverage for PR #85581 --- llvm/test/CodeGen/X86/combine-pavg.ll | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/llvm/test/CodeGen/X86/combine-pavg.ll b/llvm/test/CodeGen/X86/combine-pavg.ll index 0743592f3ca1..9bb7fec7eeac 100644 --- a/llvm/test/CodeGen/X86/combine-pavg.ll +++ b/llvm/test/CodeGen/X86/combine-pavg.ll @@ -18,6 +18,22 @@ define <16 x i8> @combine_pavgb_self(<16 x i8> %a0) { ret <16 x i8> %1 } +define <16 x i8> @combine_pavgb_zero(<16 x i8> %a0) { +; SSE-LABEL: combine_pavgb_zero: +; SSE: # %bb.0: +; SSE-NEXT: pxor %xmm1, %xmm1 +; SSE-NEXT: pavgb %xmm1, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: combine_pavgb_zero: +; AVX: # %bb.0: +; AVX-NEXT: vpxor %xmm1, %xmm1, %xmm1 +; AVX-NEXT: vpavgb %xmm1, %xmm0, %xmm0 +; AVX-NEXT: retq + %1 = call <16 x i8> @llvm.x86.sse2.pavg.b(<16 x i8> zeroinitializer, <16 x i8> %a0) + ret <16 x i8> %1 +} + define <16 x i8> @combine_pavgw_knownbits(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> %a2, <8 x i16> %a3) { ; SSE-LABEL: combine_pavgw_knownbits: ; SSE: # %bb.0: -- GitLab From 9a3ece232ced907f87ed0d5846a57f6d9cbc9832 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Tue, 19 Mar 2024 13:48:10 +0100 Subject: [PATCH 066/307] [mlir][sparse] Fix the calling convention of __truncsfbf2 on windows x64 It also wants us to return the value in XMM0. --- mlir/lib/ExecutionEngine/Float16bits.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/lib/ExecutionEngine/Float16bits.cpp b/mlir/lib/ExecutionEngine/Float16bits.cpp index 841610e3c161..e5b4f18dd644 100644 --- a/mlir/lib/ExecutionEngine/Float16bits.cpp +++ b/mlir/lib/ExecutionEngine/Float16bits.cpp @@ -165,7 +165,7 @@ bool operator==(const bf16 &f1, const bf16 &f2) { return f1.bits == f2.bits; } #endif #endif -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(_M_X64) // On x86 bfloat16 is passed in SSE registers. Since both float and __bf16 // are passed in the same register we can use the wider type and careful casting // to conform to x86_64 psABI. This only works with the assumption that we're -- GitLab From ef520ca6b18cf65fc7a13fcad1534f1d70332a88 Mon Sep 17 00:00:00 2001 From: Luke Lau <luke@igalia.com> Date: Tue, 19 Mar 2024 20:47:08 +0800 Subject: [PATCH 067/307] Revert "[RISCV] Recursively split concat_vector into smaller LMULs (#83035)" This reverts commit c59129a7c79448837d665de8f2743ad4b14666f6. This causes regressions in some x264 workloads like pixel_var_8x8 due to it interfering with the strided load combine. Reverting so I can try to rework it as a lowering instead. --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 60 +- .../CodeGen/RISCV/rvv/active_lane_mask.ll | 91 +- .../RISCV/rvv/combine-store-extract-crash.ll | 4 +- .../CodeGen/RISCV/rvv/extract-subvector.ll | 3 +- .../RISCV/rvv/fixed-vectors-shuffle-concat.ll | 307 +++-- .../rvv/fixed-vectors-strided-load-combine.ll | 126 +- .../CodeGen/RISCV/rvv/fpclamptosat_vec.ll | 1066 +++++++---------- llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll | 13 +- llvm/test/CodeGen/RISCV/rvv/pr63596.ll | 37 +- 9 files changed, 781 insertions(+), 926 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 105587f0810b..c3d1416ed518 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -15323,62 +15323,13 @@ static SDValue performINSERT_VECTOR_ELTCombine(SDNode *N, SelectionDAG &DAG, return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, ConcatOps); } -// Recursively split up concat_vectors with more than 2 operands: -// -// concat_vector op1, op2, op3, op4 -// -> -// concat_vector (concat_vector op1, op2), (concat_vector op3, op4) -// -// This reduces the length of the chain of vslideups and allows us to perform -// the vslideups at a smaller LMUL, limited to MF2. -// -// We do this as a DAG combine rather than during lowering so that any undef -// operands can get combined away. -static SDValue -performCONCAT_VECTORSSplitCombine(SDNode *N, SelectionDAG &DAG, - const RISCVTargetLowering &TLI) { - SDLoc DL(N); - - if (N->getNumOperands() <= 2) - return SDValue(); - - if (!TLI.isTypeLegal(N->getValueType(0))) - return SDValue(); - MVT VT = N->getSimpleValueType(0); - - // Don't split any further than MF2. - MVT ContainerVT = VT; - if (VT.isFixedLengthVector()) - ContainerVT = getContainerForFixedLengthVector(DAG, VT, TLI.getSubtarget()); - if (ContainerVT.bitsLT(getLMUL1VT(ContainerVT))) - return SDValue(); - - MVT HalfVT = VT.getHalfNumVectorElementsVT(); - assert(isPowerOf2_32(N->getNumOperands())); - size_t HalfNumOps = N->getNumOperands() / 2; - SDValue Lo = DAG.getNode(ISD::CONCAT_VECTORS, DL, HalfVT, - N->ops().take_front(HalfNumOps)); - SDValue Hi = DAG.getNode(ISD::CONCAT_VECTORS, DL, HalfVT, - N->ops().drop_front(HalfNumOps)); - - // Lower to an insert_subvector directly so the concat_vectors don't get - // recombined. - SDValue Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, DAG.getUNDEF(VT), Lo, - DAG.getVectorIdxConstant(0, DL)); - Vec = DAG.getNode( - ISD::INSERT_SUBVECTOR, DL, VT, Vec, Hi, - DAG.getVectorIdxConstant(HalfVT.getVectorMinNumElements(), DL)); - return Vec; -} - // If we're concatenating a series of vector loads like // concat_vectors (load v4i8, p+0), (load v4i8, p+n), (load v4i8, p+n*2) ... // Then we can turn this into a strided load by widening the vector elements // vlse32 p, stride=n -static SDValue -performCONCAT_VECTORSStridedLoadCombine(SDNode *N, SelectionDAG &DAG, - const RISCVSubtarget &Subtarget, - const RISCVTargetLowering &TLI) { +static SDValue performCONCAT_VECTORSCombine(SDNode *N, SelectionDAG &DAG, + const RISCVSubtarget &Subtarget, + const RISCVTargetLowering &TLI) { SDLoc DL(N); EVT VT = N->getValueType(0); @@ -16483,10 +16434,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N, return V; break; case ISD::CONCAT_VECTORS: - if (SDValue V = - performCONCAT_VECTORSStridedLoadCombine(N, DAG, Subtarget, *this)) - return V; - if (SDValue V = performCONCAT_VECTORSSplitCombine(N, DAG, *this)) + if (SDValue V = performCONCAT_VECTORSCombine(N, DAG, Subtarget, *this)) return V; break; case ISD::INSERT_VECTOR_ELT: diff --git a/llvm/test/CodeGen/RISCV/rvv/active_lane_mask.ll b/llvm/test/CodeGen/RISCV/rvv/active_lane_mask.ll index 139579b3d2a3..87d95d7596d4 100644 --- a/llvm/test/CodeGen/RISCV/rvv/active_lane_mask.ll +++ b/llvm/test/CodeGen/RISCV/rvv/active_lane_mask.ll @@ -161,71 +161,72 @@ define <64 x i1> @fv64(ptr %p, i64 %index, i64 %tc) { define <128 x i1> @fv128(ptr %p, i64 %index, i64 %tc) { ; CHECK-LABEL: fv128: ; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, ma ; CHECK-NEXT: lui a0, %hi(.LCPI10_0) ; CHECK-NEXT: addi a0, a0, %lo(.LCPI10_0) -; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, ma ; CHECK-NEXT: vle8.v v8, (a0) +; CHECK-NEXT: vid.v v16 +; CHECK-NEXT: vsaddu.vx v16, v16, a1 +; CHECK-NEXT: vmsltu.vx v0, v16, a2 +; CHECK-NEXT: vsext.vf8 v16, v8 +; CHECK-NEXT: vsaddu.vx v8, v16, a1 +; CHECK-NEXT: vmsltu.vx v16, v8, a2 +; CHECK-NEXT: vsetivli zero, 4, e8, m1, tu, ma +; CHECK-NEXT: vslideup.vi v0, v16, 2 ; CHECK-NEXT: lui a0, %hi(.LCPI10_1) ; CHECK-NEXT: addi a0, a0, %lo(.LCPI10_1) -; CHECK-NEXT: vle8.v v9, (a0) +; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, ma +; CHECK-NEXT: vle8.v v8, (a0) ; CHECK-NEXT: vsext.vf8 v16, v8 -; CHECK-NEXT: vsaddu.vx v16, v16, a1 -; CHECK-NEXT: vmsltu.vx v10, v16, a2 -; CHECK-NEXT: vsext.vf8 v16, v9 -; CHECK-NEXT: vsaddu.vx v16, v16, a1 -; CHECK-NEXT: vmsltu.vx v8, v16, a2 -; CHECK-NEXT: vsetivli zero, 4, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vi v8, v10, 2 +; CHECK-NEXT: vsaddu.vx v8, v16, a1 +; CHECK-NEXT: vmsltu.vx v16, v8, a2 +; CHECK-NEXT: vsetivli zero, 6, e8, m1, tu, ma +; CHECK-NEXT: vslideup.vi v0, v16, 4 ; CHECK-NEXT: lui a0, %hi(.LCPI10_2) ; CHECK-NEXT: addi a0, a0, %lo(.LCPI10_2) ; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, ma -; CHECK-NEXT: vle8.v v9, (a0) -; CHECK-NEXT: vsext.vf8 v16, v9 -; CHECK-NEXT: vsaddu.vx v16, v16, a1 -; CHECK-NEXT: vmsltu.vx v9, v16, a2 -; CHECK-NEXT: vsetivli zero, 6, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vi v8, v9, 4 +; CHECK-NEXT: vle8.v v8, (a0) +; CHECK-NEXT: vsext.vf8 v16, v8 +; CHECK-NEXT: vsaddu.vx v8, v16, a1 +; CHECK-NEXT: vmsltu.vx v16, v8, a2 +; CHECK-NEXT: vsetivli zero, 8, e8, m1, tu, ma +; CHECK-NEXT: vslideup.vi v0, v16, 6 ; CHECK-NEXT: lui a0, %hi(.LCPI10_3) ; CHECK-NEXT: addi a0, a0, %lo(.LCPI10_3) ; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, ma -; CHECK-NEXT: vle8.v v9, (a0) -; CHECK-NEXT: vsext.vf8 v16, v9 -; CHECK-NEXT: vsaddu.vx v16, v16, a1 -; CHECK-NEXT: vmsltu.vx v9, v16, a2 -; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma -; CHECK-NEXT: vslideup.vi v8, v9, 6 -; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, ma +; CHECK-NEXT: vle8.v v8, (a0) +; CHECK-NEXT: vsext.vf8 v16, v8 +; CHECK-NEXT: vsaddu.vx v8, v16, a1 +; CHECK-NEXT: vmsltu.vx v16, v8, a2 +; CHECK-NEXT: vsetivli zero, 10, e8, m1, tu, ma +; CHECK-NEXT: vslideup.vi v0, v16, 8 ; CHECK-NEXT: lui a0, %hi(.LCPI10_4) ; CHECK-NEXT: addi a0, a0, %lo(.LCPI10_4) -; CHECK-NEXT: vle8.v v9, (a0) -; CHECK-NEXT: vid.v v16 -; CHECK-NEXT: vsaddu.vx v16, v16, a1 -; CHECK-NEXT: vmsltu.vx v0, v16, a2 -; CHECK-NEXT: vsext.vf8 v16, v9 -; CHECK-NEXT: vsaddu.vx v16, v16, a1 -; CHECK-NEXT: vmsltu.vx v9, v16, a2 -; CHECK-NEXT: vsetivli zero, 4, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vi v0, v9, 2 +; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, ma +; CHECK-NEXT: vle8.v v8, (a0) +; CHECK-NEXT: vsext.vf8 v16, v8 +; CHECK-NEXT: vsaddu.vx v8, v16, a1 +; CHECK-NEXT: vmsltu.vx v16, v8, a2 +; CHECK-NEXT: vsetivli zero, 12, e8, m1, tu, ma +; CHECK-NEXT: vslideup.vi v0, v16, 10 ; CHECK-NEXT: lui a0, %hi(.LCPI10_5) ; CHECK-NEXT: addi a0, a0, %lo(.LCPI10_5) ; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, ma -; CHECK-NEXT: vle8.v v9, (a0) -; CHECK-NEXT: vsext.vf8 v16, v9 -; CHECK-NEXT: vsaddu.vx v16, v16, a1 -; CHECK-NEXT: vmsltu.vx v9, v16, a2 -; CHECK-NEXT: vsetivli zero, 6, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vi v0, v9, 4 +; CHECK-NEXT: vle8.v v8, (a0) +; CHECK-NEXT: vsext.vf8 v16, v8 +; CHECK-NEXT: vsaddu.vx v8, v16, a1 +; CHECK-NEXT: vmsltu.vx v16, v8, a2 +; CHECK-NEXT: vsetivli zero, 14, e8, m1, tu, ma +; CHECK-NEXT: vslideup.vi v0, v16, 12 ; CHECK-NEXT: lui a0, %hi(.LCPI10_6) ; CHECK-NEXT: addi a0, a0, %lo(.LCPI10_6) ; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, ma -; CHECK-NEXT: vle8.v v9, (a0) -; CHECK-NEXT: vsext.vf8 v16, v9 -; CHECK-NEXT: vsaddu.vx v16, v16, a1 -; CHECK-NEXT: vmsltu.vx v9, v16, a2 -; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma -; CHECK-NEXT: vslideup.vi v0, v9, 6 -; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma -; CHECK-NEXT: vslideup.vi v0, v8, 8 +; CHECK-NEXT: vle8.v v8, (a0) +; CHECK-NEXT: vsext.vf8 v16, v8 +; CHECK-NEXT: vsaddu.vx v8, v16, a1 +; CHECK-NEXT: vmsltu.vx v16, v8, a2 +; CHECK-NEXT: vsetvli zero, zero, e8, m1, ta, ma +; CHECK-NEXT: vslideup.vi v0, v16, 14 ; CHECK-NEXT: ret %mask = call <128 x i1> @llvm.get.active.lane.mask.v128i1.i64(i64 %index, i64 %tc) ret <128 x i1> %mask diff --git a/llvm/test/CodeGen/RISCV/rvv/combine-store-extract-crash.ll b/llvm/test/CodeGen/RISCV/rvv/combine-store-extract-crash.ll index ed434deea1a8..c64216180c2a 100644 --- a/llvm/test/CodeGen/RISCV/rvv/combine-store-extract-crash.ll +++ b/llvm/test/CodeGen/RISCV/rvv/combine-store-extract-crash.ll @@ -19,7 +19,7 @@ define void @test(ptr %ref_array, ptr %sad_array) { ; RV32-NEXT: th.swia a0, (a1), 4, 0 ; RV32-NEXT: vsetivli zero, 4, e8, mf4, ta, ma ; RV32-NEXT: vle8.v v10, (a3) -; RV32-NEXT: vsetivli zero, 8, e8, mf2, ta, ma +; RV32-NEXT: vsetivli zero, 8, e8, m1, tu, ma ; RV32-NEXT: vslideup.vi v10, v9, 4 ; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma ; RV32-NEXT: vzext.vf4 v12, v10 @@ -42,7 +42,7 @@ define void @test(ptr %ref_array, ptr %sad_array) { ; RV64-NEXT: th.swia a0, (a1), 4, 0 ; RV64-NEXT: vsetivli zero, 4, e8, mf4, ta, ma ; RV64-NEXT: vle8.v v10, (a3) -; RV64-NEXT: vsetivli zero, 8, e8, mf2, ta, ma +; RV64-NEXT: vsetivli zero, 8, e8, m1, tu, ma ; RV64-NEXT: vslideup.vi v10, v9, 4 ; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma ; RV64-NEXT: vzext.vf4 v12, v10 diff --git a/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll b/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll index e15e6452163b..76aa2b913c65 100644 --- a/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll +++ b/llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll @@ -469,8 +469,9 @@ define <vscale x 6 x half> @extract_nxv6f16_nxv12f16_6(<vscale x 12 x half> %in) ; CHECK: # %bb.0: ; CHECK-NEXT: csrr a0, vlenb ; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma +; CHECK-NEXT: vsetvli zero, a0, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vx v13, v10, a0 +; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vx v12, v9, a0 ; CHECK-NEXT: add a1, a0, a0 ; CHECK-NEXT: vsetvli zero, a1, e16, m1, ta, ma diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat.ll index 8474f95edd81..e5bef20fd9e2 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-concat.ll @@ -5,59 +5,6 @@ ; RUN: llc < %s -mtriple=riscv32 -mattr=+v -riscv-v-vector-bits-max=128 -verify-machineinstrs | FileCheck -check-prefixes=CHECK,VLS %s ; RUN: llc < %s -mtriple=riscv64 -mattr=+v -riscv-v-vector-bits-max=128 -verify-machineinstrs | FileCheck -check-prefixes=CHECK,VLS %s -define <8 x i16> @concat_2xv4i16(<4 x i16> %a, <4 x i16> %b) { -; CHECK-LABEL: concat_2xv4i16: -; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vi v8, v9, 4 -; CHECK-NEXT: ret - %ab = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> - ret <8 x i16> %ab -} - -define <8 x i16> @concat_4xv2i16(<2 x i16> %a, <2 x i16> %b, <2 x i16> %c, <2 x i16> %d) { -; CHECK-LABEL: concat_4xv2i16: -; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vi v10, v11, 2 -; CHECK-NEXT: vslideup.vi v8, v9, 2 -; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vi v8, v10, 4 -; CHECK-NEXT: ret - %ab = shufflevector <2 x i16> %a, <2 x i16> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 3> - %cd = shufflevector <2 x i16> %c, <2 x i16> %d, <4 x i32> <i32 0, i32 1, i32 2, i32 3> - %abcd = shufflevector <4 x i16> %ab, <4 x i16> %cd, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> - ret <8 x i16> %abcd -} - -define <8 x i16> @concat_8xv1i16(<1 x i16> %a, <1 x i16> %b, <1 x i16> %c, <1 x i16> %d, <1 x i16> %e, <1 x i16> %f, <1 x i16> %g, <1 x i16> %h) { -; CHECK-LABEL: concat_8xv1i16: -; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 2, e16, mf2, tu, ma -; CHECK-NEXT: vslideup.vi v12, v13, 1 -; CHECK-NEXT: vsetivli zero, 3, e16, mf2, tu, ma -; CHECK-NEXT: vslideup.vi v12, v14, 2 -; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vi v12, v15, 3 -; CHECK-NEXT: vsetivli zero, 2, e16, mf2, tu, ma -; CHECK-NEXT: vslideup.vi v8, v9, 1 -; CHECK-NEXT: vsetivli zero, 3, e16, mf2, tu, ma -; CHECK-NEXT: vslideup.vi v8, v10, 2 -; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vi v8, v11, 3 -; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vi v8, v12, 4 -; CHECK-NEXT: ret - %ab = shufflevector <1 x i16> %a, <1 x i16> %b, <2 x i32> <i32 0, i32 1> - %cd = shufflevector <1 x i16> %c, <1 x i16> %d, <2 x i32> <i32 0, i32 1> - %abcd = shufflevector <2 x i16> %ab, <2 x i16> %cd, <4 x i32> <i32 0, i32 1, i32 2, i32 3> - %ef = shufflevector <1 x i16> %e, <1 x i16> %f, <2 x i32> <i32 0, i32 1> - %gh = shufflevector <1 x i16> %g, <1 x i16> %h, <2 x i32> <i32 0, i32 1> - %efgh = shufflevector <2 x i16> %ef, <2 x i16> %gh, <4 x i32> <i32 0, i32 1, i32 2, i32 3> - %abcdefgh = shufflevector <4 x i16> %abcd, <4 x i16> %efgh, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> - ret <8 x i16> %abcdefgh -} - define <8 x i32> @concat_2xv4i32(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: concat_2xv4i32: ; CHECK: # %bb.0: @@ -72,11 +19,14 @@ define <8 x i32> @concat_2xv4i32(<4 x i32> %a, <4 x i32> %b) { define <8 x i32> @concat_4xv2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c, <2 x i32> %d) { ; CHECK-LABEL: concat_4xv2i32: ; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vi v10, v11, 2 -; CHECK-NEXT: vslideup.vi v8, v9, 2 -; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; CHECK-NEXT: vmv1r.v v12, v11 +; CHECK-NEXT: vmv1r.v v14, v9 +; CHECK-NEXT: vsetivli zero, 4, e32, m2, tu, ma +; CHECK-NEXT: vslideup.vi v8, v14, 2 +; CHECK-NEXT: vsetivli zero, 6, e32, m2, tu, ma ; CHECK-NEXT: vslideup.vi v8, v10, 4 +; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; CHECK-NEXT: vslideup.vi v8, v12, 6 ; CHECK-NEXT: ret %ab = shufflevector <2 x i32> %a, <2 x i32> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 3> %cd = shufflevector <2 x i32> %c, <2 x i32> %d, <4 x i32> <i32 0, i32 1, i32 2, i32 3> @@ -87,18 +37,24 @@ define <8 x i32> @concat_4xv2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c, <2 x define <8 x i32> @concat_8xv1i32(<1 x i32> %a, <1 x i32> %b, <1 x i32> %c, <1 x i32> %d, <1 x i32> %e, <1 x i32> %f, <1 x i32> %g, <1 x i32> %h) { ; CHECK-LABEL: concat_8xv1i32: ; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-NEXT: vslideup.vi v14, v15, 1 -; CHECK-NEXT: vslideup.vi v12, v13, 1 -; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vi v12, v14, 2 -; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-NEXT: vslideup.vi v10, v11, 1 -; CHECK-NEXT: vslideup.vi v8, v9, 1 -; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; CHECK-NEXT: vmv1r.v v16, v15 +; CHECK-NEXT: vmv1r.v v18, v13 +; CHECK-NEXT: vmv1r.v v20, v11 +; CHECK-NEXT: vmv1r.v v22, v9 +; CHECK-NEXT: vsetivli zero, 2, e32, m2, tu, ma +; CHECK-NEXT: vslideup.vi v8, v22, 1 +; CHECK-NEXT: vsetivli zero, 3, e32, m2, tu, ma ; CHECK-NEXT: vslideup.vi v8, v10, 2 -; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; CHECK-NEXT: vsetivli zero, 4, e32, m2, tu, ma +; CHECK-NEXT: vslideup.vi v8, v20, 3 +; CHECK-NEXT: vsetivli zero, 5, e32, m2, tu, ma ; CHECK-NEXT: vslideup.vi v8, v12, 4 +; CHECK-NEXT: vsetivli zero, 6, e32, m2, tu, ma +; CHECK-NEXT: vslideup.vi v8, v18, 5 +; CHECK-NEXT: vsetivli zero, 7, e32, m2, tu, ma +; CHECK-NEXT: vslideup.vi v8, v14, 6 +; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; CHECK-NEXT: vslideup.vi v8, v16, 7 ; CHECK-NEXT: ret %ab = shufflevector <1 x i32> %a, <1 x i32> %b, <2 x i32> <i32 0, i32 1> %cd = shufflevector <1 x i32> %c, <1 x i32> %d, <2 x i32> <i32 0, i32 1> @@ -124,14 +80,15 @@ define <16 x i32> @concat_2xv8i32(<8 x i32> %a, <8 x i32> %b) { define <16 x i32> @concat_4xv4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) { ; CHECK-LABEL: concat_4xv4i32: ; CHECK: # %bb.0: -; CHECK-NEXT: vmv1r.v v14, v11 -; CHECK-NEXT: vmv1r.v v12, v10 -; CHECK-NEXT: vmv1r.v v10, v9 -; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; CHECK-NEXT: vslideup.vi v12, v14, 4 -; CHECK-NEXT: vslideup.vi v8, v10, 4 +; CHECK-NEXT: vmv1r.v v12, v11 +; CHECK-NEXT: vmv1r.v v16, v10 +; CHECK-NEXT: vmv1r.v v20, v9 +; CHECK-NEXT: vsetivli zero, 8, e32, m4, tu, ma +; CHECK-NEXT: vslideup.vi v8, v20, 4 +; CHECK-NEXT: vsetivli zero, 12, e32, m4, tu, ma +; CHECK-NEXT: vslideup.vi v8, v16, 8 ; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma -; CHECK-NEXT: vslideup.vi v8, v12, 8 +; CHECK-NEXT: vslideup.vi v8, v12, 12 ; CHECK-NEXT: ret %ab = shufflevector <4 x i32> %a, <4 x i32> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> %cd = shufflevector <4 x i32> %c, <4 x i32> %d, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> @@ -142,18 +99,26 @@ define <16 x i32> @concat_4xv4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x define <16 x i32> @concat_8xv2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c, <2 x i32> %d, <2 x i32> %e, <2 x i32> %f, <2 x i32> %g, <2 x i32> %h) { ; CHECK-LABEL: concat_8xv2i32: ; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vi v14, v15, 2 -; CHECK-NEXT: vslideup.vi v12, v13, 2 -; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; CHECK-NEXT: vslideup.vi v12, v14, 4 -; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vi v10, v11, 2 -; CHECK-NEXT: vslideup.vi v8, v9, 2 -; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; CHECK-NEXT: vslideup.vi v8, v10, 4 -; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; CHECK-NEXT: vmv1r.v v16, v15 +; CHECK-NEXT: vmv1r.v v20, v14 +; CHECK-NEXT: vmv1r.v v24, v13 +; CHECK-NEXT: vmv1r.v v28, v11 +; CHECK-NEXT: vmv1r.v v4, v10 +; CHECK-NEXT: vmv1r.v v0, v9 +; CHECK-NEXT: vsetivli zero, 4, e32, m4, tu, ma +; CHECK-NEXT: vslideup.vi v8, v0, 2 +; CHECK-NEXT: vsetivli zero, 6, e32, m4, tu, ma +; CHECK-NEXT: vslideup.vi v8, v4, 4 +; CHECK-NEXT: vsetivli zero, 8, e32, m4, tu, ma +; CHECK-NEXT: vslideup.vi v8, v28, 6 +; CHECK-NEXT: vsetivli zero, 10, e32, m4, tu, ma ; CHECK-NEXT: vslideup.vi v8, v12, 8 +; CHECK-NEXT: vsetivli zero, 12, e32, m4, tu, ma +; CHECK-NEXT: vslideup.vi v8, v24, 10 +; CHECK-NEXT: vsetivli zero, 14, e32, m4, tu, ma +; CHECK-NEXT: vslideup.vi v8, v20, 12 +; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; CHECK-NEXT: vslideup.vi v8, v16, 14 ; CHECK-NEXT: ret %ab = shufflevector <2 x i32> %a, <2 x i32> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 3> %cd = shufflevector <2 x i32> %c, <2 x i32> %d, <4 x i32> <i32 0, i32 1, i32 2, i32 3> @@ -187,27 +152,29 @@ define <32 x i32> @concat_2xv16i32(<16 x i32> %a, <16 x i32> %b) { define <32 x i32> @concat_4xv8i32(<8 x i32> %a, <8 x i32> %b, <8 x i32> %c, <8 x i32> %d) { ; VLA-LABEL: concat_4xv8i32: ; VLA: # %bb.0: -; VLA-NEXT: vmv2r.v v20, v14 -; VLA-NEXT: vmv2r.v v16, v12 -; VLA-NEXT: vmv2r.v v12, v10 -; VLA-NEXT: vsetivli zero, 16, e32, m4, ta, ma -; VLA-NEXT: vslideup.vi v16, v20, 8 -; VLA-NEXT: vslideup.vi v8, v12, 8 +; VLA-NEXT: vmv2r.v v16, v14 +; VLA-NEXT: vmv2r.v v24, v12 +; VLA-NEXT: vmv2r.v v0, v10 +; VLA-NEXT: vsetivli zero, 16, e32, m8, tu, ma +; VLA-NEXT: vslideup.vi v8, v0, 8 +; VLA-NEXT: vsetivli zero, 24, e32, m8, tu, ma +; VLA-NEXT: vslideup.vi v8, v24, 16 ; VLA-NEXT: li a0, 32 ; VLA-NEXT: vsetvli zero, a0, e32, m8, ta, ma -; VLA-NEXT: vslideup.vi v8, v16, 16 +; VLA-NEXT: vslideup.vi v8, v16, 24 ; VLA-NEXT: ret ; ; VLS-LABEL: concat_4xv8i32: ; VLS: # %bb.0: -; VLS-NEXT: vmv2r.v v20, v14 -; VLS-NEXT: vmv2r.v v16, v12 -; VLS-NEXT: vmv2r.v v12, v10 -; VLS-NEXT: vsetivli zero, 16, e32, m4, ta, ma -; VLS-NEXT: vslideup.vi v16, v20, 8 -; VLS-NEXT: vslideup.vi v8, v12, 8 +; VLS-NEXT: vmv2r.v v16, v14 +; VLS-NEXT: vmv2r.v v24, v12 +; VLS-NEXT: vmv2r.v v0, v10 +; VLS-NEXT: vsetivli zero, 16, e32, m8, tu, ma +; VLS-NEXT: vslideup.vi v8, v0, 8 +; VLS-NEXT: vsetivli zero, 24, e32, m8, tu, ma +; VLS-NEXT: vslideup.vi v8, v24, 16 ; VLS-NEXT: vsetvli a0, zero, e32, m8, ta, ma -; VLS-NEXT: vslideup.vi v8, v16, 16 +; VLS-NEXT: vslideup.vi v8, v16, 24 ; VLS-NEXT: ret %ab = shufflevector <8 x i32> %a, <8 x i32> %b, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> %cd = shufflevector <8 x i32> %c, <8 x i32> %d, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> @@ -218,49 +185,123 @@ define <32 x i32> @concat_4xv8i32(<8 x i32> %a, <8 x i32> %b, <8 x i32> %c, <8 x define <32 x i32> @concat_8xv4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d, <4 x i32> %e, <4 x i32> %f, <4 x i32> %g, <4 x i32> %h) { ; VLA-LABEL: concat_8xv4i32: ; VLA: # %bb.0: -; VLA-NEXT: vmv1r.v v18, v15 -; VLA-NEXT: vmv1r.v v20, v14 -; VLA-NEXT: vmv1r.v v22, v13 +; VLA-NEXT: addi sp, sp, -16 +; VLA-NEXT: .cfi_def_cfa_offset 16 +; VLA-NEXT: csrr a0, vlenb +; VLA-NEXT: slli a0, a0, 5 +; VLA-NEXT: sub sp, sp, a0 +; VLA-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x20, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 32 * vlenb +; VLA-NEXT: vmv1r.v v16, v15 +; VLA-NEXT: csrr a0, vlenb +; VLA-NEXT: slli a0, a0, 3 +; VLA-NEXT: mv a1, a0 +; VLA-NEXT: slli a0, a0, 1 +; VLA-NEXT: add a0, a0, a1 +; VLA-NEXT: add a0, sp, a0 +; VLA-NEXT: addi a0, a0, 16 +; VLA-NEXT: vs8r.v v16, (a0) # Unknown-size Folded Spill +; VLA-NEXT: vmv1r.v v16, v14 +; VLA-NEXT: csrr a0, vlenb +; VLA-NEXT: slli a0, a0, 4 +; VLA-NEXT: add a0, sp, a0 +; VLA-NEXT: addi a0, a0, 16 +; VLA-NEXT: vs8r.v v16, (a0) # Unknown-size Folded Spill +; VLA-NEXT: vmv1r.v v16, v13 +; VLA-NEXT: csrr a0, vlenb +; VLA-NEXT: slli a0, a0, 3 +; VLA-NEXT: add a0, sp, a0 +; VLA-NEXT: addi a0, a0, 16 +; VLA-NEXT: vs8r.v v16, (a0) # Unknown-size Folded Spill ; VLA-NEXT: vmv1r.v v16, v12 -; VLA-NEXT: vmv1r.v v14, v11 -; VLA-NEXT: vmv1r.v v12, v10 -; VLA-NEXT: vmv1r.v v10, v9 -; VLA-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; VLA-NEXT: vslideup.vi v20, v18, 4 -; VLA-NEXT: vslideup.vi v16, v22, 4 -; VLA-NEXT: vsetivli zero, 16, e32, m4, ta, ma -; VLA-NEXT: vslideup.vi v16, v20, 8 -; VLA-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; VLA-NEXT: vslideup.vi v12, v14, 4 -; VLA-NEXT: vslideup.vi v8, v10, 4 -; VLA-NEXT: vsetivli zero, 16, e32, m4, ta, ma -; VLA-NEXT: vslideup.vi v8, v12, 8 +; VLA-NEXT: addi a0, sp, 16 +; VLA-NEXT: vs8r.v v16, (a0) # Unknown-size Folded Spill +; VLA-NEXT: vmv1r.v v0, v11 +; VLA-NEXT: vmv1r.v v24, v10 +; VLA-NEXT: vmv1r.v v16, v9 +; VLA-NEXT: vsetivli zero, 8, e32, m8, tu, ma +; VLA-NEXT: vslideup.vi v8, v16, 4 +; VLA-NEXT: vsetivli zero, 12, e32, m8, tu, ma +; VLA-NEXT: vslideup.vi v8, v24, 8 +; VLA-NEXT: vsetivli zero, 16, e32, m8, tu, ma +; VLA-NEXT: vslideup.vi v8, v0, 12 +; VLA-NEXT: vsetivli zero, 20, e32, m8, tu, ma +; VLA-NEXT: vl8r.v v16, (a0) # Unknown-size Folded Reload +; VLA-NEXT: vslideup.vi v8, v16, 16 +; VLA-NEXT: vsetivli zero, 24, e32, m8, tu, ma +; VLA-NEXT: csrr a0, vlenb +; VLA-NEXT: slli a0, a0, 3 +; VLA-NEXT: add a0, sp, a0 +; VLA-NEXT: addi a0, a0, 16 +; VLA-NEXT: vl8r.v v16, (a0) # Unknown-size Folded Reload +; VLA-NEXT: vslideup.vi v8, v16, 20 +; VLA-NEXT: vsetivli zero, 28, e32, m8, tu, ma +; VLA-NEXT: csrr a0, vlenb +; VLA-NEXT: slli a0, a0, 4 +; VLA-NEXT: add a0, sp, a0 +; VLA-NEXT: addi a0, a0, 16 +; VLA-NEXT: vl8r.v v16, (a0) # Unknown-size Folded Reload +; VLA-NEXT: vslideup.vi v8, v16, 24 ; VLA-NEXT: li a0, 32 ; VLA-NEXT: vsetvli zero, a0, e32, m8, ta, ma -; VLA-NEXT: vslideup.vi v8, v16, 16 +; VLA-NEXT: csrr a0, vlenb +; VLA-NEXT: slli a0, a0, 3 +; VLA-NEXT: mv a1, a0 +; VLA-NEXT: slli a0, a0, 1 +; VLA-NEXT: add a0, a0, a1 +; VLA-NEXT: add a0, sp, a0 +; VLA-NEXT: addi a0, a0, 16 +; VLA-NEXT: vl8r.v v16, (a0) # Unknown-size Folded Reload +; VLA-NEXT: vslideup.vi v8, v16, 28 +; VLA-NEXT: csrr a0, vlenb +; VLA-NEXT: slli a0, a0, 5 +; VLA-NEXT: add sp, sp, a0 +; VLA-NEXT: addi sp, sp, 16 ; VLA-NEXT: ret ; ; VLS-LABEL: concat_8xv4i32: ; VLS: # %bb.0: -; VLS-NEXT: vmv1r.v v18, v15 -; VLS-NEXT: vmv1r.v v20, v14 -; VLS-NEXT: vmv1r.v v22, v13 +; VLS-NEXT: addi sp, sp, -16 +; VLS-NEXT: .cfi_def_cfa_offset 16 +; VLS-NEXT: addi sp, sp, -512 +; VLS-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x20, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 32 * vlenb +; VLS-NEXT: vmv1r.v v16, v15 +; VLS-NEXT: addi a0, sp, 400 +; VLS-NEXT: vs8r.v v16, (a0) # Unknown-size Folded Spill +; VLS-NEXT: vmv1r.v v16, v14 +; VLS-NEXT: addi a0, sp, 272 +; VLS-NEXT: vs8r.v v16, (a0) # Unknown-size Folded Spill +; VLS-NEXT: vmv1r.v v16, v13 +; VLS-NEXT: addi a0, sp, 144 +; VLS-NEXT: vs8r.v v16, (a0) # Unknown-size Folded Spill ; VLS-NEXT: vmv1r.v v16, v12 -; VLS-NEXT: vmv1r.v v14, v11 -; VLS-NEXT: vmv1r.v v12, v10 -; VLS-NEXT: vmv1r.v v10, v9 -; VLS-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; VLS-NEXT: vslideup.vi v20, v18, 4 -; VLS-NEXT: vslideup.vi v16, v22, 4 -; VLS-NEXT: vsetivli zero, 16, e32, m4, ta, ma -; VLS-NEXT: vslideup.vi v16, v20, 8 -; VLS-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; VLS-NEXT: vslideup.vi v12, v14, 4 -; VLS-NEXT: vslideup.vi v8, v10, 4 -; VLS-NEXT: vsetivli zero, 16, e32, m4, ta, ma -; VLS-NEXT: vslideup.vi v8, v12, 8 -; VLS-NEXT: vsetvli a0, zero, e32, m8, ta, ma +; VLS-NEXT: addi a0, sp, 16 +; VLS-NEXT: vs8r.v v16, (a0) # Unknown-size Folded Spill +; VLS-NEXT: vmv1r.v v0, v11 +; VLS-NEXT: vmv1r.v v24, v10 +; VLS-NEXT: vmv1r.v v16, v9 +; VLS-NEXT: vsetivli zero, 8, e32, m8, tu, ma +; VLS-NEXT: vslideup.vi v8, v16, 4 +; VLS-NEXT: vsetivli zero, 12, e32, m8, tu, ma +; VLS-NEXT: vslideup.vi v8, v24, 8 +; VLS-NEXT: vsetivli zero, 16, e32, m8, tu, ma +; VLS-NEXT: vslideup.vi v8, v0, 12 +; VLS-NEXT: vsetivli zero, 20, e32, m8, tu, ma +; VLS-NEXT: vl8r.v v16, (a0) # Unknown-size Folded Reload ; VLS-NEXT: vslideup.vi v8, v16, 16 +; VLS-NEXT: vsetivli zero, 24, e32, m8, tu, ma +; VLS-NEXT: addi a0, sp, 144 +; VLS-NEXT: vl8r.v v16, (a0) # Unknown-size Folded Reload +; VLS-NEXT: vslideup.vi v8, v16, 20 +; VLS-NEXT: vsetivli zero, 28, e32, m8, tu, ma +; VLS-NEXT: addi a0, sp, 272 +; VLS-NEXT: vl8r.v v16, (a0) # Unknown-size Folded Reload +; VLS-NEXT: vslideup.vi v8, v16, 24 +; VLS-NEXT: vsetvli a0, zero, e32, m8, ta, ma +; VLS-NEXT: addi a0, sp, 400 +; VLS-NEXT: vl8r.v v16, (a0) # Unknown-size Folded Reload +; VLS-NEXT: vslideup.vi v8, v16, 28 +; VLS-NEXT: addi sp, sp, 512 +; VLS-NEXT: addi sp, sp, 16 ; VLS-NEXT: ret %ab = shufflevector <4 x i32> %a, <4 x i32> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> %cd = shufflevector <4 x i32> %c, <4 x i32> %d, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-strided-load-combine.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-strided-load-combine.ll index 37902aa18732..ba5db552b854 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-strided-load-combine.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-strided-load-combine.ll @@ -24,15 +24,17 @@ define void @widen_2xv4i16(ptr %x, ptr %z) { define void @widen_3xv4i16(ptr %x, ptr %z) { ; CHECK-LABEL: widen_3xv4i16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi a2, a0, 16 ; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma -; CHECK-NEXT: vle16.v v8, (a2) -; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma -; CHECK-NEXT: vle16.v v10, (a0) -; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma -; CHECK-NEXT: vslideup.vi v10, v8, 8 -; CHECK-NEXT: vsetivli zero, 12, e16, m2, ta, ma -; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: vle16.v v8, (a0) +; CHECK-NEXT: addi a2, a0, 8 +; CHECK-NEXT: vle16.v v10, (a2) +; CHECK-NEXT: addi a0, a0, 16 +; CHECK-NEXT: vle16.v v12, (a0) +; CHECK-NEXT: vsetivli zero, 8, e16, m2, tu, ma +; CHECK-NEXT: vslideup.vi v8, v10, 4 +; CHECK-NEXT: vsetivli zero, 12, e16, m2, tu, ma +; CHECK-NEXT: vslideup.vi v8, v12, 8 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: ret %a = load <4 x i16>, ptr %x %b.gep = getelementptr i8, ptr %x, i64 8 @@ -70,18 +72,20 @@ define void @widen_4xv4i16(ptr %x, ptr %z) { define void @widen_4xv4i16_unaligned(ptr %x, ptr %z) { ; CHECK-NO-MISALIGN-LABEL: widen_4xv4i16_unaligned: ; CHECK-NO-MISALIGN: # %bb.0: -; CHECK-NO-MISALIGN-NEXT: vsetivli zero, 8, e16, m1, ta, ma +; CHECK-NO-MISALIGN-NEXT: vsetivli zero, 8, e8, mf2, ta, ma ; CHECK-NO-MISALIGN-NEXT: vle8.v v8, (a0) -; CHECK-NO-MISALIGN-NEXT: addi a2, a0, 16 -; CHECK-NO-MISALIGN-NEXT: vle8.v v10, (a2) ; CHECK-NO-MISALIGN-NEXT: addi a2, a0, 8 +; CHECK-NO-MISALIGN-NEXT: vle8.v v10, (a2) +; CHECK-NO-MISALIGN-NEXT: addi a2, a0, 16 +; CHECK-NO-MISALIGN-NEXT: vle8.v v12, (a2) ; CHECK-NO-MISALIGN-NEXT: addi a0, a0, 24 -; CHECK-NO-MISALIGN-NEXT: vle8.v v9, (a0) -; CHECK-NO-MISALIGN-NEXT: vle8.v v11, (a2) -; CHECK-NO-MISALIGN-NEXT: vslideup.vi v10, v9, 4 -; CHECK-NO-MISALIGN-NEXT: vslideup.vi v8, v11, 4 +; CHECK-NO-MISALIGN-NEXT: vle8.v v14, (a0) +; CHECK-NO-MISALIGN-NEXT: vsetivli zero, 8, e16, m2, tu, ma +; CHECK-NO-MISALIGN-NEXT: vslideup.vi v8, v10, 4 +; CHECK-NO-MISALIGN-NEXT: vsetivli zero, 12, e16, m2, tu, ma +; CHECK-NO-MISALIGN-NEXT: vslideup.vi v8, v12, 8 ; CHECK-NO-MISALIGN-NEXT: vsetivli zero, 16, e16, m2, ta, ma -; CHECK-NO-MISALIGN-NEXT: vslideup.vi v8, v10, 8 +; CHECK-NO-MISALIGN-NEXT: vslideup.vi v8, v14, 12 ; CHECK-NO-MISALIGN-NEXT: vse16.v v8, (a1) ; CHECK-NO-MISALIGN-NEXT: ret ; @@ -181,14 +185,21 @@ define void @strided_constant_0(ptr %x, ptr %z) { define void @strided_constant_mismatch_4xv4i16(ptr %x, ptr %z) { ; CHECK-LABEL: strided_constant_mismatch_4xv4i16: ; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma +; CHECK-NEXT: vle16.v v8, (a0) +; CHECK-NEXT: addi a2, a0, 2 +; CHECK-NEXT: vle16.v v10, (a2) ; CHECK-NEXT: addi a2, a0, 6 -; CHECK-NEXT: li a3, 2 -; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma -; CHECK-NEXT: vlse64.v v8, (a0), a3 -; CHECK-NEXT: vlse64.v v10, (a2), a3 -; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma -; CHECK-NEXT: vslideup.vi v8, v10, 2 -; CHECK-NEXT: vse64.v v8, (a1) +; CHECK-NEXT: vle16.v v12, (a2) +; CHECK-NEXT: addi a0, a0, 8 +; CHECK-NEXT: vle16.v v14, (a0) +; CHECK-NEXT: vsetivli zero, 8, e16, m2, tu, ma +; CHECK-NEXT: vslideup.vi v8, v10, 4 +; CHECK-NEXT: vsetivli zero, 12, e16, m2, tu, ma +; CHECK-NEXT: vslideup.vi v8, v12, 8 +; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma +; CHECK-NEXT: vslideup.vi v8, v14, 12 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: ret %a = load <4 x i16>, ptr %x %b.gep = getelementptr i8, ptr %x, i64 2 @@ -244,38 +255,59 @@ define void @strided_runtime_4xv4i16(ptr %x, ptr %z, i64 %s) { define void @strided_runtime_mismatch_4xv4i16(ptr %x, ptr %z, i64 %s, i64 %t) { ; RV32-LABEL: strided_runtime_mismatch_4xv4i16: ; RV32: # %bb.0: -; RV32-NEXT: add a3, a0, a2 -; RV32-NEXT: add a3, a3, a4 -; RV32-NEXT: vsetivli zero, 2, e64, m1, ta, ma -; RV32-NEXT: vlse64.v v8, (a0), a2 -; RV32-NEXT: vlse64.v v10, (a3), a2 -; RV32-NEXT: vsetivli zero, 4, e64, m2, ta, ma -; RV32-NEXT: vslideup.vi v8, v10, 2 -; RV32-NEXT: vse64.v v8, (a1) +; RV32-NEXT: vsetivli zero, 4, e16, mf2, ta, ma +; RV32-NEXT: vle16.v v8, (a0) +; RV32-NEXT: add a0, a0, a2 +; RV32-NEXT: vle16.v v10, (a0) +; RV32-NEXT: add a0, a0, a4 +; RV32-NEXT: vle16.v v12, (a0) +; RV32-NEXT: add a0, a0, a2 +; RV32-NEXT: vle16.v v14, (a0) +; RV32-NEXT: vsetivli zero, 8, e16, m2, tu, ma +; RV32-NEXT: vslideup.vi v8, v10, 4 +; RV32-NEXT: vsetivli zero, 12, e16, m2, tu, ma +; RV32-NEXT: vslideup.vi v8, v12, 8 +; RV32-NEXT: vsetivli zero, 16, e16, m2, ta, ma +; RV32-NEXT: vslideup.vi v8, v14, 12 +; RV32-NEXT: vse16.v v8, (a1) ; RV32-NEXT: ret ; ; RV64-LABEL: strided_runtime_mismatch_4xv4i16: ; RV64: # %bb.0: -; RV64-NEXT: add a4, a0, a2 -; RV64-NEXT: add a3, a4, a3 -; RV64-NEXT: vsetivli zero, 2, e64, m1, ta, ma -; RV64-NEXT: vlse64.v v8, (a0), a2 -; RV64-NEXT: vlse64.v v10, (a3), a2 -; RV64-NEXT: vsetivli zero, 4, e64, m2, ta, ma -; RV64-NEXT: vslideup.vi v8, v10, 2 -; RV64-NEXT: vse64.v v8, (a1) +; RV64-NEXT: vsetivli zero, 4, e16, mf2, ta, ma +; RV64-NEXT: vle16.v v8, (a0) +; RV64-NEXT: add a0, a0, a2 +; RV64-NEXT: vle16.v v10, (a0) +; RV64-NEXT: add a0, a0, a3 +; RV64-NEXT: vle16.v v12, (a0) +; RV64-NEXT: add a0, a0, a2 +; RV64-NEXT: vle16.v v14, (a0) +; RV64-NEXT: vsetivli zero, 8, e16, m2, tu, ma +; RV64-NEXT: vslideup.vi v8, v10, 4 +; RV64-NEXT: vsetivli zero, 12, e16, m2, tu, ma +; RV64-NEXT: vslideup.vi v8, v12, 8 +; RV64-NEXT: vsetivli zero, 16, e16, m2, ta, ma +; RV64-NEXT: vslideup.vi v8, v14, 12 +; RV64-NEXT: vse16.v v8, (a1) ; RV64-NEXT: ret ; ; ZVE64F-LABEL: strided_runtime_mismatch_4xv4i16: ; ZVE64F: # %bb.0: -; ZVE64F-NEXT: add a4, a0, a2 -; ZVE64F-NEXT: add a3, a4, a3 -; ZVE64F-NEXT: vsetivli zero, 2, e64, m1, ta, ma -; ZVE64F-NEXT: vlse64.v v8, (a0), a2 -; ZVE64F-NEXT: vlse64.v v10, (a3), a2 -; ZVE64F-NEXT: vsetivli zero, 4, e64, m2, ta, ma -; ZVE64F-NEXT: vslideup.vi v8, v10, 2 -; ZVE64F-NEXT: vse64.v v8, (a1) +; ZVE64F-NEXT: vsetivli zero, 4, e16, mf2, ta, ma +; ZVE64F-NEXT: vle16.v v8, (a0) +; ZVE64F-NEXT: add a0, a0, a2 +; ZVE64F-NEXT: vle16.v v10, (a0) +; ZVE64F-NEXT: add a0, a0, a3 +; ZVE64F-NEXT: vle16.v v12, (a0) +; ZVE64F-NEXT: add a0, a0, a2 +; ZVE64F-NEXT: vle16.v v14, (a0) +; ZVE64F-NEXT: vsetivli zero, 8, e16, m2, tu, ma +; ZVE64F-NEXT: vslideup.vi v8, v10, 4 +; ZVE64F-NEXT: vsetivli zero, 12, e16, m2, tu, ma +; ZVE64F-NEXT: vslideup.vi v8, v12, 8 +; ZVE64F-NEXT: vsetivli zero, 16, e16, m2, ta, ma +; ZVE64F-NEXT: vslideup.vi v8, v14, 12 +; ZVE64F-NEXT: vse16.v v8, (a1) ; ZVE64F-NEXT: ret %a = load <4 x i16>, ptr %x %b.gep = getelementptr i8, ptr %x, i64 %s diff --git a/llvm/test/CodeGen/RISCV/rvv/fpclamptosat_vec.ll b/llvm/test/CodeGen/RISCV/rvv/fpclamptosat_vec.ll index b3bda5973eb8..eb7894ede046 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fpclamptosat_vec.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fpclamptosat_vec.ll @@ -441,50 +441,57 @@ define <4 x i32> @stest_f16i32(<4 x half> %x) { ; CHECK-V-NEXT: slli a1, a1, 2 ; CHECK-V-NEXT: sub sp, sp, a1 ; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x30, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 48 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu a0, 24(a0) +; CHECK-V-NEXT: lhu s0, 24(a0) +; CHECK-V-NEXT: lhu s1, 16(a0) +; CHECK-V-NEXT: lhu s2, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 ; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 3, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma -; CHECK-V-NEXT: vmv.s.x v10, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 1 ; CHECK-V-NEXT: vsetivli zero, 4, e64, m2, ta, ma +; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl2r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 ; CHECK-V-NEXT: vsetvli zero, zero, e32, m1, ta, ma ; CHECK-V-NEXT: vnclip.wi v8, v10, 0 ; CHECK-V-NEXT: csrr a0, vlenb @@ -602,50 +609,57 @@ define <4 x i32> @utesth_f16i32(<4 x half> %x) { ; CHECK-V-NEXT: slli a1, a1, 2 ; CHECK-V-NEXT: sub sp, sp, a1 ; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x30, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 48 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu a0, 24(a0) +; CHECK-V-NEXT: lhu s0, 24(a0) +; CHECK-V-NEXT: lhu s1, 16(a0) +; CHECK-V-NEXT: lhu s2, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 ; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 3, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma -; CHECK-V-NEXT: vmv.s.x v10, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 1 ; CHECK-V-NEXT: vsetivli zero, 4, e64, m2, ta, ma +; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl2r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 ; CHECK-V-NEXT: vsetvli zero, zero, e32, m1, ta, ma ; CHECK-V-NEXT: vnclipu.wi v8, v10, 0 ; CHECK-V-NEXT: csrr a0, vlenb @@ -773,53 +787,60 @@ define <4 x i32> @ustest_f16i32(<4 x half> %x) { ; CHECK-V-NEXT: slli a1, a1, 2 ; CHECK-V-NEXT: sub sp, sp, a1 ; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x30, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 48 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu a0, 24(a0) +; CHECK-V-NEXT: lhu s0, 24(a0) +; CHECK-V-NEXT: lhu s1, 16(a0) +; CHECK-V-NEXT: lhu s2, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 ; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 3, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma -; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 ; CHECK-V-NEXT: vsetivli zero, 4, e64, m2, ta, ma +; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 ; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v10, 2 +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 ; CHECK-V-NEXT: li a0, -1 ; CHECK-V-NEXT: srli a0, a0, 32 -; CHECK-V-NEXT: vmin.vx v8, v8, a0 +; CHECK-V-NEXT: vmin.vx v8, v10, a0 ; CHECK-V-NEXT: vmax.vx v10, v8, zero ; CHECK-V-NEXT: vsetvli zero, zero, e32, m1, ta, ma ; CHECK-V-NEXT: vnsrl.wi v8, v10, 0 @@ -1383,125 +1404,90 @@ define <8 x i16> @stest_f16i16(<8 x half> %x) { ; CHECK-V-NEXT: .cfi_offset s5, -56 ; CHECK-V-NEXT: .cfi_offset s6, -64 ; CHECK-V-NEXT: csrr a1, vlenb -; CHECK-V-NEXT: slli a1, a1, 2 +; CHECK-V-NEXT: slli a1, a1, 1 ; CHECK-V-NEXT: sub sp, sp, a1 -; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu s3, 24(a0) -; CHECK-V-NEXT: lhu s4, 32(a0) -; CHECK-V-NEXT: lhu s5, 40(a0) -; CHECK-V-NEXT: lhu s6, 48(a0) -; CHECK-V-NEXT: lhu a0, 56(a0) +; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 2 * vlenb +; CHECK-V-NEXT: lhu s0, 56(a0) +; CHECK-V-NEXT: lhu s1, 48(a0) +; CHECK-V-NEXT: lhu s2, 40(a0) +; CHECK-V-NEXT: lhu s3, 32(a0) +; CHECK-V-NEXT: lhu s4, 24(a0) +; CHECK-V-NEXT: lhu s5, 16(a0) +; CHECK-V-NEXT: lhu s6, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s5 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s4 +; CHECK-V-NEXT: vsetivli zero, 3, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s4 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 4, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 2 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s3 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 +; CHECK-V-NEXT: vsetivli zero, 5, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 4 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 6, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 5 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 7, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 6 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-V-NEXT: vmv.s.x v10, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 2 ; CHECK-V-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl2r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 4 +; CHECK-V-NEXT: vmv.s.x v8, a0 +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 7 ; CHECK-V-NEXT: vsetvli zero, zero, e16, m1, ta, ma ; CHECK-V-NEXT: vnclip.wi v8, v10, 0 ; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 2 +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add sp, sp, a0 ; CHECK-V-NEXT: ld ra, 72(sp) # 8-byte Folded Reload ; CHECK-V-NEXT: ld s0, 64(sp) # 8-byte Folded Reload @@ -1696,125 +1682,90 @@ define <8 x i16> @utesth_f16i16(<8 x half> %x) { ; CHECK-V-NEXT: .cfi_offset s5, -56 ; CHECK-V-NEXT: .cfi_offset s6, -64 ; CHECK-V-NEXT: csrr a1, vlenb -; CHECK-V-NEXT: slli a1, a1, 2 +; CHECK-V-NEXT: slli a1, a1, 1 ; CHECK-V-NEXT: sub sp, sp, a1 -; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu s3, 24(a0) -; CHECK-V-NEXT: lhu s4, 32(a0) -; CHECK-V-NEXT: lhu s5, 40(a0) -; CHECK-V-NEXT: lhu s6, 48(a0) -; CHECK-V-NEXT: lhu a0, 56(a0) +; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 2 * vlenb +; CHECK-V-NEXT: lhu s0, 56(a0) +; CHECK-V-NEXT: lhu s1, 48(a0) +; CHECK-V-NEXT: lhu s2, 40(a0) +; CHECK-V-NEXT: lhu s3, 32(a0) +; CHECK-V-NEXT: lhu s4, 24(a0) +; CHECK-V-NEXT: lhu s5, 16(a0) +; CHECK-V-NEXT: lhu s6, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s5 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s4 +; CHECK-V-NEXT: vsetivli zero, 3, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s4 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 4, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 2 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s3 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 +; CHECK-V-NEXT: vsetivli zero, 5, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 4 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 6, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 5 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 7, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 6 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-V-NEXT: vmv.s.x v10, a0 +; CHECK-V-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 2 -; CHECK-V-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 7 +; CHECK-V-NEXT: vsetvli zero, zero, e16, m1, ta, ma +; CHECK-V-NEXT: vnclipu.wi v8, v10, 0 ; CHECK-V-NEXT: csrr a0, vlenb ; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl2r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 4 -; CHECK-V-NEXT: vsetvli zero, zero, e16, m1, ta, ma -; CHECK-V-NEXT: vnclipu.wi v8, v10, 0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 2 ; CHECK-V-NEXT: add sp, sp, a0 ; CHECK-V-NEXT: ld ra, 72(sp) # 8-byte Folded Reload ; CHECK-V-NEXT: ld s0, 64(sp) # 8-byte Folded Reload @@ -2031,129 +1982,94 @@ define <8 x i16> @ustest_f16i16(<8 x half> %x) { ; CHECK-V-NEXT: .cfi_offset s5, -56 ; CHECK-V-NEXT: .cfi_offset s6, -64 ; CHECK-V-NEXT: csrr a1, vlenb -; CHECK-V-NEXT: slli a1, a1, 2 +; CHECK-V-NEXT: slli a1, a1, 1 ; CHECK-V-NEXT: sub sp, sp, a1 -; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu s3, 24(a0) -; CHECK-V-NEXT: lhu s4, 32(a0) -; CHECK-V-NEXT: lhu s5, 40(a0) -; CHECK-V-NEXT: lhu s6, 48(a0) -; CHECK-V-NEXT: lhu a0, 56(a0) +; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 2 * vlenb +; CHECK-V-NEXT: lhu s0, 56(a0) +; CHECK-V-NEXT: lhu s1, 48(a0) +; CHECK-V-NEXT: lhu s2, 40(a0) +; CHECK-V-NEXT: lhu s3, 32(a0) +; CHECK-V-NEXT: lhu s4, 24(a0) +; CHECK-V-NEXT: lhu s5, 16(a0) +; CHECK-V-NEXT: lhu s6, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s5 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s4 +; CHECK-V-NEXT: vsetivli zero, 3, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s4 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 4, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 2 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s3 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 +; CHECK-V-NEXT: vsetivli zero, 5, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 4 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 6, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 5 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 7, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 6 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 8, e32, m2, ta, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 2 -; CHECK-V-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 ; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v10, 4 +; CHECK-V-NEXT: vslideup.vi v10, v8, 7 ; CHECK-V-NEXT: lui a0, 16 ; CHECK-V-NEXT: addi a0, a0, -1 -; CHECK-V-NEXT: vmin.vx v8, v8, a0 +; CHECK-V-NEXT: vmin.vx v8, v10, a0 ; CHECK-V-NEXT: vmax.vx v10, v8, zero ; CHECK-V-NEXT: vsetvli zero, zero, e16, m1, ta, ma ; CHECK-V-NEXT: vnsrl.wi v8, v10, 0 ; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 2 +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add sp, sp, a0 ; CHECK-V-NEXT: ld ra, 72(sp) # 8-byte Folded Reload ; CHECK-V-NEXT: ld s0, 64(sp) # 8-byte Folded Reload @@ -3807,50 +3723,57 @@ define <4 x i32> @stest_f16i32_mm(<4 x half> %x) { ; CHECK-V-NEXT: slli a1, a1, 2 ; CHECK-V-NEXT: sub sp, sp, a1 ; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x30, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 48 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu a0, 24(a0) +; CHECK-V-NEXT: lhu s0, 24(a0) +; CHECK-V-NEXT: lhu s1, 16(a0) +; CHECK-V-NEXT: lhu s2, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 ; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 3, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma -; CHECK-V-NEXT: vmv.s.x v10, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 1 ; CHECK-V-NEXT: vsetivli zero, 4, e64, m2, ta, ma +; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl2r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 ; CHECK-V-NEXT: vsetvli zero, zero, e32, m1, ta, ma ; CHECK-V-NEXT: vnclip.wi v8, v10, 0 ; CHECK-V-NEXT: csrr a0, vlenb @@ -3966,50 +3889,57 @@ define <4 x i32> @utesth_f16i32_mm(<4 x half> %x) { ; CHECK-V-NEXT: slli a1, a1, 2 ; CHECK-V-NEXT: sub sp, sp, a1 ; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x30, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 48 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu a0, 24(a0) +; CHECK-V-NEXT: lhu s0, 24(a0) +; CHECK-V-NEXT: lhu s1, 16(a0) +; CHECK-V-NEXT: lhu s2, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 ; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 3, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma -; CHECK-V-NEXT: vmv.s.x v10, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 1 ; CHECK-V-NEXT: vsetivli zero, 4, e64, m2, ta, ma +; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl2r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 ; CHECK-V-NEXT: vsetvli zero, zero, e32, m1, ta, ma ; CHECK-V-NEXT: vnclipu.wi v8, v10, 0 ; CHECK-V-NEXT: csrr a0, vlenb @@ -4136,53 +4066,60 @@ define <4 x i32> @ustest_f16i32_mm(<4 x half> %x) { ; CHECK-V-NEXT: slli a1, a1, 2 ; CHECK-V-NEXT: sub sp, sp, a1 ; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x30, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 48 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu a0, 24(a0) +; CHECK-V-NEXT: lhu s0, 24(a0) +; CHECK-V-NEXT: lhu s1, 16(a0) +; CHECK-V-NEXT: lhu s2, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 ; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 3, e64, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 +; CHECK-V-NEXT: add a0, sp, a0 +; CHECK-V-NEXT: addi a0, a0, 16 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma -; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 ; CHECK-V-NEXT: vsetivli zero, 4, e64, m2, ta, ma +; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: csrr a0, vlenb +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add a0, sp, a0 ; CHECK-V-NEXT: addi a0, a0, 16 ; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v10, 2 +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 ; CHECK-V-NEXT: li a0, -1 ; CHECK-V-NEXT: srli a0, a0, 32 -; CHECK-V-NEXT: vmin.vx v8, v8, a0 +; CHECK-V-NEXT: vmin.vx v8, v10, a0 ; CHECK-V-NEXT: vmax.vx v10, v8, zero ; CHECK-V-NEXT: vsetvli zero, zero, e32, m1, ta, ma ; CHECK-V-NEXT: vnsrl.wi v8, v10, 0 @@ -4734,125 +4671,90 @@ define <8 x i16> @stest_f16i16_mm(<8 x half> %x) { ; CHECK-V-NEXT: .cfi_offset s5, -56 ; CHECK-V-NEXT: .cfi_offset s6, -64 ; CHECK-V-NEXT: csrr a1, vlenb -; CHECK-V-NEXT: slli a1, a1, 2 +; CHECK-V-NEXT: slli a1, a1, 1 ; CHECK-V-NEXT: sub sp, sp, a1 -; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu s3, 24(a0) -; CHECK-V-NEXT: lhu s4, 32(a0) -; CHECK-V-NEXT: lhu s5, 40(a0) -; CHECK-V-NEXT: lhu s6, 48(a0) -; CHECK-V-NEXT: lhu a0, 56(a0) +; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 2 * vlenb +; CHECK-V-NEXT: lhu s0, 56(a0) +; CHECK-V-NEXT: lhu s1, 48(a0) +; CHECK-V-NEXT: lhu s2, 40(a0) +; CHECK-V-NEXT: lhu s3, 32(a0) +; CHECK-V-NEXT: lhu s4, 24(a0) +; CHECK-V-NEXT: lhu s5, 16(a0) +; CHECK-V-NEXT: lhu s6, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s5 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s4 +; CHECK-V-NEXT: vsetivli zero, 3, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s4 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 4, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 2 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s3 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 +; CHECK-V-NEXT: vsetivli zero, 5, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 4 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 6, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 5 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 7, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 6 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-V-NEXT: vmv.s.x v10, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 2 ; CHECK-V-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl2r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 4 +; CHECK-V-NEXT: vmv.s.x v8, a0 +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 7 ; CHECK-V-NEXT: vsetvli zero, zero, e16, m1, ta, ma ; CHECK-V-NEXT: vnclip.wi v8, v10, 0 ; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 2 +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add sp, sp, a0 ; CHECK-V-NEXT: ld ra, 72(sp) # 8-byte Folded Reload ; CHECK-V-NEXT: ld s0, 64(sp) # 8-byte Folded Reload @@ -5045,125 +4947,90 @@ define <8 x i16> @utesth_f16i16_mm(<8 x half> %x) { ; CHECK-V-NEXT: .cfi_offset s5, -56 ; CHECK-V-NEXT: .cfi_offset s6, -64 ; CHECK-V-NEXT: csrr a1, vlenb -; CHECK-V-NEXT: slli a1, a1, 2 +; CHECK-V-NEXT: slli a1, a1, 1 ; CHECK-V-NEXT: sub sp, sp, a1 -; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu s3, 24(a0) -; CHECK-V-NEXT: lhu s4, 32(a0) -; CHECK-V-NEXT: lhu s5, 40(a0) -; CHECK-V-NEXT: lhu s6, 48(a0) -; CHECK-V-NEXT: lhu a0, 56(a0) +; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 2 * vlenb +; CHECK-V-NEXT: lhu s0, 56(a0) +; CHECK-V-NEXT: lhu s1, 48(a0) +; CHECK-V-NEXT: lhu s2, 40(a0) +; CHECK-V-NEXT: lhu s3, 32(a0) +; CHECK-V-NEXT: lhu s4, 24(a0) +; CHECK-V-NEXT: lhu s5, 16(a0) +; CHECK-V-NEXT: lhu s6, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s5 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s4 +; CHECK-V-NEXT: vsetivli zero, 3, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s4 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 4, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 2 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s3 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 +; CHECK-V-NEXT: vsetivli zero, 5, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 4 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 6, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 5 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 7, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 6 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.lu.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-V-NEXT: vmv.s.x v10, a0 -; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 2 ; CHECK-V-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl2r.v v8, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v10, v8, 4 +; CHECK-V-NEXT: vmv.s.x v8, a0 +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 7 ; CHECK-V-NEXT: vsetvli zero, zero, e16, m1, ta, ma ; CHECK-V-NEXT: vnclipu.wi v8, v10, 0 ; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 2 +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add sp, sp, a0 ; CHECK-V-NEXT: ld ra, 72(sp) # 8-byte Folded Reload ; CHECK-V-NEXT: ld s0, 64(sp) # 8-byte Folded Reload @@ -5379,129 +5246,94 @@ define <8 x i16> @ustest_f16i16_mm(<8 x half> %x) { ; CHECK-V-NEXT: .cfi_offset s5, -56 ; CHECK-V-NEXT: .cfi_offset s6, -64 ; CHECK-V-NEXT: csrr a1, vlenb -; CHECK-V-NEXT: slli a1, a1, 2 +; CHECK-V-NEXT: slli a1, a1, 1 ; CHECK-V-NEXT: sub sp, sp, a1 -; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 4 * vlenb -; CHECK-V-NEXT: lhu s0, 0(a0) -; CHECK-V-NEXT: lhu s1, 8(a0) -; CHECK-V-NEXT: lhu s2, 16(a0) -; CHECK-V-NEXT: lhu s3, 24(a0) -; CHECK-V-NEXT: lhu s4, 32(a0) -; CHECK-V-NEXT: lhu s5, 40(a0) -; CHECK-V-NEXT: lhu s6, 48(a0) -; CHECK-V-NEXT: lhu a0, 56(a0) +; CHECK-V-NEXT: .cfi_escape 0x0f, 0x0e, 0x72, 0x00, 0x11, 0xd0, 0x00, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 80 + 2 * vlenb +; CHECK-V-NEXT: lhu s0, 56(a0) +; CHECK-V-NEXT: lhu s1, 48(a0) +; CHECK-V-NEXT: lhu s2, 40(a0) +; CHECK-V-NEXT: lhu s3, 32(a0) +; CHECK-V-NEXT: lhu s4, 24(a0) +; CHECK-V-NEXT: lhu s5, 16(a0) +; CHECK-V-NEXT: lhu s6, 0(a0) +; CHECK-V-NEXT: lhu a0, 8(a0) ; CHECK-V-NEXT: fmv.w.x fa0, a0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz ; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s6 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 2, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v8, v10, 1 +; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s5 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s4 +; CHECK-V-NEXT: vsetivli zero, 3, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 2 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s4 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 4, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 2 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: addi a0, sp, 16 +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 3 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s3 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s2 +; CHECK-V-NEXT: vsetivli zero, 5, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 4 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s2 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 6, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 5 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill ; CHECK-V-NEXT: fmv.w.x fa0, s1 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; CHECK-V-NEXT: fmv.w.x fa0, s0 +; CHECK-V-NEXT: vsetivli zero, 7, e32, m2, tu, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload +; CHECK-V-NEXT: vslideup.vi v10, v8, 6 +; CHECK-V-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-V-NEXT: fmv.w.x fa0, s0 ; CHECK-V-NEXT: call __extendhfsf2 ; CHECK-V-NEXT: fcvt.l.s a0, fa0, rtz -; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vsetivli zero, 8, e32, m2, ta, ma ; CHECK-V-NEXT: vmv.s.x v8, a0 ; CHECK-V-NEXT: addi a0, sp, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 1 -; CHECK-V-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 -; CHECK-V-NEXT: vl1r.v v9, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v9, 2 -; CHECK-V-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 1 -; CHECK-V-NEXT: add a0, sp, a0 -; CHECK-V-NEXT: addi a0, a0, 16 ; CHECK-V-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload -; CHECK-V-NEXT: vslideup.vi v8, v10, 4 +; CHECK-V-NEXT: vslideup.vi v10, v8, 7 ; CHECK-V-NEXT: lui a0, 16 ; CHECK-V-NEXT: addi a0, a0, -1 -; CHECK-V-NEXT: vmin.vx v8, v8, a0 +; CHECK-V-NEXT: vmin.vx v8, v10, a0 ; CHECK-V-NEXT: vmax.vx v10, v8, zero ; CHECK-V-NEXT: vsetvli zero, zero, e16, m1, ta, ma ; CHECK-V-NEXT: vnsrl.wi v8, v10, 0 ; CHECK-V-NEXT: csrr a0, vlenb -; CHECK-V-NEXT: slli a0, a0, 2 +; CHECK-V-NEXT: slli a0, a0, 1 ; CHECK-V-NEXT: add sp, sp, a0 ; CHECK-V-NEXT: ld ra, 72(sp) # 8-byte Folded Reload ; CHECK-V-NEXT: ld s0, 64(sp) # 8-byte Folded Reload diff --git a/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll index 0b236f6d3ff3..f3ae03af7c78 100644 --- a/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll @@ -2136,18 +2136,17 @@ define <vscale x 32 x i8> @mgather_baseidx_nxv32i8(ptr %base, <vscale x 32 x i8> ; RV64-NEXT: vluxei64.v v13, (a0), v24, v0.t ; RV64-NEXT: srli a1, a1, 2 ; RV64-NEXT: vsetvli a3, zero, e8, mf2, ta, ma -; RV64-NEXT: vslidedown.vx v8, v16, a1 +; RV64-NEXT: vslidedown.vx v0, v16, a1 +; RV64-NEXT: vsetvli a1, zero, e64, m8, ta, ma +; RV64-NEXT: vsext.vf8 v16, v10 +; RV64-NEXT: vsetvli zero, zero, e8, m1, ta, mu +; RV64-NEXT: vluxei64.v v14, (a0), v16, v0.t ; RV64-NEXT: vsetvli a1, zero, e8, mf4, ta, ma -; RV64-NEXT: vslidedown.vx v0, v8, a2 +; RV64-NEXT: vslidedown.vx v0, v0, a2 ; RV64-NEXT: vsetvli a1, zero, e64, m8, ta, ma ; RV64-NEXT: vsext.vf8 v16, v11 ; RV64-NEXT: vsetvli zero, zero, e8, m1, ta, mu ; RV64-NEXT: vluxei64.v v15, (a0), v16, v0.t -; RV64-NEXT: vsetvli zero, zero, e64, m8, ta, ma -; RV64-NEXT: vsext.vf8 v16, v10 -; RV64-NEXT: vsetvli zero, zero, e8, m1, ta, mu -; RV64-NEXT: vmv1r.v v0, v8 -; RV64-NEXT: vluxei64.v v14, (a0), v16, v0.t ; RV64-NEXT: vmv4r.v v8, v12 ; RV64-NEXT: ret %ptrs = getelementptr inbounds i8, ptr %base, <vscale x 32 x i8> %idxs diff --git a/llvm/test/CodeGen/RISCV/rvv/pr63596.ll b/llvm/test/CodeGen/RISCV/rvv/pr63596.ll index d13d67fd0a88..c27488b18a01 100644 --- a/llvm/test/CodeGen/RISCV/rvv/pr63596.ll +++ b/llvm/test/CodeGen/RISCV/rvv/pr63596.ll @@ -9,38 +9,39 @@ define <4 x float> @foo(ptr %0) nounwind { ; CHECK-NEXT: sd s0, 32(sp) # 8-byte Folded Spill ; CHECK-NEXT: sd s1, 24(sp) # 8-byte Folded Spill ; CHECK-NEXT: sd s2, 16(sp) # 8-byte Folded Spill -; CHECK-NEXT: lhu s0, 0(a0) -; CHECK-NEXT: lhu s1, 2(a0) -; CHECK-NEXT: lhu s2, 4(a0) -; CHECK-NEXT: lhu a0, 6(a0) +; CHECK-NEXT: lhu s0, 6(a0) +; CHECK-NEXT: lhu s1, 4(a0) +; CHECK-NEXT: lhu s2, 0(a0) +; CHECK-NEXT: lhu a0, 2(a0) ; CHECK-NEXT: fmv.w.x fa0, a0 ; CHECK-NEXT: call __extendhfsf2 -; CHECK-NEXT: fsw fa0, 4(sp) +; CHECK-NEXT: fsw fa0, 8(sp) ; CHECK-NEXT: fmv.w.x fa0, s2 ; CHECK-NEXT: call __extendhfsf2 -; CHECK-NEXT: fsw fa0, 12(sp) +; CHECK-NEXT: fsw fa0, 0(sp) ; CHECK-NEXT: fmv.w.x fa0, s1 ; CHECK-NEXT: call __extendhfsf2 -; CHECK-NEXT: fsw fa0, 8(sp) +; CHECK-NEXT: fsw fa0, 12(sp) ; CHECK-NEXT: fmv.w.x fa0, s0 ; CHECK-NEXT: call __extendhfsf2 -; CHECK-NEXT: fsw fa0, 0(sp) -; CHECK-NEXT: addi a0, sp, 4 +; CHECK-NEXT: fsw fa0, 4(sp) +; CHECK-NEXT: addi a0, sp, 8 ; CHECK-NEXT: vsetivli zero, 1, e32, mf2, ta, ma +; CHECK-NEXT: vle32.v v9, (a0) +; CHECK-NEXT: mv a0, sp ; CHECK-NEXT: vle32.v v8, (a0) +; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, ma +; CHECK-NEXT: vslideup.vi v8, v9, 1 ; CHECK-NEXT: addi a0, sp, 12 +; CHECK-NEXT: vsetivli zero, 1, e32, mf2, ta, ma ; CHECK-NEXT: vle32.v v9, (a0) -; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-NEXT: vslideup.vi v9, v8, 1 -; CHECK-NEXT: addi a0, sp, 8 +; CHECK-NEXT: vsetivli zero, 3, e32, m1, tu, ma +; CHECK-NEXT: vslideup.vi v8, v9, 2 +; CHECK-NEXT: addi a0, sp, 4 ; CHECK-NEXT: vsetivli zero, 1, e32, mf2, ta, ma -; CHECK-NEXT: vle32.v v10, (a0) -; CHECK-NEXT: mv a0, sp -; CHECK-NEXT: vle32.v v8, (a0) -; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-NEXT: vslideup.vi v8, v10, 1 +; CHECK-NEXT: vle32.v v9, (a0) ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vi v8, v9, 2 +; CHECK-NEXT: vslideup.vi v8, v9, 3 ; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload ; CHECK-NEXT: ld s0, 32(sp) # 8-byte Folded Reload ; CHECK-NEXT: ld s1, 24(sp) # 8-byte Folded Reload -- GitLab From 92764c99e97ab2b347072718ba2a6799b3fe41c7 Mon Sep 17 00:00:00 2001 From: Shourya Goel <shouryagoel10000@gmail.com> Date: Tue, 19 Mar 2024 18:32:37 +0530 Subject: [PATCH 068/307] [DAG] Matched Fixedwidth Pattern for ISD::AVGCEILU (#85031) Fixes: #84753 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 21 +++++++++++++++++++ llvm/test/CodeGen/AArch64/hadd-combine.ll | 14 ++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index cce765c7c310..f199625bf67a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2529,6 +2529,23 @@ static SDValue foldAddSubBoolOfMaskedVal(SDNode *N, SelectionDAG &DAG) { return DAG.getNode(IsAdd ? ISD::SUB : ISD::ADD, DL, VT, C1, LowBit); } +// Attempt to form avgceilu(A, B) from (A | B) - ((A ^ B) >> 1) +static SDValue combineFixedwidthToAVGCEILU(SDNode *N, SelectionDAG &DAG) { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + SDValue N0 = N->getOperand(0); + EVT VT = N0.getValueType(); + SDLoc DL(N); + if (TLI.isOperationLegal(ISD::AVGCEILU, VT)) { + SDValue A, B; + if (sd_match(N, m_Sub(m_Or(m_Value(A), m_Value(B)), + m_Srl(m_Xor(m_Deferred(A), m_Deferred(B)), + m_SpecificInt(1))))) { + return DAG.getNode(ISD::AVGCEILU, DL, VT, A, B); + } + } + return SDValue(); +} + /// Try to fold a 'not' shifted sign-bit with add/sub with constant operand into /// a shift and add with a different constant. static SDValue foldAddSubOfSignBit(SDNode *N, SelectionDAG &DAG) { @@ -3849,6 +3866,10 @@ SDValue DAGCombiner::visitSUB(SDNode *N) { if (SDValue V = foldAddSubOfSignBit(N, DAG)) return V; + // Try to match AVGCEILU fixedwidth pattern + if (SDValue V = combineFixedwidthToAVGCEILU(N, DAG)) + return V; + if (SDValue V = foldAddSubMasked1(false, N0, N1, DAG, SDLoc(N))) return V; diff --git a/llvm/test/CodeGen/AArch64/hadd-combine.ll b/llvm/test/CodeGen/AArch64/hadd-combine.ll index b035ba03529c..e12502980790 100644 --- a/llvm/test/CodeGen/AArch64/hadd-combine.ll +++ b/llvm/test/CodeGen/AArch64/hadd-combine.ll @@ -329,9 +329,17 @@ define <8 x i16> @hadds_i_undef(<8 x i16> %t, <8 x i16> %src1) { ret <8 x i16> %result } - - - +define <8 x i16> @sub_fixedwidth_v4i32(<8 x i16> %a0, <8 x i16> %a1) { +; CHECK-LABEL: sub_fixedwidth_v4i32: +; CHECK: // %bb.0: +; CHECK-NEXT: urhadd v0.8h, v0.8h, v1.8h +; CHECK-NEXT: ret + %or = or <8 x i16> %a0, %a1 + %xor = xor <8 x i16> %a0, %a1 + %srl = lshr <8 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = sub <8 x i16> %or, %srl + ret <8 x i16> %res +} define <8 x i16> @rhaddu_base(<8 x i16> %src1, <8 x i16> %src2) { ; CHECK-LABEL: rhaddu_base: -- GitLab From 930f21c6bc0fe05c1d08be6353f7c7c6c51f4dc0 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Tue, 19 Mar 2024 14:02:27 +0100 Subject: [PATCH 069/307] [bazel] Trim TransformDialectInterfaces to the bare minimum --- utils/bazel/llvm-project-overlay/mlir/BUILD.bazel | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel index da1d111b0a94..57d4e1a91f06 100644 --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -12067,12 +12067,14 @@ gentbl_cc_library( cc_library( name = "TransformDialectInterfaces", # FIXME: Change this once https://github.com/llvm/llvm-project/pull/85221 lands - hdrs = glob(["include/mlir/Dialect/Transform/IR/*.h"]), + hdrs = [ + "include/mlir/Dialect/Transform/IR/TransformInterfaces.h", + "include/mlir/Dialect/Transform/IR/TransformTypes.h", + ], deps = [ ":CastInterfaces", ":IR", ":Rewrite", - ":SideEffectInterfaces", ":Support", ":TransformDialectInterfacesIncGen", ":TransformDialectUtils", -- GitLab From e9da5f0083d12a7284c780e916c17b6a2785933e Mon Sep 17 00:00:00 2001 From: Akash Banerjee <akash.banerjee@amd.com> Date: Tue, 19 Mar 2024 13:04:23 +0000 Subject: [PATCH 070/307] [OpenMP] Fix target data region codegen being omitted for device pass (#85218) This patch enables the BodyCodeGen callback to still trigger for the TargetData nested region during the device pass. There maybe Target code nested within the TargetData region for which this is required. Also add tests for the same. --- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 5 ++- .../Frontend/OpenMPIRBuilderTest.cpp | 17 ++++++++++ .../fortran/target-nested-target-data.f90 | 31 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 openmp/libomptarget/test/offloading/fortran/target-nested-target-data.f90 diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index c74c898e1e88..c07ee34bfb7a 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -4883,8 +4883,11 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createTargetData( return InsertPointTy(); // Disable TargetData CodeGen on Device pass. - if (Config.IsTargetDevice.value_or(false)) + if (Config.IsTargetDevice.value_or(false)) { + if (BodyGenCB) + Builder.restoreIP(BodyGenCB(Builder.saveIP(), BodyGenTy::NoPriv)); return Builder.saveIP(); + } Builder.restoreIP(CodeGenIP); bool IsStandAlone = !BodyGenCB; diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp index fdbe8df783b1..5c415cadcd68 100644 --- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp +++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp @@ -5856,6 +5856,23 @@ TEST_F(OpenMPIRBuilderTest, TargetDataRegion) { EXPECT_TRUE(TargetDataCall->getOperand(2)->getType()->isIntegerTy(32)); EXPECT_TRUE(TargetDataCall->getOperand(8)->getType()->isPointerTy()); + // Check that BodyGenCB is still made when IsTargetDevice is set to true. + OMPBuilder.Config.setIsTargetDevice(true); + bool CheckDevicePassBodyGen = false; + auto BodyTargetCB = [&](InsertPointTy CodeGenIP, BodyGenTy BodyGenType) { + CheckDevicePassBodyGen = true; + Builder.restoreIP(CodeGenIP); + CallInst *TargetDataCall = + dyn_cast<CallInst>(BB->back().getPrevNode()->getPrevNode()); + // Make sure no begin_mapper call is present for device pass. + EXPECT_EQ(TargetDataCall, nullptr); + return Builder.saveIP(); + }; + Builder.restoreIP(OMPBuilder.createTargetData( + Loc, AllocaIP, Builder.saveIP(), Builder.getInt64(DeviceID), + /* IfCond= */ nullptr, Info, GenMapInfoCB, nullptr, BodyTargetCB)); + EXPECT_TRUE(CheckDevicePassBodyGen); + Builder.CreateRetVoid(); EXPECT_FALSE(verifyModule(*M, &errs())); } diff --git a/openmp/libomptarget/test/offloading/fortran/target-nested-target-data.f90 b/openmp/libomptarget/test/offloading/fortran/target-nested-target-data.f90 new file mode 100644 index 000000000000..a694f2464546 --- /dev/null +++ b/openmp/libomptarget/test/offloading/fortran/target-nested-target-data.f90 @@ -0,0 +1,31 @@ +! Offloading test for target nested inside +! a target data region +! REQUIRES: flang +! UNSUPPORTED: nvptx64-nvidia-cuda-LTO +! UNSUPPORTED: aarch64-unknown-linux-gnu +! UNSUPPORTED: aarch64-unknown-linux-gnu-LTO +! UNSUPPORTED: x86_64-pc-linux-gnu +! UNSUPPORTED: x86_64-pc-linux-gnu-LTO + +! RUN: %libomptarget-compile-fortran-run-and-check-generic +program main + integer :: A(10), B(10), C(10) + + do I = 1, 10 + A(I) = 1 + B(I) = 2 + end do + !$omp target data map(to: A, B) map(alloc: C) + !$omp target map(from: C) + do I = 1, 10 + C(I) = A(I) + B(I) ! assigns 3, A:1 + B:2 + end do + !$omp end target + !$omp target update from(C) ! updates C device -> host + !$omp end target data + + print *, C ! should be all 3's + +end program + +! CHECK: 3 3 3 3 3 3 3 3 3 3 -- GitLab From 335f3659820e2e771f5165d215300567be478b13 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand <ulrich.weigand@de.ibm.com> Date: Tue, 19 Mar 2024 11:14:57 +0100 Subject: [PATCH 071/307] Reapply: [SystemZ] Fix overflow flag for i128 USUBO We use the VSCBIQ/VSBIQ/VSBCBIQ family of instructions to implement USUBO/USUBO_CARRY for the i128 data type. However, these instructions use an inverted sense of the borrow indication flag (a value of 1 indicates *no* borrow, while a value of 0 indicated borrow). This does not match the semantics of the boolean "overflow" flag of the USUBO/USUBO_CARRY ISD nodes. Fix this by generating code to explicitly invert the flag. These cancel out of the result of USUBO feeds into an USUBO_CARRY. To avoid unnecessary zero-extend operations, also improve the DAGCombine handling of ZERO_EXTEND to optimize (zext (xor (trunc))) sequences where appropriate. Fixes: https://github.com/llvm/llvm-project/issues/83268 --- .../Target/SystemZ/SystemZISelLowering.cpp | 34 +++++++++++++++++++ llvm/test/CodeGen/SystemZ/int-usub-12.ll | 22 ++++++++++++ llvm/test/CodeGen/SystemZ/int-usub-13.ll | 2 ++ 3 files changed, 58 insertions(+) diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index 887c35a7ba24..bc60d14ee700 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -4263,6 +4263,7 @@ SDValue SystemZTargetLowering::lowerXALUO(SDValue Op, if (N->getValueType(0) == MVT::i128) { unsigned BaseOp = 0; unsigned FlagOp = 0; + bool IsBorrow = false; switch (Op.getOpcode()) { default: llvm_unreachable("Unknown instruction!"); case ISD::UADDO: @@ -4272,6 +4273,7 @@ SDValue SystemZTargetLowering::lowerXALUO(SDValue Op, case ISD::USUBO: BaseOp = ISD::SUB; FlagOp = SystemZISD::VSCBI; + IsBorrow = true; break; } SDValue Result = DAG.getNode(BaseOp, DL, MVT::i128, LHS, RHS); @@ -4279,6 +4281,9 @@ SDValue SystemZTargetLowering::lowerXALUO(SDValue Op, Flag = DAG.getNode(ISD::AssertZext, DL, MVT::i128, Flag, DAG.getValueType(MVT::i1)); Flag = DAG.getZExtOrTrunc(Flag, DL, N->getValueType(1)); + if (IsBorrow) + Flag = DAG.getNode(ISD::XOR, DL, Flag.getValueType(), + Flag, DAG.getConstant(1, DL, Flag.getValueType())); return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, Flag); } @@ -4351,6 +4356,7 @@ SDValue SystemZTargetLowering::lowerUADDSUBO_CARRY(SDValue Op, if (VT == MVT::i128) { unsigned BaseOp = 0; unsigned FlagOp = 0; + bool IsBorrow = false; switch (Op.getOpcode()) { default: llvm_unreachable("Unknown instruction!"); case ISD::UADDO_CARRY: @@ -4360,14 +4366,21 @@ SDValue SystemZTargetLowering::lowerUADDSUBO_CARRY(SDValue Op, case ISD::USUBO_CARRY: BaseOp = SystemZISD::VSBI; FlagOp = SystemZISD::VSBCBI; + IsBorrow = true; break; } + if (IsBorrow) + Carry = DAG.getNode(ISD::XOR, DL, Carry.getValueType(), + Carry, DAG.getConstant(1, DL, Carry.getValueType())); Carry = DAG.getZExtOrTrunc(Carry, DL, MVT::i128); SDValue Result = DAG.getNode(BaseOp, DL, MVT::i128, LHS, RHS, Carry); SDValue Flag = DAG.getNode(FlagOp, DL, MVT::i128, LHS, RHS, Carry); Flag = DAG.getNode(ISD::AssertZext, DL, MVT::i128, Flag, DAG.getValueType(MVT::i1)); Flag = DAG.getZExtOrTrunc(Flag, DL, N->getValueType(1)); + if (IsBorrow) + Flag = DAG.getNode(ISD::XOR, DL, Flag.getValueType(), + Flag, DAG.getConstant(1, DL, Flag.getValueType())); return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, Flag); } @@ -6619,6 +6632,27 @@ SDValue SystemZTargetLowering::combineZERO_EXTEND( return NewSelect; } } + // Convert (zext (xor (trunc X), C)) into (xor (trunc X), C') if the size + // of the result is smaller than the size of X and all the truncated bits + // of X are already zero. + if (N0.getOpcode() == ISD::XOR && + N0.hasOneUse() && N0.getOperand(0).hasOneUse() && + N0.getOperand(0).getOpcode() == ISD::TRUNCATE && + N0.getOperand(1).getOpcode() == ISD::Constant) { + SDValue X = N0.getOperand(0).getOperand(0); + if (VT.isScalarInteger() && VT.getSizeInBits() < X.getValueSizeInBits()) { + KnownBits Known = DAG.computeKnownBits(X); + APInt TruncatedBits = APInt::getBitsSet(X.getValueSizeInBits(), + N0.getValueSizeInBits(), + VT.getSizeInBits()); + if (TruncatedBits.isSubsetOf(Known.Zero)) { + X = DAG.getNode(ISD::TRUNCATE, SDLoc(X), VT, X); + APInt Mask = N0.getConstantOperandAPInt(1).zext(VT.getSizeInBits()); + return DAG.getNode(ISD::XOR, SDLoc(N0), VT, + X, DAG.getConstant(Mask, SDLoc(N0), VT)); + } + } + } // Fold into ATOMIC_LOAD unless it is already sign extending. if (auto *ALoad = dyn_cast<AtomicSDNode>(N0)) diff --git a/llvm/test/CodeGen/SystemZ/int-usub-12.ll b/llvm/test/CodeGen/SystemZ/int-usub-12.ll index c39a6da37048..147fbfd920a9 100644 --- a/llvm/test/CodeGen/SystemZ/int-usub-12.ll +++ b/llvm/test/CodeGen/SystemZ/int-usub-12.ll @@ -11,6 +11,7 @@ define zeroext i1 @f1(i128 %a, i128 %b, ptr %res) { ; CHECK-NEXT: vscbiq %v2, %v1, %v0 ; CHECK-NEXT: vlgvg %r2, %v2, 1 ; CHECK-NEXT: vsq %v0, %v1, %v0 +; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: vst %v0, 0(%r4), 3 ; CHECK-NEXT: br %r14 %t = call {i128, i1} @llvm.usub.with.overflow.i128(i128 %a, i128 %b) @@ -27,6 +28,7 @@ define zeroext i1 @f2(i128 %a, i128 %b) { ; CHECK-NEXT: vl %v1, 0(%r2), 3 ; CHECK-NEXT: vscbiq %v0, %v1, %v0 ; CHECK-NEXT: vlgvg %r2, %v0, 1 +; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: br %r14 %t = call {i128, i1} @llvm.usub.with.overflow.i128(i128 %a, i128 %b) %obit = extractvalue {i128, i1} %t, 1 @@ -46,5 +48,25 @@ define i128 @f3(i128 %a, i128 %b) { ret i128 %val } +define i128 @f4(i128 %a, i128 %b) { +; CHECK-LABEL: f4: +; CHECK: # %bb.0: +; CHECK-NEXT: vl %v0, 0(%r4), 3 +; CHECK-NEXT: vl %v1, 0(%r3), 3 +; CHECK-NEXT: vscbiq %v2, %v1, %v0 +; CHECK-NEXT: vlgvf %r0, %v2, 3 +; CHECK-NEXT: vgbm %v2, 0 +; CHECK-NEXT: xilf %r0, 1 +; CHECK-NEXT: jl .LBB3_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: vsq %v2, %v1, %v0 +; CHECK-NEXT: .LBB3_2: +; CHECK-NEXT: vst %v2, 0(%r2), 3 +; CHECK-NEXT: br %r14 + %val = call i128 @llvm.usub.sat.i128(i128 %a, i128 %b) + ret i128 %val +} + declare {i128, i1} @llvm.usub.with.overflow.i128(i128, i128) nounwind readnone +declare i128 @llvm.usub.sat.i128(i128, i128) nounwind readnone diff --git a/llvm/test/CodeGen/SystemZ/int-usub-13.ll b/llvm/test/CodeGen/SystemZ/int-usub-13.ll index 637e1a81de99..794af3b73fbe 100644 --- a/llvm/test/CodeGen/SystemZ/int-usub-13.ll +++ b/llvm/test/CodeGen/SystemZ/int-usub-13.ll @@ -15,6 +15,7 @@ define zeroext i1 @f1(i256 %a, i256 %b, ptr %res) { ; CHECK-NEXT: vlgvg %r2, %v5, 1 ; CHECK-NEXT: vsbiq %v0, %v1, %v0, %v4 ; CHECK-NEXT: vsq %v1, %v3, %v2 +; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: vst %v1, 16(%r4), 3 ; CHECK-NEXT: vst %v0, 0(%r4), 3 ; CHECK-NEXT: br %r14 @@ -35,6 +36,7 @@ define zeroext i1 @f2(i256 %a, i256 %b) { ; CHECK-NEXT: vscbiq %v2, %v3, %v2 ; CHECK-NEXT: vsbcbiq %v0, %v1, %v0, %v2 ; CHECK-NEXT: vlgvg %r2, %v0, 1 +; CHECK-NEXT: xilf %r2, 1 ; CHECK-NEXT: br %r14 %t = call {i256, i1} @llvm.usub.with.overflow.i256(i256 %a, i256 %b) %obit = extractvalue {i256, i1} %t, 1 -- GitLab From 175ad6630a869831126dde80f0f9257f9c4c477f Mon Sep 17 00:00:00 2001 From: NagyDonat <donat.nagy@ericsson.com> Date: Tue, 19 Mar 2024 14:12:27 +0100 Subject: [PATCH 072/307] [analyzer] Mention possibility of underflow in array overflow errors (#84201) The checker alpha.security.ArrayBoundV2 performs bounds checking in two steps: first it checks for underflow, and if it isn't guaranteed then it assumes that there is no underflow. After this, it checks for overflow, and if that's guaranteed or the index is tainted then it reports it. This meant that in situations where overflow and underflow are both possible (but the index is either tainted or guaranteed to be invalid), the checker was reporting just an overflow error. This commit modifies the messages printed in these cases to mention the possibility of an underflow. --------- Co-authored-by: Balazs Benics <benicsbalazs@gmail.com> --- .../Checkers/ArrayBoundCheckerV2.cpp | 43 +++++++++----- .../test/Analysis/out-of-bounds-diagnostics.c | 56 ++++++++++++++++++- .../test/Analysis/taint-diagnostic-visitor.c | 2 +- 3 files changed, 86 insertions(+), 15 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp index 29eb93258402..f82288f1099e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp @@ -83,6 +83,8 @@ public: AssumedUpperBound = UpperBoundVal; } + bool assumedNonNegative() { return AssumedNonNegative; } + const NoteTag *createNoteTag(CheckerContext &C) const; private: @@ -402,7 +404,8 @@ static bool tryDividePair(std::optional<int64_t> &Val1, } static Messages getExceedsMsgs(ASTContext &ACtx, const SubRegion *Region, - NonLoc Offset, NonLoc Extent, SVal Location) { + NonLoc Offset, NonLoc Extent, SVal Location, + bool AlsoMentionUnderflow) { std::string RegName = getRegionName(Region); const auto *EReg = Location.getAsRegion()->getAs<ElementRegion>(); assert(EReg && "this checker only handles element access"); @@ -414,6 +417,7 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const SubRegion *Region, int64_t ElemSize = ACtx.getTypeSizeInChars(ElemType).getQuantity(); bool UseByteOffsets = !tryDividePair(OffsetN, ExtentN, ElemSize); + const char *OffsetOrIndex = UseByteOffsets ? "byte offset" : "index"; SmallString<256> Buf; llvm::raw_svector_ostream Out(Buf); @@ -421,10 +425,12 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const SubRegion *Region, if (!ExtentN && !UseByteOffsets) Out << "'" << ElemType.getAsString() << "' element in "; Out << RegName << " at "; - if (OffsetN) { - Out << (UseByteOffsets ? "byte offset " : "index ") << *OffsetN; + if (AlsoMentionUnderflow) { + Out << "a negative or overflowing " << OffsetOrIndex; + } else if (OffsetN) { + Out << OffsetOrIndex << " " << *OffsetN; } else { - Out << "an overflowing " << (UseByteOffsets ? "byte offset" : "index"); + Out << "an overflowing " << OffsetOrIndex; } if (ExtentN) { Out << ", while it holds only "; @@ -441,17 +447,20 @@ static Messages getExceedsMsgs(ASTContext &ACtx, const SubRegion *Region, Out << "s"; } - return { - formatv("Out of bound access to memory after the end of {0}", RegName), - std::string(Buf)}; + return {formatv("Out of bound access to memory {0} {1}", + AlsoMentionUnderflow ? "around" : "after the end of", + RegName), + std::string(Buf)}; } -static Messages getTaintMsgs(const SubRegion *Region, const char *OffsetName) { +static Messages getTaintMsgs(const SubRegion *Region, const char *OffsetName, + bool AlsoMentionUnderflow) { std::string RegName = getRegionName(Region); return {formatv("Potential out of bound access to {0} with tainted {1}", RegName, OffsetName), - formatv("Access of {0} with a tainted {1} that may be too large", - RegName, OffsetName)}; + formatv("Access of {0} with a tainted {1} that may be {2}too large", + RegName, OffsetName, + AlsoMentionUnderflow ? "negative or " : "")}; } const NoteTag *StateUpdateReporter::createNoteTag(CheckerContext &C) const { @@ -600,6 +609,13 @@ void ArrayBoundCheckerV2::performCheck(const Expr *E, CheckerContext &C) const { // CHECK UPPER BOUND DefinedOrUnknownSVal Size = getDynamicExtent(State, Reg, SVB); if (auto KnownSize = Size.getAs<NonLoc>()) { + // In a situation where both overflow and overflow are possible (but the + // index is either tainted or known to be invalid), the logic of this + // checker will first assume that the offset is non-negative, and then + // (with this additional assumption) it will detect an overflow error. + // In this situation the warning message should mention both possibilities. + bool AlsoMentionUnderflow = SUR.assumedNonNegative(); + auto [WithinUpperBound, ExceedsUpperBound] = compareValueToThreshold(State, ByteOffset, *KnownSize, SVB); @@ -615,8 +631,9 @@ void ArrayBoundCheckerV2::performCheck(const Expr *E, CheckerContext &C) const { return; } - Messages Msgs = getExceedsMsgs(C.getASTContext(), Reg, ByteOffset, - *KnownSize, Location); + Messages Msgs = + getExceedsMsgs(C.getASTContext(), Reg, ByteOffset, *KnownSize, + Location, AlsoMentionUnderflow); reportOOB(C, ExceedsUpperBound, Msgs, ByteOffset, KnownSize); return; } @@ -632,7 +649,7 @@ void ArrayBoundCheckerV2::performCheck(const Expr *E, CheckerContext &C) const { if (isTainted(State, ASE->getIdx(), C.getLocationContext())) OffsetName = "index"; - Messages Msgs = getTaintMsgs(Reg, OffsetName); + Messages Msgs = getTaintMsgs(Reg, OffsetName, AlsoMentionUnderflow); reportOOB(C, ExceedsUpperBound, Msgs, ByteOffset, KnownSize, /*IsTaintBug=*/true); return; diff --git a/clang/test/Analysis/out-of-bounds-diagnostics.c b/clang/test/Analysis/out-of-bounds-diagnostics.c index 0c3c67c6a546..92f983d8b156 100644 --- a/clang/test/Analysis/out-of-bounds-diagnostics.c +++ b/clang/test/Analysis/out-of-bounds-diagnostics.c @@ -24,6 +24,33 @@ void taintedIndex(void) { scanf("%d", &index); // expected-note@-1 {{Taint originated here}} // expected-note@-2 {{Taint propagated to the 2nd argument}} + TenElements[index] = 5; + // expected-warning@-1 {{Potential out of bound access to 'TenElements' with tainted index}} + // expected-note@-2 {{Access of 'TenElements' with a tainted index that may be negative or too large}} +} + +void taintedIndexNonneg(void) { + int index; + scanf("%d", &index); + // expected-note@-1 {{Taint originated here}} + // expected-note@-2 {{Taint propagated to the 2nd argument}} + + // expected-note@+2 {{Assuming 'index' is >= 0}} + // expected-note@+1 {{Taking false branch}} + if (index < 0) + return; + + TenElements[index] = 5; + // expected-warning@-1 {{Potential out of bound access to 'TenElements' with tainted index}} + // expected-note@-2 {{Access of 'TenElements' with a tainted index that may be too large}} +} + +void taintedIndexUnsigned(void) { + unsigned index; + scanf("%u", &index); + // expected-note@-1 {{Taint originated here}} + // expected-note@-2 {{Taint propagated to the 2nd argument}} + TenElements[index] = 5; // expected-warning@-1 {{Potential out of bound access to 'TenElements' with tainted index}} // expected-note@-2 {{Access of 'TenElements' with a tainted index that may be too large}} @@ -59,7 +86,7 @@ void taintedOffset(void) { int *p = TenElements + index; p[0] = 5; // expected-warning@-1 {{Potential out of bound access to 'TenElements' with tainted offset}} - // expected-note@-2 {{Access of 'TenElements' with a tainted offset that may be too large}} + // expected-note@-2 {{Access of 'TenElements' with a tainted offset that may be negative or too large}} } void arrayOverflow(void) { @@ -109,6 +136,33 @@ int *potentialAfterTheEndPtr(int idx) { // &TenElements[idx]. } +int overflowOrUnderflow(int arg) { + // expected-note@+2 {{Assuming 'arg' is < 0}} + // expected-note@+1 {{Taking false branch}} + if (arg >= 0) + return 0; + + return TenElements[arg - 1]; + // expected-warning@-1 {{Out of bound access to memory around 'TenElements'}} + // expected-note@-2 {{Access of 'TenElements' at a negative or overflowing index, while it holds only 10 'int' elements}} +} + +char TwoElements[2] = {11, 22}; +char overflowOrUnderflowConcrete(int arg) { + // expected-note@#cond {{Assuming 'arg' is < 3}} + // expected-note@#cond {{Left side of '||' is false}} + // expected-note@#cond {{Assuming 'arg' is not equal to 0}} + // expected-note@#cond {{Left side of '||' is false}} + // expected-note@#cond {{Assuming 'arg' is not equal to 1}} + // expected-note@#cond {{Taking false branch}} + if (arg >= 3 || arg == 0 || arg == 1) // #cond + return 0; + + return TwoElements[arg]; + // expected-warning@-1 {{Out of bound access to memory around 'TwoElements'}} + // expected-note@-2 {{Access of 'TwoElements' at a negative or overflowing index, while it holds only 2 'char' elements}} +} + int scalar; int scalarOverflow(void) { return (&scalar)[1]; diff --git a/clang/test/Analysis/taint-diagnostic-visitor.c b/clang/test/Analysis/taint-diagnostic-visitor.c index 020e9579ac53..2ba7d9938fc3 100644 --- a/clang/test/Analysis/taint-diagnostic-visitor.c +++ b/clang/test/Analysis/taint-diagnostic-visitor.c @@ -30,7 +30,7 @@ int taintDiagnosticOutOfBound(void) { scanf("%d", &index); // expected-note {{Taint originated here}} // expected-note@-1 {{Taint propagated to the 2nd argument}} return Array[index]; // expected-warning {{Potential out of bound access to 'Array' with tainted index}} - // expected-note@-1 {{Access of 'Array' with a tainted index that may be too large}} + // expected-note@-1 {{Access of 'Array' with a tainted index}} } int taintDiagnosticDivZero(int operand) { -- GitLab From 4b10d1fdd31f46a9cdf3e7a196f9934d766a922f Mon Sep 17 00:00:00 2001 From: Zack Johnson <zacklj89@gmail.com> Date: Tue, 19 Mar 2024 09:16:18 -0400 Subject: [PATCH 073/307] [compiler-rt] Fixing UB on Windows for trampoline allocations (#85639) Fixing the type of the constant to avoid undefined behavior with respect to overflow. --- compiler-rt/lib/interception/interception_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp index 1829358705fe..a04175ba1e4b 100644 --- a/compiler-rt/lib/interception/interception_win.cpp +++ b/compiler-rt/lib/interception/interception_win.cpp @@ -339,7 +339,7 @@ struct TrampolineMemoryRegion { uptr max_size; }; -UNUSED static const uptr kTrampolineScanLimitRange = 1 << 31; // 2 gig +UNUSED static const uptr kTrampolineScanLimitRange = 1ull << 31; // 2 gig static const int kMaxTrampolineRegion = 1024; static TrampolineMemoryRegion TrampolineRegions[kMaxTrampolineRegion]; -- GitLab From 9f80444c2e669237a5c92013f1a42b91b5609012 Mon Sep 17 00:00:00 2001 From: Sergio Afonso <safonsof@amd.com> Date: Tue, 19 Mar 2024 13:25:33 +0000 Subject: [PATCH 074/307] Revert "[Flang][OpenMP][Lower] NFC: Move clause processing helpers into the ClauseProcessor (#85258)" Reverting due to failing gfortran test. This reverts commit 2f2f16f32bb2a6c250b19adbc229d9dc3b38640c. --- flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 31 +--------- flang/lib/Lower/OpenMP/ClauseProcessor.h | 15 ++--- flang/lib/Lower/OpenMP/OpenMP.cpp | 72 +++++++++++++++++++--- flang/lib/Lower/OpenMP/Utils.cpp | 19 ------ flang/lib/Lower/OpenMP/Utils.h | 3 - 5 files changed, 74 insertions(+), 66 deletions(-) diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 81919f2a4896..13347c8cf7b6 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -208,25 +208,6 @@ addUseDeviceClause(Fortran::lower::AbstractConverter &converter, useDeviceSymbols.push_back(object.id()); } -static void convertLoopBounds(Fortran::lower::AbstractConverter &converter, - mlir::Location loc, - llvm::SmallVectorImpl<mlir::Value> &lowerBound, - llvm::SmallVectorImpl<mlir::Value> &upperBound, - llvm::SmallVectorImpl<mlir::Value> &step, - std::size_t loopVarTypeSize) { - fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - // The types of lower bound, upper bound, and step are converted into the - // type of the loop variable if necessary. - mlir::Type loopVarType = getLoopVarType(converter, loopVarTypeSize); - for (unsigned it = 0; it < (unsigned)lowerBound.size(); it++) { - lowerBound[it] = - firOpBuilder.createConvert(loc, loopVarType, lowerBound[it]); - upperBound[it] = - firOpBuilder.createConvert(loc, loopVarType, upperBound[it]); - step[it] = firOpBuilder.createConvert(loc, loopVarType, step[it]); - } -} - //===----------------------------------------------------------------------===// // ClauseProcessor unique clauses //===----------------------------------------------------------------------===// @@ -236,7 +217,8 @@ bool ClauseProcessor::processCollapse( llvm::SmallVectorImpl<mlir::Value> &lowerBound, llvm::SmallVectorImpl<mlir::Value> &upperBound, llvm::SmallVectorImpl<mlir::Value> &step, - llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> &iv) const { + llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> &iv, + std::size_t &loopVarTypeSize) const { bool found = false; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); @@ -254,7 +236,7 @@ bool ClauseProcessor::processCollapse( found = true; } - std::size_t loopVarTypeSize = 0; + loopVarTypeSize = 0; do { Fortran::lower::pft::Evaluation *doLoop = &doConstructEval->getFirstNestedEvaluation(); @@ -285,9 +267,6 @@ bool ClauseProcessor::processCollapse( &*std::next(doConstructEval->getNestedEvaluations().begin()); } while (collapseValue > 0); - convertLoopBounds(converter, currentLocation, lowerBound, upperBound, step, - loopVarTypeSize); - return found; } @@ -928,7 +907,6 @@ bool ClauseProcessor::processMap( bool ClauseProcessor::processReduction( mlir::Location currentLocation, llvm::SmallVectorImpl<mlir::Value> &reductionVars, - llvm::SmallVectorImpl<mlir::Type> &reductionTypes, llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols, llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *reductionSymbols) const { @@ -938,9 +916,6 @@ bool ClauseProcessor::processReduction( ReductionProcessor rp; rp.addReductionDecl(currentLocation, converter, clause, reductionVars, reductionDeclSymbols, reductionSymbols); - reductionTypes.reserve(reductionVars.size()); - llvm::transform(reductionVars, std::back_inserter(reductionTypes), - [](mlir::Value v) { return v.getType(); }); }); } diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index 3f50909fe73a..3f6adcce8ae8 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -56,12 +56,14 @@ public: clauses(makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. - bool processCollapse( - mlir::Location currentLocation, Fortran::lower::pft::Evaluation &eval, - llvm::SmallVectorImpl<mlir::Value> &lowerBound, - llvm::SmallVectorImpl<mlir::Value> &upperBound, - llvm::SmallVectorImpl<mlir::Value> &step, - llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> &iv) const; + bool + processCollapse(mlir::Location currentLocation, + Fortran::lower::pft::Evaluation &eval, + llvm::SmallVectorImpl<mlir::Value> &lowerBound, + llvm::SmallVectorImpl<mlir::Value> &upperBound, + llvm::SmallVectorImpl<mlir::Value> &step, + llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> &iv, + std::size_t &loopVarTypeSize) const; bool processDefault() const; bool processDevice(Fortran::lower::StatementContext &stmtCtx, mlir::Value &result) const; @@ -124,7 +126,6 @@ public: bool processReduction(mlir::Location currentLocation, llvm::SmallVectorImpl<mlir::Value> &reductionVars, - llvm::SmallVectorImpl<mlir::Type> &reductionTypes, llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols, llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *reductionSymbols = nullptr) const; diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index dbdb6f1a453b..eaaa8fcd165a 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -214,6 +214,24 @@ static void threadPrivatizeVars(Fortran::lower::AbstractConverter &converter, firOpBuilder.restoreInsertionPoint(insPt); } +static mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter, + std::size_t loopVarTypeSize) { + // OpenMP runtime requires 32-bit or 64-bit loop variables. + loopVarTypeSize = loopVarTypeSize * 8; + if (loopVarTypeSize < 32) { + loopVarTypeSize = 32; + } else if (loopVarTypeSize > 64) { + loopVarTypeSize = 64; + mlir::emitWarning(converter.getCurrentLocation(), + "OpenMP loop iteration variable cannot have more than 64 " + "bits size and will be narrowed into 64 bits."); + } + assert((loopVarTypeSize == 32 || loopVarTypeSize == 64) && + "OpenMP loop iteration variable size must be transformed into 32-bit " + "or 64-bit"); + return converter.getFirOpBuilder().getIntegerType(loopVarTypeSize); +} + static mlir::Operation * createAndSetPrivatizedLoopVar(Fortran::lower::AbstractConverter &converter, mlir::Location loc, mlir::Value indexVal, @@ -550,7 +568,6 @@ genParallelOp(Fortran::lower::AbstractConverter &converter, mlir::omp::ClauseProcBindKindAttr procBindKindAttr; llvm::SmallVector<mlir::Value> allocateOperands, allocatorOperands, reductionVars; - llvm::SmallVector<mlir::Type> reductionTypes; llvm::SmallVector<mlir::Attribute> reductionDeclSymbols; llvm::SmallVector<const Fortran::semantics::Symbol *> reductionSymbols; @@ -561,8 +578,13 @@ genParallelOp(Fortran::lower::AbstractConverter &converter, cp.processDefault(); cp.processAllocate(allocatorOperands, allocateOperands); if (!outerCombined) - cp.processReduction(currentLocation, reductionVars, reductionTypes, - reductionDeclSymbols, &reductionSymbols); + cp.processReduction(currentLocation, reductionVars, reductionDeclSymbols, + &reductionSymbols); + + llvm::SmallVector<mlir::Type> reductionTypes; + reductionTypes.reserve(reductionVars.size()); + llvm::transform(reductionVars, std::back_inserter(reductionTypes), + [](mlir::Value v) { return v.getType(); }); auto reductionCallback = [&](mlir::Operation *op) { llvm::SmallVector<mlir::Location> locs(reductionVars.size(), @@ -1446,6 +1468,25 @@ genOMP(Fortran::lower::AbstractConverter &converter, standaloneConstruct.u); } +static void convertLoopBounds(Fortran::lower::AbstractConverter &converter, + mlir::Location loc, + llvm::SmallVectorImpl<mlir::Value> &lowerBound, + llvm::SmallVectorImpl<mlir::Value> &upperBound, + llvm::SmallVectorImpl<mlir::Value> &step, + std::size_t loopVarTypeSize) { + fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); + // The types of lower bound, upper bound, and step are converted into the + // type of the loop variable if necessary. + mlir::Type loopVarType = getLoopVarType(converter, loopVarTypeSize); + for (unsigned it = 0; it < (unsigned)lowerBound.size(); it++) { + lowerBound[it] = + firOpBuilder.createConvert(loc, loopVarType, lowerBound[it]); + upperBound[it] = + firOpBuilder.createConvert(loc, loopVarType, upperBound[it]); + step[it] = firOpBuilder.createConvert(loc, loopVarType, step[it]); + } +} + static llvm::SmallVector<const Fortran::semantics::Symbol *> genLoopVars(mlir::Operation *op, Fortran::lower::AbstractConverter &converter, mlir::Location &loc, @@ -1541,15 +1582,16 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter, llvm::SmallVector<mlir::Value> lowerBound, upperBound, step, reductionVars; llvm::SmallVector<mlir::Value> alignedVars, nontemporalVars; llvm::SmallVector<const Fortran::semantics::Symbol *> iv; - llvm::SmallVector<mlir::Type> reductionTypes; llvm::SmallVector<mlir::Attribute> reductionDeclSymbols; mlir::omp::ClauseOrderKindAttr orderClauseOperand; mlir::IntegerAttr simdlenClauseOperand, safelenClauseOperand; + std::size_t loopVarTypeSize; ClauseProcessor cp(converter, semaCtx, loopOpClauseList); - cp.processCollapse(loc, eval, lowerBound, upperBound, step, iv); + cp.processCollapse(loc, eval, lowerBound, upperBound, step, iv, + loopVarTypeSize); cp.processScheduleChunk(stmtCtx, scheduleChunkClauseOperand); - cp.processReduction(loc, reductionVars, reductionTypes, reductionDeclSymbols); + cp.processReduction(loc, reductionVars, reductionDeclSymbols); cp.processIf(clause::If::DirectiveNameModifier::Simd, ifClauseOperand); cp.processSimdlen(simdlenClauseOperand); cp.processSafelen(safelenClauseOperand); @@ -1559,6 +1601,9 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter, Fortran::parser::OmpClause::Nontemporal, Fortran::parser::OmpClause::Order>(loc, ompDirective); + convertLoopBounds(converter, loc, lowerBound, upperBound, step, + loopVarTypeSize); + mlir::TypeRange resultType; auto simdLoopOp = firOpBuilder.create<mlir::omp::SimdLoopOp>( loc, resultType, lowerBound, upperBound, step, alignedVars, @@ -1596,7 +1641,6 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, llvm::SmallVector<mlir::Value> lowerBound, upperBound, step, reductionVars; llvm::SmallVector<mlir::Value> linearVars, linearStepVars; llvm::SmallVector<const Fortran::semantics::Symbol *> iv; - llvm::SmallVector<mlir::Type> reductionTypes; llvm::SmallVector<mlir::Attribute> reductionDeclSymbols; llvm::SmallVector<const Fortran::semantics::Symbol *> reductionSymbols; mlir::omp::ClauseOrderKindAttr orderClauseOperand; @@ -1604,15 +1648,20 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, mlir::UnitAttr nowaitClauseOperand, byrefOperand, scheduleSimdClauseOperand; mlir::IntegerAttr orderedClauseOperand; mlir::omp::ScheduleModifierAttr scheduleModClauseOperand; + std::size_t loopVarTypeSize; ClauseProcessor cp(converter, semaCtx, beginClauseList); - cp.processCollapse(loc, eval, lowerBound, upperBound, step, iv); + cp.processCollapse(loc, eval, lowerBound, upperBound, step, iv, + loopVarTypeSize); cp.processScheduleChunk(stmtCtx, scheduleChunkClauseOperand); - cp.processReduction(loc, reductionVars, reductionTypes, reductionDeclSymbols, + cp.processReduction(loc, reductionVars, reductionDeclSymbols, &reductionSymbols); cp.processTODO<Fortran::parser::OmpClause::Linear, Fortran::parser::OmpClause::Order>(loc, ompDirective); + convertLoopBounds(converter, loc, lowerBound, upperBound, step, + loopVarTypeSize); + if (ReductionProcessor::doReductionByRef(reductionVars)) byrefOperand = firOpBuilder.getUnitAttr(); @@ -1653,6 +1702,11 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, auto *nestedEval = getCollapsedLoopEval( eval, Fortran::lower::getCollapseValue(beginClauseList)); + llvm::SmallVector<mlir::Type> reductionTypes; + reductionTypes.reserve(reductionVars.size()); + llvm::transform(reductionVars, std::back_inserter(reductionTypes), + [](mlir::Value v) { return v.getType(); }); + auto ivCallback = [&](mlir::Operation *op) { return genLoopAndReductionVars(op, converter, loc, iv, reductionSymbols, reductionTypes); diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp index b9c0660aa4da..fa4a51e33848 100644 --- a/flang/lib/Lower/OpenMP/Utils.cpp +++ b/flang/lib/Lower/OpenMP/Utils.cpp @@ -15,7 +15,6 @@ #include <flang/Lower/AbstractConverter.h> #include <flang/Lower/ConvertType.h> -#include <flang/Optimizer/Builder/FIRBuilder.h> #include <flang/Parser/parse-tree.h> #include <flang/Parser/tools.h> #include <flang/Semantics/tools.h> @@ -71,24 +70,6 @@ void genObjectList2(const Fortran::parser::OmpObjectList &objectList, } } -mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter, - std::size_t loopVarTypeSize) { - // OpenMP runtime requires 32-bit or 64-bit loop variables. - loopVarTypeSize = loopVarTypeSize * 8; - if (loopVarTypeSize < 32) { - loopVarTypeSize = 32; - } else if (loopVarTypeSize > 64) { - loopVarTypeSize = 64; - mlir::emitWarning(converter.getCurrentLocation(), - "OpenMP loop iteration variable cannot have more than 64 " - "bits size and will be narrowed into 64 bits."); - } - assert((loopVarTypeSize == 32 || loopVarTypeSize == 64) && - "OpenMP loop iteration variable size must be transformed into 32-bit " - "or 64-bit"); - return converter.getFirOpBuilder().getIntegerType(loopVarTypeSize); -} - void gatherFuncAndVarSyms( const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause, llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause) { diff --git a/flang/lib/Lower/OpenMP/Utils.h b/flang/lib/Lower/OpenMP/Utils.h index 4074bf73987d..3ab0823a4621 100644 --- a/flang/lib/Lower/OpenMP/Utils.h +++ b/flang/lib/Lower/OpenMP/Utils.h @@ -51,9 +51,6 @@ createMapInfoOp(fir::FirOpBuilder &builder, mlir::Location loc, mlir::omp::VariableCaptureKind mapCaptureType, mlir::Type retTy, bool isVal = false); -mlir::Type getLoopVarType(Fortran::lower::AbstractConverter &converter, - std::size_t loopVarTypeSize); - void gatherFuncAndVarSyms( const ObjectList &objects, mlir::omp::DeclareTargetCaptureClause clause, llvm::SmallVectorImpl<DeclareTargetCapturePair> &symbolAndClause); -- GitLab From 94c6ce1de92f56879cad1bfa12ba23ef0ecfcd91 Mon Sep 17 00:00:00 2001 From: Nikita Popov <npopov@redhat.com> Date: Tue, 19 Mar 2024 14:26:52 +0100 Subject: [PATCH 075/307] [SLPVectorizer] Use IRBuilderBase where possible (NFC) Instead of hardcoding a specific IRBuilder type, use the base class. --- llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 6dbd54069bb9..f2ac060a2e3a 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -11677,7 +11677,7 @@ Value *BoUpSLP::createBuildVector(const TreeEntry *E) { } Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { - IRBuilder<>::InsertPointGuard Guard(Builder); + IRBuilderBase::InsertPointGuard Guard(Builder); if (E->VectorizedValue && (E->State != TreeEntry::Vectorize || E->getOpcode() != Instruction::PHI || @@ -12700,7 +12700,7 @@ Value *BoUpSLP::vectorizeTree( auto Key = std::make_pair(Vec, ScalarTy); auto VecIt = VectorCasts.find(Key); if (VecIt == VectorCasts.end()) { - IRBuilder<>::InsertPointGuard Guard(Builder); + IRBuilderBase::InsertPointGuard Guard(Builder); if (auto *IVec = dyn_cast<Instruction>(Vec)) Builder.SetInsertPoint(IVec->getNextNonDebugInstruction()); Vec = Builder.CreateIntCast( @@ -14689,7 +14689,7 @@ class HorizontalReduction { } /// Creates reduction operation with the current opcode. - static Value *createOp(IRBuilder<> &Builder, RecurKind Kind, Value *LHS, + static Value *createOp(IRBuilderBase &Builder, RecurKind Kind, Value *LHS, Value *RHS, const Twine &Name, bool UseSelect) { unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(Kind); bool IsConstant = isConstant(LHS) && isConstant(RHS); @@ -14768,7 +14768,7 @@ class HorizontalReduction { /// Creates reduction operation with the current opcode with the IR flags /// from \p ReductionOps, dropping nuw/nsw flags. - static Value *createOp(IRBuilder<> &Builder, RecurKind RdxKind, Value *LHS, + static Value *createOp(IRBuilderBase &Builder, RecurKind RdxKind, Value *LHS, Value *RHS, const Twine &Name, const ReductionOpsListType &ReductionOps) { bool UseSelect = @@ -15857,7 +15857,7 @@ private: } /// Emit a horizontal reduction of the vectorized value. - Value *emitReduction(Value *VectorizedValue, IRBuilder<> &Builder, + Value *emitReduction(Value *VectorizedValue, IRBuilderBase &Builder, unsigned ReduxWidth, const TargetTransformInfo *TTI) { assert(VectorizedValue && "Need to have a vectorized tree node"); assert(isPowerOf2_32(ReduxWidth) && -- GitLab From 835c1b56a82542d91c337e24140bd2b08a7bf715 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams <orlando.hyams@sony.com> Date: Tue, 19 Mar 2024 13:28:43 +0000 Subject: [PATCH 076/307] [RemoveDIs] Auto-upgrade debug intrinsics to DbgRecords (default false) (#85650) If --load-bitcode-into-experimental-debuginfo-iterators is true then debug intrinsics are auto-upgraded to DbgRecords (the new debug info format). The upgrade is trivial because the two representations are semantically identical. llvm.dbg.value with 4 operands and llvm.dbg.addr intrinsics are upgraded in the same way as usual, but converted directly into DbgRecords instead of debug intrinsics. --- llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 26 +++++--- llvm/lib/IR/AutoUpgrade.cpp | 70 ++++++++++++++++++++- llvm/test/Bitcode/DIExpression-aggresult.ll | 1 + llvm/test/Bitcode/dbg-record-roundtrip.ll | 5 ++ llvm/test/Bitcode/upgrade-dbg-addr.ll | 1 + 5 files changed, 93 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 3807320e7f17..fb005ee826ec 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -609,17 +609,25 @@ class MetadataLoader::MetadataLoaderImpl { if (!NeedDeclareExpressionUpgrade) return; + auto UpdateDeclareIfNeeded = [&](auto *Declare) { + auto *DIExpr = Declare->getExpression(); + if (!DIExpr || !DIExpr->startsWithDeref() || + !isa_and_nonnull<Argument>(Declare->getAddress())) + return; + SmallVector<uint64_t, 8> Ops; + Ops.append(std::next(DIExpr->elements_begin()), DIExpr->elements_end()); + Declare->setExpression(DIExpression::get(Context, Ops)); + }; + for (auto &BB : F) - for (auto &I : BB) + for (auto &I : BB) { + for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { + if (DPV.isDbgDeclare()) + UpdateDeclareIfNeeded(&DPV); + } if (auto *DDI = dyn_cast<DbgDeclareInst>(&I)) - if (auto *DIExpr = DDI->getExpression()) - if (DIExpr->startsWithDeref() && - isa_and_nonnull<Argument>(DDI->getAddress())) { - SmallVector<uint64_t, 8> Ops; - Ops.append(std::next(DIExpr->elements_begin()), - DIExpr->elements_end()); - DDI->setExpression(DIExpression::get(Context, Ops)); - } + UpdateDeclareIfNeeded(DDI); + } } /// Upgrade the expression from previous versions. diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index dbea4529456c..c28a291c449c 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -1056,6 +1056,18 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } case 'd': if (Name.consume_front("dbg.")) { + // Mark debug intrinsics for upgrade to new debug format. + if (F->getParent()->IsNewDbgInfoFormat) { + if (Name == "addr" || Name == "value" || Name == "assign" || + Name == "declare" || Name == "label") { + // There's no function to replace these with. + NewFn = nullptr; + // But we do want these to get upgraded. + return true; + } + } + // Update llvm.dbg.addr intrinsics even in "new debug mode"; they'll get + // converted to DPValues later. if (Name == "addr" || (Name == "value" && F->arg_size() == 4)) { rename(F); NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_value); @@ -2332,6 +2344,59 @@ static Value *upgradeAMDGCNIntrinsicCall(StringRef Name, CallBase *CI, llvm_unreachable("Unknown function for AMDGPU intrinsic upgrade."); } +/// Helper to unwrap intrinsic call MetadataAsValue operands. +template <typename MDType> +static MDType *unwrapMAVOp(CallBase *CI, unsigned Op) { + if (MetadataAsValue *MAV = dyn_cast<MetadataAsValue>(CI->getArgOperand(Op))) + return dyn_cast<MDType>(MAV->getMetadata()); + return nullptr; +} + +/// Convert debug intrinsic calls to non-instruction debug records. +/// \p Name - Final part of the intrinsic name, e.g. 'value' in llvm.dbg.value. +/// \p CI - The debug intrinsic call. +static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) { + DbgRecord *DR = nullptr; + if (Name == "label") { + DR = new DPLabel(unwrapMAVOp<DILabel>(CI, 0), CI->getDebugLoc()); + } else if (Name == "assign") { + DR = new DPValue( + unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, 1), + unwrapMAVOp<DIExpression>(CI, 2), unwrapMAVOp<DIAssignID>(CI, 3), + unwrapMAVOp<Metadata>(CI, 4), unwrapMAVOp<DIExpression>(CI, 5), + CI->getDebugLoc()); + } else if (Name == "declare") { + DR = new DPValue(unwrapMAVOp<Metadata>(CI, 0), + unwrapMAVOp<DILocalVariable>(CI, 1), + unwrapMAVOp<DIExpression>(CI, 2), CI->getDebugLoc(), + DPValue::LocationType::Declare); + } else if (Name == "addr") { + // Upgrade dbg.addr to dbg.value with DW_OP_deref. + DIExpression *Expr = unwrapMAVOp<DIExpression>(CI, 2); + Expr = DIExpression::append(Expr, dwarf::DW_OP_deref); + DR = new DPValue(unwrapMAVOp<Metadata>(CI, 0), + unwrapMAVOp<DILocalVariable>(CI, 1), Expr, + CI->getDebugLoc()); + } else if (Name == "value") { + // An old version of dbg.value had an extra offset argument. + unsigned VarOp = 1; + unsigned ExprOp = 2; + if (CI->arg_size() == 4) { + auto *Offset = dyn_cast_or_null<Constant>(CI->getArgOperand(1)); + // Nonzero offset dbg.values get dropped without a replacement. + if (!Offset || !Offset->isZeroValue()) + return; + VarOp = 2; + ExprOp = 3; + } + DR = new DPValue(unwrapMAVOp<Metadata>(CI, 0), + unwrapMAVOp<DILocalVariable>(CI, VarOp), + unwrapMAVOp<DIExpression>(CI, ExprOp), CI->getDebugLoc()); + } + assert(DR && "Unhandled intrinsic kind in upgrade to DbgRecord"); + CI->getParent()->insertDbgRecordBefore(DR, CI->getIterator()); +} + /// Upgrade a call to an old intrinsic. All argument and return casting must be /// provided to seamlessly integrate with existing context. void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { @@ -2357,6 +2422,7 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { bool IsNVVM = Name.consume_front("nvvm."); bool IsARM = Name.consume_front("arm."); bool IsAMDGCN = Name.consume_front("amdgcn."); + bool IsDbg = Name.consume_front("dbg."); if (IsX86 && Name.starts_with("sse4a.movnt.")) { SmallVector<Metadata *, 1> Elts; @@ -2461,7 +2527,7 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { return; } - Value *Rep; + Value *Rep = nullptr; // Upgrade packed integer vector compare intrinsics to compare instructions. if (IsX86 && (Name.starts_with("sse2.pcmp") || Name.starts_with("avx2.pcmp"))) { @@ -4196,6 +4262,8 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { Rep = upgradeARMIntrinsicCall(Name, CI, F, Builder); } else if (IsAMDGCN) { Rep = upgradeAMDGCNIntrinsicCall(Name, CI, F, Builder); + } else if (IsDbg && CI->getModule()->IsNewDbgInfoFormat) { + upgradeDbgIntrinsicToDbgRecord(Name, CI); } else { llvm_unreachable("Unknown function for CallBase upgrade."); } diff --git a/llvm/test/Bitcode/DIExpression-aggresult.ll b/llvm/test/Bitcode/DIExpression-aggresult.ll index 0b89454aa2f9..017218277d02 100644 --- a/llvm/test/Bitcode/DIExpression-aggresult.ll +++ b/llvm/test/Bitcode/DIExpression-aggresult.ll @@ -1,4 +1,5 @@ ; RUN: llvm-dis -o - %s.bc | FileCheck %s +; RUN: llvm-dis -o - %s.bc --load-bitcode-into-experimental-debuginfo-iterators=true | FileCheck %s %class.A = type { i32, i32, i32, i32 } define void @_Z3fooi(%class.A* sret(%class.A) %agg.result) #0 !dbg !3 { diff --git a/llvm/test/Bitcode/dbg-record-roundtrip.ll b/llvm/test/Bitcode/dbg-record-roundtrip.ll index 251c3d9f4bb7..bd347cac7206 100644 --- a/llvm/test/Bitcode/dbg-record-roundtrip.ll +++ b/llvm/test/Bitcode/dbg-record-roundtrip.ll @@ -10,6 +10,11 @@ ; RUN: | llvm-dis --load-bitcode-into-experimental-debuginfo-iterators=true --write-experimental-debuginfo=true \ ; RUN: | FileCheck %s --check-prefixes=RECORDS +;; Load intrinsics directly into the new format (auto-upgrade). +; RUN: llvm-as --write-experimental-debuginfo-iterators-to-bitcode=false %s -o - \ +; RUN: | llvm-dis --load-bitcode-into-experimental-debuginfo-iterators=true --write-experimental-debuginfo=true \ +; RUN: | FileCheck %s --check-prefixes=RECORDS + ;; Check that verify-uselistorder passes regardless of input format. ; RUN: llvm-as %s --write-experimental-debuginfo-iterators-to-bitcode=true -o - | verify-uselistorder ; RUN: verify-uselistorder %s diff --git a/llvm/test/Bitcode/upgrade-dbg-addr.ll b/llvm/test/Bitcode/upgrade-dbg-addr.ll index 40fd7db18948..06a411c2c834 100644 --- a/llvm/test/Bitcode/upgrade-dbg-addr.ll +++ b/llvm/test/Bitcode/upgrade-dbg-addr.ll @@ -1,6 +1,7 @@ ; Test upgrade of dbg.addr intrinsics into dbg.value with DW_OP_deref appended ; ; RUN: llvm-dis < %s.bc | FileCheck %s +; RUN: llvm-dis < %s.bc --load-bitcode-into-experimental-debuginfo-iterators --write-experimental-debuginfo=false | FileCheck %s ; RUN: verify-uselistorder < %s.bc define i32 @example(i32 %num) { -- GitLab From 5b59b3afe1cfe52c3c2cb9c9817ca21e589928a0 Mon Sep 17 00:00:00 2001 From: Jeremy Morse <jeremy.morse@sony.com> Date: Tue, 19 Mar 2024 13:39:46 +0000 Subject: [PATCH 077/307] [NFC][RemoveDIs] Switch constant-hoisting to insert with iterators (#84738) Seeing how constant-hoisting also happens to store an insertion-point in a DenseMap, this means we have to install DenseMapInfo for hashing BasicBlock::iterators and comparing them. I'm not really sure where to put the DenseMapInfo declarations as BasicBlock.h seems most logical, but that then means including DenseMap.h into pretty much all of LLVM. I've sent this up to the compile time tracker to see whether there's a major cost from this. --------- Merged by: Stephen Tozer <stephen.tozer@sony.com> --- llvm/include/llvm/IR/BasicBlock.h | 28 ++++++++++- .../llvm/Transforms/Scalar/ConstantHoisting.h | 15 +++--- .../Transforms/Scalar/ConstantHoisting.cpp | 48 ++++++++++--------- 3 files changed, 61 insertions(+), 30 deletions(-) diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index 71c1a8394896..88e341d7ad6f 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -14,6 +14,7 @@ #define LLVM_IR_BASICBLOCK_H #include "llvm-c/Types.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Twine.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" @@ -21,7 +22,6 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/IR/DebugProgramInstruction.h" #include "llvm/IR/Instruction.h" -#include "llvm/IR/DebugProgramInstruction.h" #include "llvm/IR/SymbolTableListTraits.h" #include "llvm/IR/Value.h" #include <cassert> @@ -774,6 +774,32 @@ BasicBlock::iterator skipDebugIntrinsics(BasicBlock::iterator It); inline void BasicBlock::validateInstrOrdering() const {} #endif +// Specialize DenseMapInfo for iterators, so that ththey can be installed into +// maps and sets. The iterator is made up of its node pointer, and the +// debug-info "head" bit. +template <> struct DenseMapInfo<BasicBlock::iterator> { + static inline BasicBlock::iterator getEmptyKey() { + return BasicBlock::iterator(nullptr); + } + + static inline BasicBlock::iterator getTombstoneKey() { + BasicBlock::iterator It(nullptr); + It.setHeadBit(true); + return It; + } + + static unsigned getHashValue(const BasicBlock::iterator &It) { + return DenseMapInfo<void *>::getHashValue( + reinterpret_cast<void *>(It.getNodePtr())) ^ + It.getHeadBit(); + } + + static bool isEqual(const BasicBlock::iterator &LHS, + const BasicBlock::iterator &RHS) { + return LHS == RHS && LHS.getHeadBit() == RHS.getHeadBit(); + } +}; + } // end namespace llvm #endif // LLVM_IR_BASICBLOCK_H diff --git a/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h b/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h index a4d1653fdf4b..48f8421c1813 100644 --- a/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h +++ b/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h @@ -172,11 +172,12 @@ private: void collectMatInsertPts( const consthoist::RebasedConstantListType &RebasedConstants, - SmallVectorImpl<Instruction *> &MatInsertPts) const; - Instruction *findMatInsertPt(Instruction *Inst, unsigned Idx = ~0U) const; - SetVector<Instruction *> - findConstantInsertionPoint(const consthoist::ConstantInfo &ConstInfo, - const ArrayRef<Instruction *> MatInsertPts) const; + SmallVectorImpl<BasicBlock::iterator> &MatInsertPts) const; + BasicBlock::iterator findMatInsertPt(Instruction *Inst, + unsigned Idx = ~0U) const; + SetVector<BasicBlock::iterator> findConstantInsertionPoint( + const consthoist::ConstantInfo &ConstInfo, + const ArrayRef<BasicBlock::iterator> MatInsertPts) const; void collectConstantCandidates(ConstCandMapType &ConstCandMap, Instruction *Inst, unsigned Idx, ConstantInt *ConstInt); @@ -203,9 +204,9 @@ private: struct UserAdjustment { Constant *Offset; Type *Ty; - Instruction *MatInsertPt; + BasicBlock::iterator MatInsertPt; const consthoist::ConstantUser User; - UserAdjustment(Constant *O, Type *T, Instruction *I, + UserAdjustment(Constant *O, Type *T, BasicBlock::iterator I, consthoist::ConstantUser U) : Offset(O), Ty(T), MatInsertPt(I), User(U) {} }; diff --git a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp index c12dc281b0e3..68774cf31ce9 100644 --- a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp +++ b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp @@ -162,27 +162,27 @@ bool ConstantHoistingLegacyPass::runOnFunction(Function &Fn) { void ConstantHoistingPass::collectMatInsertPts( const RebasedConstantListType &RebasedConstants, - SmallVectorImpl<Instruction *> &MatInsertPts) const { + SmallVectorImpl<BasicBlock::iterator> &MatInsertPts) const { for (const RebasedConstantInfo &RCI : RebasedConstants) for (const ConstantUser &U : RCI.Uses) MatInsertPts.emplace_back(findMatInsertPt(U.Inst, U.OpndIdx)); } /// Find the constant materialization insertion point. -Instruction *ConstantHoistingPass::findMatInsertPt(Instruction *Inst, - unsigned Idx) const { +BasicBlock::iterator ConstantHoistingPass::findMatInsertPt(Instruction *Inst, + unsigned Idx) const { // If the operand is a cast instruction, then we have to materialize the // constant before the cast instruction. if (Idx != ~0U) { Value *Opnd = Inst->getOperand(Idx); if (auto CastInst = dyn_cast<Instruction>(Opnd)) if (CastInst->isCast()) - return CastInst; + return CastInst->getIterator(); } // The simple and common case. This also includes constant expressions. if (!isa<PHINode>(Inst) && !Inst->isEHPad()) - return Inst; + return Inst->getIterator(); // We can't insert directly before a phi node or an eh pad. Insert before // the terminator of the incoming or dominating block. @@ -191,7 +191,7 @@ Instruction *ConstantHoistingPass::findMatInsertPt(Instruction *Inst, if (Idx != ~0U && isa<PHINode>(Inst)) { InsertionBlock = cast<PHINode>(Inst)->getIncomingBlock(Idx); if (!InsertionBlock->isEHPad()) { - return InsertionBlock->getTerminator(); + return InsertionBlock->getTerminator()->getIterator(); } } else { InsertionBlock = Inst->getParent(); @@ -206,7 +206,7 @@ Instruction *ConstantHoistingPass::findMatInsertPt(Instruction *Inst, IDom = IDom->getIDom(); } - return IDom->getBlock()->getTerminator(); + return IDom->getBlock()->getTerminator()->getIterator(); } /// Given \p BBs as input, find another set of BBs which collectively @@ -314,26 +314,27 @@ static void findBestInsertionSet(DominatorTree &DT, BlockFrequencyInfo &BFI, } /// Find an insertion point that dominates all uses. -SetVector<Instruction *> ConstantHoistingPass::findConstantInsertionPoint( +SetVector<BasicBlock::iterator> +ConstantHoistingPass::findConstantInsertionPoint( const ConstantInfo &ConstInfo, - const ArrayRef<Instruction *> MatInsertPts) const { + const ArrayRef<BasicBlock::iterator> MatInsertPts) const { assert(!ConstInfo.RebasedConstants.empty() && "Invalid constant info entry."); // Collect all basic blocks. SetVector<BasicBlock *> BBs; - SetVector<Instruction *> InsertPts; + SetVector<BasicBlock::iterator> InsertPts; - for (Instruction *MatInsertPt : MatInsertPts) + for (BasicBlock::iterator MatInsertPt : MatInsertPts) BBs.insert(MatInsertPt->getParent()); if (BBs.count(Entry)) { - InsertPts.insert(&Entry->front()); + InsertPts.insert(Entry->begin()); return InsertPts; } if (BFI) { findBestInsertionSet(*DT, *BFI, Entry, BBs); for (BasicBlock *BB : BBs) - InsertPts.insert(&*BB->getFirstInsertionPt()); + InsertPts.insert(BB->getFirstInsertionPt()); return InsertPts; } @@ -343,7 +344,7 @@ SetVector<Instruction *> ConstantHoistingPass::findConstantInsertionPoint( BB2 = BBs.pop_back_val(); BB = DT->findNearestCommonDominator(BB1, BB2); if (BB == Entry) { - InsertPts.insert(&Entry->front()); + InsertPts.insert(Entry->begin()); return InsertPts; } BBs.insert(BB); @@ -764,11 +765,13 @@ void ConstantHoistingPass::emitBaseConstants(Instruction *Base, Mat = GetElementPtrInst::Create(Type::getInt8Ty(*Ctx), Base, Adj->Offset, "mat_gep", Adj->MatInsertPt); // Hide it behind a bitcast. - Mat = new BitCastInst(Mat, Adj->Ty, "mat_bitcast", Adj->MatInsertPt); + Mat = new BitCastInst(Mat, Adj->Ty, "mat_bitcast", + Adj->MatInsertPt->getIterator()); } else // Constant being rebased is a ConstantInt. - Mat = BinaryOperator::Create(Instruction::Add, Base, Adj->Offset, - "const_mat", Adj->MatInsertPt); + Mat = + BinaryOperator::Create(Instruction::Add, Base, Adj->Offset, + "const_mat", Adj->MatInsertPt->getIterator()); LLVM_DEBUG(dbgs() << "Materialize constant (" << *Base->getOperand(0) << " + " << *Adj->Offset << ") in BB " @@ -819,7 +822,8 @@ void ConstantHoistingPass::emitBaseConstants(Instruction *Base, // Aside from constant GEPs, only constant cast expressions are collected. assert(ConstExpr->isCast() && "ConstExpr should be a cast"); - Instruction *ConstExprInst = ConstExpr->getAsInstruction(Adj->MatInsertPt); + Instruction *ConstExprInst = ConstExpr->getAsInstruction(); + ConstExprInst->insertBefore(Adj->MatInsertPt); ConstExprInst->setOperand(0, Mat); // Use the same debug location as the instruction we are about to update. @@ -845,9 +849,9 @@ bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) { SmallVectorImpl<consthoist::ConstantInfo> &ConstInfoVec = BaseGV ? ConstGEPInfoMap[BaseGV] : ConstIntInfoVec; for (const consthoist::ConstantInfo &ConstInfo : ConstInfoVec) { - SmallVector<Instruction *, 4> MatInsertPts; + SmallVector<BasicBlock::iterator, 4> MatInsertPts; collectMatInsertPts(ConstInfo.RebasedConstants, MatInsertPts); - SetVector<Instruction *> IPSet = + SetVector<BasicBlock::iterator> IPSet = findConstantInsertionPoint(ConstInfo, MatInsertPts); // We can have an empty set if the function contains unreachable blocks. if (IPSet.empty()) @@ -856,7 +860,7 @@ bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) { unsigned UsesNum = 0; unsigned ReBasesNum = 0; unsigned NotRebasedNum = 0; - for (Instruction *IP : IPSet) { + for (const BasicBlock::iterator &IP : IPSet) { // First, collect constants depending on this IP of the base. UsesNum = 0; SmallVector<UserAdjustment, 4> ToBeRebased; @@ -864,7 +868,7 @@ bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) { for (auto const &RCI : ConstInfo.RebasedConstants) { UsesNum += RCI.Uses.size(); for (auto const &U : RCI.Uses) { - Instruction *MatInsertPt = MatInsertPts[MatCtr++]; + const BasicBlock::iterator &MatInsertPt = MatInsertPts[MatCtr++]; BasicBlock *OrigMatInsertBB = MatInsertPt->getParent(); // If Base constant is to be inserted in multiple places, // generate rebase for U using the Base dominating U. -- GitLab From c1328db9d8e41bb96e031eb3dfa884e56b07244b Mon Sep 17 00:00:00 2001 From: Yitzhak Mandelbaum <ymand@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:41:29 -0400 Subject: [PATCH 078/307] [clang][dataflow] Refactor processing of terminator element (#84499) This patch vastly simplifies the code handling terminators, without changing any behavior. Additionally, the simplification unblocks our ability to address a (simple) FIXME in the code to invoke `transferBranch`, even when builtin options are disabled. --- .../TypeErasedDataflowAnalysis.cpp | 136 ++++++------------ 1 file changed, 42 insertions(+), 94 deletions(-) diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 721a11c20985..595f70f819dd 100644 --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#include <algorithm> #include <optional> #include <system_error> #include <utility> @@ -33,7 +32,6 @@ #include "clang/Analysis/FlowSensitive/Value.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallBitVector.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Error.h" @@ -64,88 +62,27 @@ static bool isBackedgeNode(const CFGBlock &B) { namespace { -// The return type of the visit functions in TerminatorVisitor. The first -// element represents the terminator expression (that is the conditional -// expression in case of a path split in the CFG). The second element -// represents whether the condition was true or false. -using TerminatorVisitorRetTy = std::pair<const Expr *, bool>; - -/// Extends the flow condition of an environment based on a terminator -/// statement. +/// Extracts the terminator's condition expression. class TerminatorVisitor - : public ConstStmtVisitor<TerminatorVisitor, TerminatorVisitorRetTy> { + : public ConstStmtVisitor<TerminatorVisitor, const Expr *> { public: - TerminatorVisitor(Environment &Env, int BlockSuccIdx) - : Env(Env), BlockSuccIdx(BlockSuccIdx) {} - - TerminatorVisitorRetTy VisitIfStmt(const IfStmt *S) { - auto *Cond = S->getCond(); - assert(Cond != nullptr); - return extendFlowCondition(*Cond); - } - - TerminatorVisitorRetTy VisitWhileStmt(const WhileStmt *S) { - auto *Cond = S->getCond(); - assert(Cond != nullptr); - return extendFlowCondition(*Cond); - } - - TerminatorVisitorRetTy VisitDoStmt(const DoStmt *S) { - auto *Cond = S->getCond(); - assert(Cond != nullptr); - return extendFlowCondition(*Cond); - } - - TerminatorVisitorRetTy VisitForStmt(const ForStmt *S) { - auto *Cond = S->getCond(); - if (Cond != nullptr) - return extendFlowCondition(*Cond); - return {nullptr, false}; - } - - TerminatorVisitorRetTy VisitCXXForRangeStmt(const CXXForRangeStmt *) { + TerminatorVisitor() = default; + const Expr *VisitIfStmt(const IfStmt *S) { return S->getCond(); } + const Expr *VisitWhileStmt(const WhileStmt *S) { return S->getCond(); } + const Expr *VisitDoStmt(const DoStmt *S) { return S->getCond(); } + const Expr *VisitForStmt(const ForStmt *S) { return S->getCond(); } + const Expr *VisitCXXForRangeStmt(const CXXForRangeStmt *) { // Don't do anything special for CXXForRangeStmt, because the condition // (being implicitly generated) isn't visible from the loop body. - return {nullptr, false}; + return nullptr; } - - TerminatorVisitorRetTy VisitBinaryOperator(const BinaryOperator *S) { + const Expr *VisitBinaryOperator(const BinaryOperator *S) { assert(S->getOpcode() == BO_LAnd || S->getOpcode() == BO_LOr); - auto *LHS = S->getLHS(); - assert(LHS != nullptr); - return extendFlowCondition(*LHS); + return S->getLHS(); } - - TerminatorVisitorRetTy - VisitConditionalOperator(const ConditionalOperator *S) { - auto *Cond = S->getCond(); - assert(Cond != nullptr); - return extendFlowCondition(*Cond); + const Expr *VisitConditionalOperator(const ConditionalOperator *S) { + return S->getCond(); } - -private: - TerminatorVisitorRetTy extendFlowCondition(const Expr &Cond) { - auto *Val = Env.get<BoolValue>(Cond); - // In transferCFGBlock(), we ensure that we always have a `Value` for the - // terminator condition, so assert this. - // We consciously assert ourselves instead of asserting via `cast()` so - // that we get a more meaningful line number if the assertion fails. - assert(Val != nullptr); - - bool ConditionValue = true; - // The condition must be inverted for the successor that encompasses the - // "else" branch, if such exists. - if (BlockSuccIdx == 1) { - Val = &Env.makeNot(*Val); - ConditionValue = false; - } - - Env.assume(Val->formula()); - return {&Cond, ConditionValue}; - } - - Environment &Env; - int BlockSuccIdx; }; /// Holds data structures required for running dataflow analysis. @@ -263,9 +200,13 @@ public: return Result; } }; - } // namespace +static const Expr *getTerminatorCondition(const Stmt *TerminatorStmt) { + return TerminatorStmt == nullptr ? nullptr + : TerminatorVisitor().Visit(TerminatorStmt); +} + /// Computes the input state for a given basic block by joining the output /// states of its predecessors. /// @@ -337,25 +278,32 @@ computeBlockInputState(const CFGBlock &Block, AnalysisContext &AC) { if (!MaybePredState) continue; + const TypeErasedDataflowAnalysisState &PredState = *MaybePredState; + const Expr *Cond = getTerminatorCondition(Pred->getTerminatorStmt()); + if (Cond == nullptr) { + Builder.addUnowned(PredState); + continue; + } + + bool BranchVal = blockIndexInPredecessor(*Pred, Block) == 0; + + // `transferBranch` may need to mutate the environment to describe the + // dynamic effect of the terminator for a given branch. Copy now. + TypeErasedDataflowAnalysisState Copy = MaybePredState->fork(); if (AC.Analysis.builtinOptions()) { - if (const Stmt *PredTerminatorStmt = Pred->getTerminatorStmt()) { - // We have a terminator: we need to mutate an environment to describe - // when the terminator is taken. Copy now. - TypeErasedDataflowAnalysisState Copy = MaybePredState->fork(); - - auto [Cond, CondValue] = - TerminatorVisitor(Copy.Env, blockIndexInPredecessor(*Pred, Block)) - .Visit(PredTerminatorStmt); - if (Cond != nullptr) - // FIXME: Call transferBranchTypeErased even if BuiltinTransferOpts - // are not set. - AC.Analysis.transferBranchTypeErased(CondValue, Cond, Copy.Lattice, - Copy.Env); - Builder.addOwned(std::move(Copy)); - continue; - } + auto *CondVal = Copy.Env.get<BoolValue>(*Cond); + // In transferCFGBlock(), we ensure that we always have a `Value` + // for the terminator condition, so assert this. We consciously + // assert ourselves instead of asserting via `cast()` so that we get + // a more meaningful line number if the assertion fails. + assert(CondVal != nullptr); + BoolValue *AssertedVal = + BranchVal ? CondVal : &Copy.Env.makeNot(*CondVal); + Copy.Env.assume(AssertedVal->formula()); } - Builder.addUnowned(*MaybePredState); + AC.Analysis.transferBranchTypeErased(BranchVal, Cond, Copy.Lattice, + Copy.Env); + Builder.addOwned(std::move(Copy)); } return std::move(Builder).take(); } -- GitLab From d93363a0e803a9fb2889ff03237f4e93aacf0108 Mon Sep 17 00:00:00 2001 From: Tom Stellard <tstellar@redhat.com> Date: Tue, 19 Mar 2024 06:55:10 -0700 Subject: [PATCH 079/307] workflows: Fix baseline version for llvm abi checks (#85166) The baseline version calculations was assuming the minor release would always be 0. --- .github/workflows/llvm-tests.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/llvm-tests.yml b/.github/workflows/llvm-tests.yml index 127628d76f19..64d60bc3da45 100644 --- a/.github/workflows/llvm-tests.yml +++ b/.github/workflows/llvm-tests.yml @@ -42,6 +42,7 @@ jobs: BASELINE_REF: ${{ steps.vars.outputs.BASELINE_REF }} ABI_HEADERS: ${{ steps.vars.outputs.ABI_HEADERS }} BASELINE_VERSION_MAJOR: ${{ steps.vars.outputs.BASELINE_VERSION_MAJOR }} + BASELINE_VERSION_MINOR: ${{ steps.vars.outputs.BASELINE_VERSION_MINOR }} LLVM_VERSION_MAJOR: ${{ steps.version.outputs.LLVM_VERSION_MAJOR }} LLVM_VERSION_MINOR: ${{ steps.version.outputs.LLVM_VERSION_MINOR }} LLVM_VERSION_PATCH: ${{ steps.version.outputs.LLVM_VERSION_PATCH }} @@ -58,7 +59,14 @@ jobs: - name: Setup Variables id: vars run: | - if [ ${{ steps.version.outputs.LLVM_VERSION_MINOR }} -ne 0 ] || [ ${{ steps.version.outputs.LLVM_VERSION_PATCH }} -eq 0 ]; then + # C++ ABI: + # 18.1.0 we aren't doing ABI checks. + # 18.1.1 We want to check 18.1.0. + # C ABI: + # 18.1.0 We want to check 17.0.x + # 18.1.1 We want to check 18.1.0 + echo "BASELINE_VERSION_MINOR=1" >> "$GITHUB_OUTPUT" + if [ ${{ steps.version.outputs.LLVM_VERSION_PATCH }} -eq 0 ]; then { echo "BASELINE_VERSION_MAJOR=$(( ${{ steps.version.outputs.LLVM_VERSION_MAJOR }} - 1))" echo "ABI_HEADERS=llvm-c" @@ -82,7 +90,7 @@ jobs: include: - name: build-baseline llvm_version_major: ${{ needs.abi-dump-setup.outputs.BASELINE_VERSION_MAJOR }} - ref: llvmorg-${{ needs.abi-dump-setup.outputs.BASELINE_VERSION_MAJOR }}.0.0 + ref: llvmorg-${{ needs.abi-dump-setup.outputs.BASELINE_VERSION_MAJOR }}.${{ needs.abi-dump-setup.outputs.BASELINE_VERSION_MINOR }}.0 repo: llvm/llvm-project - name: build-latest llvm_version_major: ${{ needs.abi-dump-setup.outputs.LLVM_VERSION_MAJOR }} -- GitLab From ef395a492aa931f428e99e1c0a93d4ad2fb0fcfa Mon Sep 17 00:00:00 2001 From: ostannard <oliver.stannard@arm.com> Date: Tue, 19 Mar 2024 13:58:51 +0000 Subject: [PATCH 080/307] [AArch64] Add soft-float ABI (#84146) This is re-working of #74460, which adds a soft-float ABI for AArch64. That was reverted because it causes errors when building the linux and fuchsia kernels. The problem is that GCC's implementation of the ABI compatibility checks when using the hard-float ABI on a target without FP registers does it's checks after optimisation. The previous version of this patch reported errors for all uses of floating-point types, which is stricter than what GCC does in practice. This changes two things compared to the first version: * Only check the types of function arguments and returns, not the types of other values. This is more relaxed than GCC, while still guaranteeing ABI compatibility. * Move the check from Sema to CodeGen, so that inline functions are only checked if they are actually used. There are some cases in the linux kernel which depend on this behaviour of GCC. --- .../clang/Basic/DiagnosticCommonKinds.td | 2 + .../clang/Basic/DiagnosticFrontendKinds.td | 6 + clang/include/clang/Basic/DiagnosticIDs.h | 3 + clang/lib/Basic/DiagnosticIDs.cpp | 8 + clang/lib/Basic/Targets/AArch64.cpp | 16 +- clang/lib/Basic/Targets/AArch64.h | 2 + clang/lib/CodeGen/CodeGenFunction.cpp | 2 + clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/ModuleBuilder.cpp | 16 +- clang/lib/CodeGen/TargetInfo.h | 6 + clang/lib/CodeGen/Targets/AArch64.cpp | 50 +++++- .../CodeGen/aarch64-soft-float-abi-errors.c | 99 +++++++++++ clang/test/CodeGen/aarch64-soft-float-abi.c | 58 +++++++ .../test/CodeGen/attr-target-clones-aarch64.c | 10 -- clang/test/CodeGen/target-avx-abi-diag.c | 42 ++--- clang/test/Driver/aarch64-soft-float-abi.c | 26 +++ .../Preprocessor/aarch64-target-features.c | 6 +- clang/test/Sema/arm-vector-types-support.c | 2 + llvm/test/CodeGen/AArch64/soft-float-abi.ll | 161 ++++++++++++++++++ 19 files changed, 470 insertions(+), 47 deletions(-) create mode 100644 clang/test/CodeGen/aarch64-soft-float-abi-errors.c create mode 100644 clang/test/CodeGen/aarch64-soft-float-abi.c create mode 100644 clang/test/Driver/aarch64-soft-float-abi.c create mode 100644 llvm/test/CodeGen/AArch64/soft-float-abi.ll diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 08bb1d81ba29..43e132e56658 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -356,6 +356,8 @@ def warn_target_unrecognized_env : Warning< def warn_knl_knm_isa_support_removed : Warning< "KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.">, InGroup<DiagGroup<"knl-knm-isa-support-removed">>; +def err_target_unsupported_abi_with_fpu : Error< + "'%0' ABI is not supported with FPU">; // Source manager def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal; diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 794a0a82be6d..ba23cf84c5e3 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -281,6 +281,8 @@ def err_builtin_needs_feature : Error<"%0 needs target feature %1">; def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " "be inlined into function %0 that is compiled without support for '%2'">; + +let CategoryName = "Codegen ABI Check" in { def err_function_always_inline_attribute_mismatch : Error< "always_inline function %1 and its caller %0 have mismatching %2 attributes">; def err_function_always_inline_new_za : Error< @@ -292,6 +294,10 @@ def warn_avx_calling_convention InGroup<DiagGroup<"psabi">>; def err_avx_calling_convention : Error<warn_avx_calling_convention.Summary>; +def err_target_unsupported_type_for_abi + : Error<"%0 requires %1 type support, but ABI '%2' does not support it">; +} + def err_alias_to_undefined : Error< "%select{alias|ifunc}0 must point to a defined " "%select{variable or |}1function">; diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h index 95b502b1e97a..5ff782c7f8c7 100644 --- a/clang/include/clang/Basic/DiagnosticIDs.h +++ b/clang/include/clang/Basic/DiagnosticIDs.h @@ -278,6 +278,9 @@ public: /// category. static bool isARCDiagnostic(unsigned DiagID); + /// Return true if a given diagnostic is a codegen-time ABI check. + static bool isCodegenABICheckDiagnostic(unsigned DiagID); + /// Enumeration describing how the emission of a diagnostic should /// be treated when it occurs during C++ template argument deduction. enum SFINAEResponse { diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index 4138b4ee4b0e..cd42573968b2 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -861,6 +861,9 @@ bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const { if (isARCDiagnostic(DiagID)) return false; + if (isCodegenABICheckDiagnostic(DiagID)) + return false; + return true; } @@ -868,3 +871,8 @@ bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) { unsigned cat = getCategoryNumberForDiag(DiagID); return DiagnosticIDs::getCategoryNameFromID(cat).starts_with("ARC "); } + +bool DiagnosticIDs::isCodegenABICheckDiagnostic(unsigned DiagID) { + unsigned cat = getCategoryNumberForDiag(DiagID); + return DiagnosticIDs::getCategoryNameFromID(cat) == "Codegen ABI Check"; +} diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index fa8b5a869594..1c3199bd76ee 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "AArch64.h" +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" @@ -200,13 +201,23 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, StringRef AArch64TargetInfo::getABI() const { return ABI; } bool AArch64TargetInfo::setABI(const std::string &Name) { - if (Name != "aapcs" && Name != "darwinpcs") + if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs") return false; ABI = Name; return true; } +bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const { + if (hasFeature("fp") && ABI == "aapcs-soft") { + // aapcs-soft is not allowed for targets with an FPU, to avoid there being + // two incomatible ABIs. + Diags.Report(diag::err_target_unsupported_abi_with_fpu) << ABI; + return false; + } + return true; +} + bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef, BranchProtectionInfo &BPI, StringRef &Err) const { @@ -681,7 +692,8 @@ bool AArch64TargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch<bool>(Feature) .Cases("aarch64", "arm64", "arm", true) .Case("fmv", HasFMV) - .Cases("neon", "fp", "simd", FPU & NeonMode) + .Case("fp", FPU & FPUMode) + .Cases("neon", "simd", FPU & NeonMode) .Case("jscvt", HasJSCVT) .Case("fcma", HasFCMA) .Case("rng", HasRandGen) diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 2dd6b2181e87..542894c66412 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -201,6 +201,8 @@ public: bool hasInt128Type() const override; bool hasBitIntType() const override { return true; } + + bool validateTarget(DiagnosticsEngine &Diags) const override; }; class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo { diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 4a3ff49b0007..98bea8209cf3 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1361,6 +1361,8 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, FunctionArgList Args; QualType ResTy = BuildFunctionArgList(GD, Args); + CGM.getTargetCodeGenInfo().checkFunctionABI(CGM, FD); + if (FD->isInlineBuiltinDeclaration()) { // When generating code for a builtin with an inline declaration, use a // mangled name to hold the actual body, while keeping an external diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 8ceecff28cbc..bb26bfcddaeb 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -145,6 +145,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { Kind = AArch64ABIKind::DarwinPCS; else if (Triple.isOSWindows()) return createWindowsAArch64TargetCodeGenInfo(CGM, AArch64ABIKind::Win64); + else if (Target.getABI() == "aapcs-soft") + Kind = AArch64ABIKind::AAPCSSoft; return createAArch64TargetCodeGenInfo(CGM, Kind); } diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index 3594f4c66e67..df85295cfb2e 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -180,7 +180,7 @@ namespace { bool HandleTopLevelDecl(DeclGroupRef DG) override { // FIXME: Why not return false and abort parsing? - if (Diags.hasErrorOccurred()) + if (Diags.hasUnrecoverableErrorOccurred()) return true; HandlingTopLevelDeclRAII HandlingDecl(*this); @@ -206,7 +206,7 @@ namespace { } void HandleInlineFunctionDefinition(FunctionDecl *D) override { - if (Diags.hasErrorOccurred()) + if (Diags.hasUnrecoverableErrorOccurred()) return; assert(D->doesThisDeclarationHaveABody()); @@ -233,7 +233,7 @@ namespace { /// client hack on the type, which can occur at any point in the file /// (because these can be defined in declspecs). void HandleTagDeclDefinition(TagDecl *D) override { - if (Diags.hasErrorOccurred()) + if (Diags.hasUnrecoverableErrorOccurred()) return; // Don't allow re-entrant calls to CodeGen triggered by PCH @@ -269,7 +269,7 @@ namespace { } void HandleTagDeclRequiredDefinition(const TagDecl *D) override { - if (Diags.hasErrorOccurred()) + if (Diags.hasUnrecoverableErrorOccurred()) return; // Don't allow re-entrant calls to CodeGen triggered by PCH @@ -283,7 +283,7 @@ namespace { void HandleTranslationUnit(ASTContext &Ctx) override { // Release the Builder when there is no error. - if (!Diags.hasErrorOccurred() && Builder) + if (!Diags.hasUnrecoverableErrorOccurred() && Builder) Builder->Release(); // If there are errors before or when releasing the Builder, reset @@ -297,14 +297,14 @@ namespace { } void AssignInheritanceModel(CXXRecordDecl *RD) override { - if (Diags.hasErrorOccurred()) + if (Diags.hasUnrecoverableErrorOccurred()) return; Builder->RefreshTypeCacheForClass(RD); } void CompleteTentativeDefinition(VarDecl *D) override { - if (Diags.hasErrorOccurred()) + if (Diags.hasUnrecoverableErrorOccurred()) return; Builder->EmitTentativeDefinition(D); @@ -315,7 +315,7 @@ namespace { } void HandleVTable(CXXRecordDecl *RD) override { - if (Diags.hasErrorOccurred()) + if (Diags.hasUnrecoverableErrorOccurred()) return; Builder->EmitVTable(RD); diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index 7682f197041c..6893b50a3cfe 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -84,6 +84,11 @@ public: /// Provides a convenient hook to handle extra target-specific globals. virtual void emitTargetGlobals(CodeGen::CodeGenModule &CGM) const {} + /// Any further codegen related checks that need to be done on a function + /// signature in a target specific manner. + virtual void checkFunctionABI(CodeGenModule &CGM, + const FunctionDecl *Decl) const {} + /// Any further codegen related checks that need to be done on a function call /// in a target specific manner. virtual void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, @@ -416,6 +421,7 @@ enum class AArch64ABIKind { AAPCS = 0, DarwinPCS, Win64, + AAPCSSoft, }; std::unique_ptr<TargetCodeGenInfo> diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 85117366de0e..4c32f510101f 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -27,6 +27,8 @@ public: AArch64ABIInfo(CodeGenTypes &CGT, AArch64ABIKind Kind) : ABIInfo(CGT), Kind(Kind) {} + bool isSoftFloat() const { return Kind == AArch64ABIKind::AAPCSSoft; } + private: AArch64ABIKind getABIKind() const { return Kind; } bool isDarwinPCS() const { return Kind == AArch64ABIKind::DarwinPCS; } @@ -55,8 +57,8 @@ private: Address EmitDarwinVAArg(Address VAListAddr, QualType Ty, CodeGenFunction &CGF) const; - Address EmitAAPCSVAArg(Address VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + Address EmitAAPCSVAArg(Address VAListAddr, QualType Ty, CodeGenFunction &CGF, + AArch64ABIKind Kind) const; Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const override { @@ -67,7 +69,7 @@ private: return Kind == AArch64ABIKind::Win64 ? EmitMSVAArg(CGF, VAListAddr, Ty) : isDarwinPCS() ? EmitDarwinVAArg(VAListAddr, Ty, CGF) - : EmitAAPCSVAArg(VAListAddr, Ty, CGF); + : EmitAAPCSVAArg(VAListAddr, Ty, CGF, Kind); } Address EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, @@ -163,6 +165,9 @@ public: return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty); } + void checkFunctionABI(CodeGenModule &CGM, + const FunctionDecl *Decl) const override; + void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, const FunctionDecl *Callee, @@ -494,6 +499,11 @@ bool AArch64SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, } bool AArch64ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { + // For the soft-float ABI variant, no types are considered to be homogeneous + // aggregates. + if (Kind == AArch64ABIKind::AAPCSSoft) + return false; + // Homogeneous aggregates for AAPCS64 must have base types of a floating // point type or a short-vector type. This is the same as the 32-bit ABI, // but with the difference that any floating-point type is allowed, @@ -525,7 +535,8 @@ bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() } Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty, - CodeGenFunction &CGF) const { + CodeGenFunction &CGF, + AArch64ABIKind Kind) const { ABIArgInfo AI = classifyArgumentType(Ty, /*IsVariadic=*/true, CGF.CurFnInfo->getCallingConvention()); // Empty records are ignored for parameter passing purposes. @@ -550,7 +561,8 @@ Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty, BaseTy = ArrTy->getElementType(); NumRegs = ArrTy->getNumElements(); } - bool IsFPR = BaseTy->isFloatingPointTy() || BaseTy->isVectorTy(); + bool IsFPR = Kind != AArch64ABIKind::AAPCSSoft && + (BaseTy->isFloatingPointTy() || BaseTy->isVectorTy()); // The AArch64 va_list type and handling is specified in the Procedure Call // Standard, section B.4: @@ -841,6 +853,34 @@ static bool isStreamingCompatible(const FunctionDecl *F) { return false; } +void AArch64TargetCodeGenInfo::checkFunctionABI( + CodeGenModule &CGM, const FunctionDecl *FuncDecl) const { + const AArch64ABIInfo &ABIInfo = getABIInfo<AArch64ABIInfo>(); + const TargetInfo &TI = ABIInfo.getContext().getTargetInfo(); + + // If we are using a hard-float ABI, but do not have floating point + // registers, then report an error for any function arguments or returns + // which would be passed in floating-pint registers. + auto CheckType = [&CGM, &TI, &ABIInfo](const QualType &Ty, + const NamedDecl *D) { + const Type *HABase = nullptr; + uint64_t HAMembers = 0; + if (Ty->isFloatingType() || Ty->isVectorType() || + ABIInfo.isHomogeneousAggregate(Ty, HABase, HAMembers)) { + CGM.getDiags().Report(D->getLocation(), + diag::err_target_unsupported_type_for_abi) + << D->getDeclName() << Ty << TI.getABI(); + } + }; + + if (!TI.hasFeature("fp") && !ABIInfo.isSoftFloat()) { + CheckType(FuncDecl->getReturnType(), FuncDecl); + for (ParmVarDecl *PVD : FuncDecl->parameters()) { + CheckType(PVD->getType(), PVD); + } + } +} + void AArch64TargetCodeGenInfo::checkFunctionCallABI( CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, const FunctionDecl *Callee, const CallArgList &Args) const { diff --git a/clang/test/CodeGen/aarch64-soft-float-abi-errors.c b/clang/test/CodeGen/aarch64-soft-float-abi-errors.c new file mode 100644 index 000000000000..3e5ab9e92a1d --- /dev/null +++ b/clang/test/CodeGen/aarch64-soft-float-abi-errors.c @@ -0,0 +1,99 @@ +// REQUIRES: aarch64-registered-target + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +fp-armv8 -S -target-abi aapcs -verify=fp-hard %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fp-armv8 -S -target-abi aapcs-soft -verify=nofp-soft %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fp-armv8 -S -target-abi aapcs -verify=nofp-hard %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fp-armv8 -S -target-abi aapcs -O1 -verify=nofp-hard,nofp-hard-opt -emit-llvm %s +// No run line needed for soft-float ABI with an FPU because that is rejected by the driver + +// With the hard-float ABI and a target with an FPU, FP arguments are passed in +// FP registers, no diagnostics needed. +// fp-hard-no-diagnostics + +// With the soft-float ABI, FP arguments are passed in integer registers, no +// diagnostics needed. +// nofp-soft-no-diagnostics + +// With the hard-float ABI but no FPU, FP arguments cannot be passed in an +// ABI-compatible way, so we report errors for these cases: + +struct HFA { + float x, y; +}; + +struct non_HFA { + float x; + int y; +}; + +// Floating-point arguments are returns are rejected +void test_fp16_arg(__fp16 a) {} +// nofp-hard-error@-1 {{'a' requires '__fp16' type support, but ABI 'aapcs' does not support it}} +__fp16 test_fp16_ret(void) { return 3.141; } +// nofp-hard-error@-1 {{'test_fp16_ret' requires '__fp16' type support, but ABI 'aapcs' does not support it}} +void test_float_arg(float a) {} +// nofp-hard-error@-1 {{'a' requires 'float' type support, but ABI 'aapcs' does not support it}} +float test_float_ret(void) { return 3.141f; } +// nofp-hard-error@-1 {{'test_float_ret' requires 'float' type support, but ABI 'aapcs' does not support it}} +void test_double_arg(double a) {} +// nofp-hard-error@-1 {{'a' requires 'double' type support, but ABI 'aapcs' does not support it}} +double test_double_ret(void) { return 3.141; } +// nofp-hard-error@-1 {{'test_double_ret' requires 'double' type support, but ABI 'aapcs' does not support it}} +void test_long_double_arg(long double a) {} +// nofp-hard-error@-1 {{'a' requires 'long double' type support, but ABI 'aapcs' does not support it}} +long double test_long_double_ret(void) { return 3.141L; } +// nofp-hard-error@-1 {{'test_long_double_ret' requires 'long double' type support, but ABI 'aapcs' does not support it}} + +// HFAs would be passed in floating-point registers, so are rejected. +void test_hfa_arg(struct HFA a) {} +// nofp-hard-error@-1 {{'a' requires 'struct HFA' type support, but ABI 'aapcs' does not support it}} +struct HFA test_hfa_ret(void) { return (struct HFA){}; } +// nofp-hard-error@-1 {{'test_hfa_ret' requires 'struct HFA' type support, but ABI 'aapcs' does not support it}} + +// Note: vector types cannot be created at all for targets without an FPU, so +// it is not possible to create a function which passes/returns them when using +// either the default or soft-float ABI. This is tested elsewhere. + +// This struct contains a floating-point type, but is not an HFA, so can be +// passed/returned without affecting the ABI. +struct non_HFA test_non_hfa_ret(void) { return (struct non_HFA){}; } +void test_non_hfa_arg(struct non_HFA a) {} + +// This inline function does not get code-generated because there is no use of +// it in this file, so we we don't emit an error for it, matching GCC's +// behaviour. +inline void test_float_arg_inline(float a) {} + +// This inline function is used, so we emit the error if we generate code for +// it. The code isn't generated at -O0, so no error is emitted there. +inline void test_float_arg_inline_used(float a) {} +// nofp-hard-opt-error@-1 {{'a' requires 'float' type support, but ABI 'aapcs' does not support it}} +void use_inline() { test_float_arg_inline_used(1.0f); } + +// The always_inline attribute causes an inline function to always be +// code-genned, even at -O0, so we always emit the error. +__attribute((always_inline)) +inline void test_float_arg_always_inline_used(float a) {} +// nofp-hard-error@-1 {{'a' requires 'float' type support, but ABI 'aapcs' does not support it}} +void use_always_inline() { test_float_arg_always_inline_used(1.0f); } + +// Floating-point expressions, global variables and local variables do not +// affect the ABI, so are allowed. GCC does reject some uses of floating point +// types like this, but it does so after optimisation, which we can't +// accurately match in clang. +int test_expr_float(int a) { return a + 1.0f; } +int test_expr_double(int a) { return a + 1.0; } + +float global_float = 2.0f * 3.5f; +float global_double = 2.0 * 3.5; + +int test_var_float(int a) { + float f = a; + f *= 6.0; + return (int)f; +} +int test_var_double(int a) { + double d = a; + d *= 6.0; + return (int)d; +} diff --git a/clang/test/CodeGen/aarch64-soft-float-abi.c b/clang/test/CodeGen/aarch64-soft-float-abi.c new file mode 100644 index 000000000000..143377e218a1 --- /dev/null +++ b/clang/test/CodeGen/aarch64-soft-float-abi.c @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -triple aarch64 -target-feature +fp-armv8 -target-abi aapcs -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,HARD +// RUN: %clang_cc1 -triple aarch64 -target-feature -fp-armv8 -target-abi aapcs-soft -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,SOFT + +// See also llvm/test/CodeGen/AArch64/soft-float-abi.ll, which checks the LLVM +// backend parts of the soft-float ABI. + +// The va_list type does not change between the ABIs +// CHECK: %struct.__va_list = type { ptr, ptr, ptr, i32, i32 } + +// Floats are passed in integer registers, this will be handled by the backend. +// CHECK: define dso_local half @test0(half noundef %a) +// CHECK: define dso_local bfloat @test1(bfloat noundef %a) +// CHECK: define dso_local float @test2(float noundef %a) +// CHECK: define dso_local double @test3(double noundef %a) +// CHECK: define dso_local fp128 @test4(fp128 noundef %a) +__fp16 test0(__fp16 a) { return a; } +__bf16 test1(__bf16 a) { return a; } +float test2(float a) { return a; } +double test3(double a) { return a; } +long double test4(long double a) { return a; } + +// No types are considered to be HFAs or HVAs by the soft-float PCS, so these +// are converted to integer types. +struct A { + float x; +}; +// SOFT: define dso_local i32 @test10(i64 %a.coerce) +// HARD: define dso_local %struct.A @test10([1 x float] alignstack(8) %a.coerce) +struct A test10(struct A a) { return a; } + +struct B { + double x; + double y; +}; +// SOFT: define dso_local [2 x i64] @test11([2 x i64] %a.coerce) +// HARD: define dso_local %struct.B @test11([2 x double] alignstack(8) %a.coerce) +struct B test11(struct B a) { return a; } + +#include <stdarg.h> + +// The layout of the va_list struct is unchanged between the ABIs, but for +// aapcs-soft, floating-point arguments will be retreived from the GPR save +// area, as if they were an integer type of the same size. +// CHECK-LABEL: define dso_local double @test20(i32 noundef %a, ...) +// CHECK: %vl = alloca %struct.__va_list, align 8 +// SOFT: %gr_offs_p = getelementptr inbounds %struct.__va_list, ptr %vl, i32 0, i32 3 +// SOFT: %reg_top_p = getelementptr inbounds %struct.__va_list, ptr %vl, i32 0, i32 1 +// HARD: %vr_offs_p = getelementptr inbounds %struct.__va_list, ptr %vl, i32 0, i32 4 +// HARD: %reg_top_p = getelementptr inbounds %struct.__va_list, ptr %vl, i32 0, i32 2 +double test20(int a, ...) { + va_list vl; + va_start(vl, a); + return va_arg(vl, double); +} + +// Vector types are only available for targets with the correct hardware, and +// their calling-convention is left undefined by the soft-float ABI, so they +// aren't tested here. diff --git a/clang/test/CodeGen/attr-target-clones-aarch64.c b/clang/test/CodeGen/attr-target-clones-aarch64.c index 276a7b87b7a1..94095f9aa3e1 100644 --- a/clang/test/CodeGen/attr-target-clones-aarch64.c +++ b/clang/test/CodeGen/attr-target-clones-aarch64.c @@ -23,8 +23,6 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) - - //. // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } // CHECK: @ftc.ifunc = weak_odr alias i32 (), ptr @ftc @@ -177,15 +175,7 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK: resolver_return: // CHECK-NEXT: ret ptr @ftc_dup2._McrcMdotprod // CHECK: resolver_else: -// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 256 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 256 -// CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] -// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] -// CHECK: resolver_return1: // CHECK-NEXT: ret ptr @ftc_dup2._Mfp -// CHECK: resolver_else2: -// CHECK-NEXT: ret ptr @ftc_dup2.default // // // CHECK: Function Attrs: noinline nounwind optnone diff --git a/clang/test/CodeGen/target-avx-abi-diag.c b/clang/test/CodeGen/target-avx-abi-diag.c index 84be9e252db5..dfbbc3213ca6 100644 --- a/clang/test/CodeGen/target-avx-abi-diag.c +++ b/clang/test/CodeGen/target-avx-abi-diag.c @@ -2,13 +2,9 @@ // RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx -verify=no512 -o - -S // RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx512f -verify=both -o - -S // RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx512f -target-feature +evex512 -verify=both -o - -S -// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx512f -target-feature -evex512 -verify=avx512-256 -DAVX512_ERR=1 -o - -S -// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx512f -target-feature -evex512 -verify=avx512-256 -DAVX512_ERR=2 -DNOEVEX512 -o - -S -// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx512f -target-feature -evex512 -verify=avx512-256 -DAVX512_ERR=3 -DNOEVEX512 -o - -S +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx512f -target-feature -evex512 -verify=avx512-256 -DNOEVEX512 -o - -S // RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx10.1-512 -verify=both -o - -S -// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx10.1-256 -verify=avx512-256 -DAVX512_ERR=1 -o - -S -// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx10.1-256 -verify=avx512-256 -DAVX512_ERR=2 -o - -S -// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx10.1-256 -verify=avx512-256 -DAVX512_ERR=3 -o - -S +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx10.1-256 -verify=avx512-256 -o - -S // REQUIRES: x86-registered-target // both-no-diagnostics @@ -25,7 +21,6 @@ void takesAvx512_no_target(avx512fType t); void variadic(int i, ...); __attribute__((target("avx512f"))) void variadic_err(int i, ...); -#if !defined(AVX512_ERR) || AVX512_ERR == 1 // If neither side has an attribute, warn. void call_warn(void) { avx256Type t1; @@ -39,9 +34,7 @@ void call_warn(void) { // avx512-256-error@+1 {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'evex512' enabled changes the ABI}} variadic(3, t2); // no512-warning {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'avx512f' enabled changes the ABI}} } -#endif -#if !defined(AVX512_ERR) || AVX512_ERR == 2 // If only 1 side has an attribute, error. void call_errors(void) { avx256Type t1; @@ -54,16 +47,21 @@ void call_errors(void) { // avx512-256-error@+1 {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'evex512' enabled changes the ABI}} variadic_err(3, t2); // no512-error {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'avx512f' enabled changes the ABI}} } -#if defined(__AVX10_1__) -// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} -// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} -// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} -// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} -// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} -#endif -#endif -#if !defined(AVX512_ERR) || AVX512_ERR == 3 +// Check that these errors are treated as non-fatal, so we can report them for +// all functions, not just the first. +void call_errors_2(void) { + avx256Type t1; + takesAvx256(t1); // no256-error {{AVX vector argument of type 'avx256Type' (vector of 16 'short' values) without 'avx' enabled changes the ABI}} + avx512fType t2; + // avx512-256-error@+1 {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'evex512' enabled changes the ABI}} + takesAvx512(t2); // no512-error {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'avx512f' enabled changes the ABI}} + + variadic_err(1, t1); // no256-error {{AVX vector argument of type 'avx256Type' (vector of 16 'short' values) without 'avx' enabled changes the ABI}} + // avx512-256-error@+1 {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'evex512' enabled changes the ABI}} + variadic_err(3, t2); // no512-error {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'avx512f' enabled changes the ABI}} +} + __attribute__((target("avx"))) void call_avx256_ok(void) { avx256Type t; takesAvx256(t); @@ -93,5 +91,11 @@ __attribute__((target("avx512f"))) void call_avx512_ok2(void) { // avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} // avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} // avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} -#endif +// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} +// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} +// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} +// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} +// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} +// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} +// avx512-256-warning@*:* {{invalid feature combination: +avx512f +avx10.1-256; will be promoted to avx10.1-512}} #endif diff --git a/clang/test/Driver/aarch64-soft-float-abi.c b/clang/test/Driver/aarch64-soft-float-abi.c new file mode 100644 index 000000000000..0486d94e6607 --- /dev/null +++ b/clang/test/Driver/aarch64-soft-float-abi.c @@ -0,0 +1,26 @@ +// REQUIRES: aarch64-registered-target + +// Hard-float, valid +// RUN: %clang --target=aarch64-none-elf -c %s -o /dev/null +// RUN: %clang --target=aarch64-none-elf -mabi=aapcs -c %s -o /dev/null +// RUN: %clang --target=aarch64-none-elf -march=armv8-r -c %s -o /dev/null +// RUN: %clang --target=aarch64-none-elf -march=armv8-r -mabi=aapcs -c %s -o /dev/null +// RUN: %clang --target=aarch64-none-elf -march=armv8-r+fp -mabi=aapcs -c %s -o /dev/null + +// Soft-float, no FP +// RUN: %clang --target=aarch64-none-elf -march=armv8-r+nofp -mabi=aapcs-soft -c %s -o /dev/null +// RUN: %clang --target=aarch64-none-elf -mgeneral-regs-only -mabi=aapcs-soft -c %s -o /dev/null + +// Soft-float, FP hardware: Rejected, to avoid having two incompatible ABIs for common targets. +// RUN: not %clang --target=aarch64-none-elf -mabi=aapcs-soft -c %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=INVALID-SOFT +// RUN: not %clang --target=aarch64-none-elf -march=armv8-r+fp -mabi=aapcs-soft -c %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=INVALID-SOFT +// RUN: not %clang --target=aarch64-none-elf -march=armv8-r+nofp+fp -mabi=aapcs-soft -c %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=INVALID-SOFT + +// No FP, hard-float. This is accepted by the driver, but functions which +// require arguments or returns to be passed in FP registers will be rejected +// (tested elsewhere). +// RUN: %clang --target=aarch64-none-elf -march=armv8-r+nofp -c %s -o /dev/null +// RUN: %clang --target=aarch64-none-elf -march=armv8-r+nofp -mabi=aapcs -c %s -o /dev/null +// RUN: %clang --target=aarch64-none-elf -mgeneral-regs-only -mabi=aapcs -c %s -o /dev/null + +// INVALID-SOFT: error: 'aapcs-soft' ABI is not supported with FPU diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c index 6ec4dcd60cf6..9f8a8bdeeb9c 100644 --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -342,15 +342,15 @@ // RUN: %clang -target aarch64 -march=armv8-a+fp+simd+crc+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-1 %s // RUN: %clang -target aarch64 -march=armv8-a+nofp+nosimd+nocrc+nocrypto+fp+simd+crc+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-1 %s -// RUN: %clang -target aarch64 -march=armv8-a+nofp+nosimd+nocrc+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-2 %s -// RUN: %clang -target aarch64 -march=armv8-a+fp+simd+crc+crypto+nofp+nosimd+nocrc+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-2 %s +// RUN: %clang -target aarch64 -march=armv8-a+nofp+nosimd+nocrc+nocrypto -mabi=aapcs-soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-2 %s +// RUN: %clang -target aarch64 -march=armv8-a+fp+simd+crc+crypto+nofp+nosimd+nocrc+nocrypto -mabi=aapcs-soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-2 %s // RUN: %clang -target aarch64 -march=armv8-a+nosimd -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-3 %s // CHECK-MARCH-1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+sha2" "-target-feature" "+neon" // CHECK-MARCH-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "-fp-armv8"{{.*}} "-target-feature" "-neon" // CHECK-MARCH-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "-neon" // While we're checking +nofp, also make sure it stops defining __ARM_FP -// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-r+nofp -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-NOFP %s +// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-r+nofp -mabi=aapcs-soft -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-NOFP %s // CHECK-NOFP-NOT: #define __ARM_FP{{ }} // Check +sm4: diff --git a/clang/test/Sema/arm-vector-types-support.c b/clang/test/Sema/arm-vector-types-support.c index 83a83ddfe780..ed5f5ba175a9 100644 --- a/clang/test/Sema/arm-vector-types-support.c +++ b/clang/test/Sema/arm-vector-types-support.c @@ -1,4 +1,6 @@ // RUN: %clang_cc1 %s -triple armv7 -fsyntax-only -verify +// RUN: %clang_cc1 %s -triple aarch64 -fsyntax-only -verify +// RUN: %clang_cc1 %s -triple aarch64 -target-feature -fp-armv8 -target-abi aapcs-soft -fsyntax-only -verify typedef __attribute__((neon_vector_type(2))) int int32x2_t; // expected-error{{'neon_vector_type' attribute is not supported on targets missing 'neon', 'mve', 'sve' or 'sme'; specify an appropriate -march= or -mcpu=}} typedef __attribute__((neon_polyvector_type(16))) short poly8x16_t; // expected-error{{'neon_polyvector_type' attribute is not supported on targets missing 'neon' or 'mve'; specify an appropriate -march= or -mcpu=}} diff --git a/llvm/test/CodeGen/AArch64/soft-float-abi.ll b/llvm/test/CodeGen/AArch64/soft-float-abi.ll new file mode 100644 index 000000000000..291c3875c248 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/soft-float-abi.ll @@ -0,0 +1,161 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc --mtriple aarch64-none-eabi < %s -mattr=-fp-armv8 | FileCheck %s + +; See also clang/test/CodeGen/aarch64-soft-float-abi.c, which tests the clang +; parts of the soft-float ABI. + +; FP types up to 64-bit are passed in a general purpose register. +define half @test0(half %a, half %b) { +; CHECK-LABEL: test0: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov w0, w1 +; CHECK-NEXT: ret +entry: + ret half %b +} + +define bfloat @test1(i32 %a, bfloat %b) { +; CHECK-LABEL: test1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov w0, w1 +; CHECK-NEXT: ret +entry: + ret bfloat %b +} + +define float @test2(i64 %a, float %b) { +; CHECK-LABEL: test2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov w0, w1 +; CHECK-NEXT: ret +entry: + ret float %b +} + +define double @test3(half %a, double %b) { +; CHECK-LABEL: test3: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov x0, x1 +; CHECK-NEXT: ret +entry: + ret double %b +} + +; fp128 is passed in a pair of GPRs. +define fp128 @test4(fp128 %a, fp128 %b) { +; CHECK-LABEL: test4: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov x1, x3 +; CHECK-NEXT: mov x0, x2 +; CHECK-NEXT: ret +entry: + ret fp128 %b +} + +; fp128 is passed in an aligned pair of GPRs, leaving one register unused is +; necessary. +define fp128 @test5(float %a, fp128 %b) { +; CHECK-LABEL: test5: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov x1, x3 +; CHECK-NEXT: mov x0, x2 +; CHECK-NEXT: ret +entry: + ret fp128 %b +} + +; If the alignment of an fp128 leaves a register unused, it remains unused even +; if a later argument could fit in it. +define i64 @test6(i64 %a, fp128 %b, i64 %c) { +; CHECK-LABEL: test6: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov x0, x4 +; CHECK-NEXT: ret +entry: + ret i64 %c +} + +; HFAs are all bit-casted to integer types in the frontend when using the +; soft-float ABI, so they get passed in the same way as non-homeogeneous +; aggregates. The IR is identical to the equivalent integer types, so nothing +; to test here. + +; The PCS for vector and HVA types is not defined by the soft-float ABI because +; these types are only defined by the ACLE when vector hardware is available, +; so nothing to test here. + +; The front-end generates IR for va_arg which always reads from the integer +; register save area, and never the floating-point register save area. The +; layout of the va_list type remains the same, the floating-point related +; fields are unused. The only change needed in the backend is in va_start, to +; not attempt to save the floating-point registers or set the FP fields in the +; va_list. +%struct.__va_list = type { ptr, ptr, ptr, i32, i32 } +declare void @llvm.va_start(ptr) +define double @test20(i32 %a, ...) { +; CHECK-LABEL: test20: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: sub sp, sp, #96 +; CHECK-NEXT: .cfi_def_cfa_offset 96 +; CHECK-NEXT: mov w8, #-56 // =0xffffffc8 +; CHECK-NEXT: add x10, sp, #8 +; CHECK-NEXT: add x9, sp, #96 +; CHECK-NEXT: str x8, [sp, #88] +; CHECK-NEXT: add x10, x10, #56 +; CHECK-NEXT: ldrsw x8, [sp, #88] +; CHECK-NEXT: stp x1, x2, [sp, #8] +; CHECK-NEXT: stp x3, x4, [sp, #24] +; CHECK-NEXT: stp x5, x6, [sp, #40] +; CHECK-NEXT: stp x7, x9, [sp, #56] +; CHECK-NEXT: str x10, [sp, #72] +; CHECK-NEXT: tbz w8, #31, .LBB7_3 +; CHECK-NEXT: // %bb.1: // %vaarg.maybe_reg +; CHECK-NEXT: add w9, w8, #8 +; CHECK-NEXT: cmn w8, #8 +; CHECK-NEXT: str w9, [sp, #88] +; CHECK-NEXT: b.gt .LBB7_3 +; CHECK-NEXT: // %bb.2: // %vaarg.in_reg +; CHECK-NEXT: ldr x9, [sp, #72] +; CHECK-NEXT: add x8, x9, x8 +; CHECK-NEXT: b .LBB7_4 +; CHECK-NEXT: .LBB7_3: // %vaarg.on_stack +; CHECK-NEXT: ldr x8, [sp, #64] +; CHECK-NEXT: add x9, x8, #8 +; CHECK-NEXT: str x9, [sp, #64] +; CHECK-NEXT: .LBB7_4: // %vaarg.end +; CHECK-NEXT: ldr x0, [x8] +; CHECK-NEXT: add sp, sp, #96 +; CHECK-NEXT: ret +entry: + %vl = alloca %struct.__va_list, align 8 + call void @llvm.va_start(ptr nonnull %vl) + %gr_offs_p = getelementptr inbounds %struct.__va_list, ptr %vl, i64 0, i32 3 + %gr_offs = load i32, ptr %gr_offs_p, align 8 + %0 = icmp sgt i32 %gr_offs, -1 + br i1 %0, label %vaarg.on_stack, label %vaarg.maybe_reg + +vaarg.maybe_reg: ; preds = %entry + %new_reg_offs = add nsw i32 %gr_offs, 8 + store i32 %new_reg_offs, ptr %gr_offs_p, align 8 + %inreg = icmp slt i32 %gr_offs, -7 + br i1 %inreg, label %vaarg.in_reg, label %vaarg.on_stack + +vaarg.in_reg: ; preds = %vaarg.maybe_reg + %reg_top_p = getelementptr inbounds %struct.__va_list, ptr %vl, i64 0, i32 1 + %reg_top = load ptr, ptr %reg_top_p, align 8 + %1 = sext i32 %gr_offs to i64 + %2 = getelementptr inbounds i8, ptr %reg_top, i64 %1 + br label %vaarg.end + +vaarg.on_stack: ; preds = %vaarg.maybe_reg, %entry + %stack = load ptr, ptr %vl, align 8 + %new_stack = getelementptr inbounds i8, ptr %stack, i64 8 + store ptr %new_stack, ptr %vl, align 8 + br label %vaarg.end + +vaarg.end: ; preds = %vaarg.on_stack, %vaarg.in_reg + %vaargs.addr = phi ptr [ %2, %vaarg.in_reg ], [ %stack, %vaarg.on_stack ] + %3 = load double, ptr %vaargs.addr, align 8 + ret double %3 +} + -- GitLab From 4aec1438cdb2326c3709d57a5ec22fe436d4d8f1 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Tue, 19 Mar 2024 15:25:36 +0100 Subject: [PATCH 081/307] [bazel] Make grab bag //libc:internal_includes textual, some of these don't even parse --- utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 01bb8b4298cd..77fb8c16507b 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -66,7 +66,7 @@ config_setting( libc_support_library( name = "internal_includes", - hdrs = glob([ + textual_hdrs = glob([ "include/llvm-libc-macros/*.h", "include/llvm-libc-types/*", ]), -- GitLab From 7ef433f62c199c414bffdcac1c8ee3159b29c5f5 Mon Sep 17 00:00:00 2001 From: Jeremy Morse <jeremy.morse@sony.com> Date: Tue, 19 Mar 2024 14:30:41 +0000 Subject: [PATCH 082/307] [NFC][RemoveDIs] Switch ConstantExpr::getAsInstruction to not insert (#84737) Because the RemoveDIs work is putting a debug-info bit into BasicBlock::iterator and iterators are needed for insertion, the getAsInstruction method declaration would need to use a fully defined instruction-iterator, which leads to a complicated header-inclusion-order problem. Much simpler to instead just not insert, and make it the callers problem to insert. This is proportionate because there are only four call-sites to getAsInstruction -- it would suck if we did this everywhere. --------- Merged by: Stephen Tozer <stephen.tozer@sony.com> --- llvm/include/llvm/IR/Constants.h | 5 ++--- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 13 ++++++++---- llvm/lib/IR/Constants.cpp | 21 +++++++++---------- llvm/lib/IR/ReplaceConstant.cpp | 13 ++++++------ .../Target/XCore/XCoreLowerThreadLocal.cpp | 9 +++++--- 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h index c0ac9a4aa675..c5e1e19d6498 100644 --- a/llvm/include/llvm/IR/Constants.h +++ b/llvm/include/llvm/IR/Constants.h @@ -1289,14 +1289,13 @@ public: Type *SrcTy = nullptr) const; /// Returns an Instruction which implements the same operation as this - /// ConstantExpr. If \p InsertBefore is not null, the new instruction is - /// inserted before it, otherwise it is not inserted into any basic block. + /// ConstantExpr. It is not inserted into any basic block. /// /// A better approach to this could be to have a constructor for Instruction /// which would take a ConstantExpr parameter, but that would have spread /// implementation details of ConstantExpr outside of Constants.cpp, which /// would make it harder to remove ConstantExprs altogether. - Instruction *getAsInstruction(Instruction *InsertBefore = nullptr) const; + Instruction *getAsInstruction() const; /// Whether creating a constant expression for this binary operator is /// desirable. diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index c07ee34bfb7a..16507a69ea85 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -5073,10 +5073,15 @@ FunctionCallee OpenMPIRBuilder::createDispatchFiniFunction(unsigned IVSize, static void replaceConstatExprUsesInFuncWithInstr(ConstantExpr *ConstExpr, Function *Func) { - for (User *User : make_early_inc_range(ConstExpr->users())) - if (auto *Instr = dyn_cast<Instruction>(User)) - if (Instr->getFunction() == Func) - Instr->replaceUsesOfWith(ConstExpr, ConstExpr->getAsInstruction(Instr)); + for (User *User : make_early_inc_range(ConstExpr->users())) { + if (auto *Instr = dyn_cast<Instruction>(User)) { + if (Instr->getFunction() == Func) { + Instruction *ConstInst = ConstExpr->getAsInstruction(); + ConstInst->insertBefore(*Instr->getParent(), Instr->getIterator()); + Instr->replaceUsesOfWith(ConstExpr, ConstInst); + } + } + } } static void replaceConstantValueUsesInFuncWithInstr(llvm::Value *Input, diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index e6b92aad392f..07b5bced96da 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -3303,7 +3303,7 @@ Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV) { NewOps, this, From, To, NumUpdated, OperandNo); } -Instruction *ConstantExpr::getAsInstruction(Instruction *InsertBefore) const { +Instruction *ConstantExpr::getAsInstruction() const { SmallVector<Value *, 4> ValueOperands(operands()); ArrayRef<Value*> Ops(ValueOperands); @@ -3322,32 +3322,31 @@ Instruction *ConstantExpr::getAsInstruction(Instruction *InsertBefore) const { case Instruction::BitCast: case Instruction::AddrSpaceCast: return CastInst::Create((Instruction::CastOps)getOpcode(), Ops[0], - getType(), "", InsertBefore); + getType(), ""); case Instruction::InsertElement: - return InsertElementInst::Create(Ops[0], Ops[1], Ops[2], "", InsertBefore); + return InsertElementInst::Create(Ops[0], Ops[1], Ops[2], ""); case Instruction::ExtractElement: - return ExtractElementInst::Create(Ops[0], Ops[1], "", InsertBefore); + return ExtractElementInst::Create(Ops[0], Ops[1], ""); case Instruction::ShuffleVector: - return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask(), "", - InsertBefore); + return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask(), ""); case Instruction::GetElementPtr: { const auto *GO = cast<GEPOperator>(this); if (GO->isInBounds()) - return GetElementPtrInst::CreateInBounds( - GO->getSourceElementType(), Ops[0], Ops.slice(1), "", InsertBefore); + return GetElementPtrInst::CreateInBounds(GO->getSourceElementType(), + Ops[0], Ops.slice(1), ""); return GetElementPtrInst::Create(GO->getSourceElementType(), Ops[0], - Ops.slice(1), "", InsertBefore); + Ops.slice(1), ""); } case Instruction::ICmp: case Instruction::FCmp: return CmpInst::Create((Instruction::OtherOps)getOpcode(), (CmpInst::Predicate)getPredicate(), Ops[0], Ops[1], - "", InsertBefore); + ""); default: assert(getNumOperands() == 2 && "Must be binary operator?"); BinaryOperator *BO = BinaryOperator::Create( - (Instruction::BinaryOps)getOpcode(), Ops[0], Ops[1], "", InsertBefore); + (Instruction::BinaryOps)getOpcode(), Ops[0], Ops[1], ""); if (isa<OverflowingBinaryOperator>(BO)) { BO->setHasNoUnsignedWrap(SubclassOptionalData & OverflowingBinaryOperator::NoUnsignedWrap); diff --git a/llvm/lib/IR/ReplaceConstant.cpp b/llvm/lib/IR/ReplaceConstant.cpp index 42dec7c72328..9b07bd804049 100644 --- a/llvm/lib/IR/ReplaceConstant.cpp +++ b/llvm/lib/IR/ReplaceConstant.cpp @@ -22,11 +22,13 @@ static bool isExpandableUser(User *U) { return isa<ConstantExpr>(U) || isa<ConstantAggregate>(U); } -static SmallVector<Instruction *, 4> expandUser(Instruction *InsertPt, +static SmallVector<Instruction *, 4> expandUser(BasicBlock::iterator InsertPt, Constant *C) { SmallVector<Instruction *, 4> NewInsts; if (auto *CE = dyn_cast<ConstantExpr>(C)) { - NewInsts.push_back(CE->getAsInstruction(InsertPt)); + Instruction *ConstInst = CE->getAsInstruction(); + ConstInst->insertBefore(*InsertPt->getParent(), InsertPt); + NewInsts.push_back(ConstInst); } else if (isa<ConstantStruct>(C) || isa<ConstantArray>(C)) { Value *V = PoisonValue::get(C->getType()); for (auto [Idx, Op] : enumerate(C->operands())) { @@ -80,12 +82,11 @@ bool convertUsersOfConstantsToInstructions(ArrayRef<Constant *> Consts) { Instruction *I = InstructionWorklist.pop_back_val(); DebugLoc Loc = I->getDebugLoc(); for (Use &U : I->operands()) { - auto *BI = I; + BasicBlock::iterator BI = I->getIterator(); if (auto *Phi = dyn_cast<PHINode>(I)) { BasicBlock *BB = Phi->getIncomingBlock(U); - BasicBlock::iterator It = BB->getFirstInsertionPt(); - assert(It != BB->end() && "Unexpected empty basic block"); - BI = &*It; + BI = BB->getFirstInsertionPt(); + assert(BI != BB->end() && "Unexpected empty basic block"); } if (auto *C = dyn_cast<Constant>(U.get())) { diff --git a/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp b/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp index b5a683de33ab..5e91cce1068b 100644 --- a/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp +++ b/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp @@ -88,12 +88,15 @@ static bool replaceConstantExprOp(ConstantExpr *CE, Pass *P) { BasicBlock *PredBB = PN->getIncomingBlock(I); if (PredBB->getTerminator()->getNumSuccessors() > 1) PredBB = SplitEdge(PredBB, PN->getParent()); - Instruction *InsertPos = PredBB->getTerminator(); - Instruction *NewInst = CE->getAsInstruction(InsertPos); + BasicBlock::iterator InsertPos = + PredBB->getTerminator()->getIterator(); + Instruction *NewInst = CE->getAsInstruction(); + NewInst->insertBefore(*PredBB, InsertPos); PN->setOperand(I, NewInst); } } else if (Instruction *Instr = dyn_cast<Instruction>(WU)) { - Instruction *NewInst = CE->getAsInstruction(Instr); + Instruction *NewInst = CE->getAsInstruction(); + NewInst->insertBefore(*Instr->getParent(), Instr->getIterator()); Instr->replaceUsesOfWith(CE, NewInst); } else { ConstantExpr *CExpr = dyn_cast<ConstantExpr>(WU); -- GitLab From b4b7d988bdb48827a822d9c87fdc460dceae5cab Mon Sep 17 00:00:00 2001 From: Leandro Lupori <leandro.lupori@linaro.org> Date: Tue, 19 Mar 2024 11:35:52 -0300 Subject: [PATCH 083/307] [flang] Fix cuda-option test on Darwin (#85687) On Darwin, -isysroot is needed and is automatically appended to %flang and %flang_fc1, so use %flang_fc1 instead to have both -fc1 and -isysroot in the expected positions and avoid errors. --- flang/test/Driver/cuda-option.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flang/test/Driver/cuda-option.f90 b/flang/test/Driver/cuda-option.f90 index 112e1cb6c77f..562f8683b0ff 100644 --- a/flang/test/Driver/cuda-option.f90 +++ b/flang/test/Driver/cuda-option.f90 @@ -1,6 +1,6 @@ ! Test -fcuda option -! RUN: %flang -fc1 -cpp -x cuda -fdebug-unparse %s -o - | FileCheck %s -! RUN: not %flang -fc1 -cpp %s -o - 2>&1 | FileCheck %s --check-prefix=ERROR +! RUN: %flang_fc1 -cpp -x cuda -fdebug-unparse %s -o - | FileCheck %s +! RUN: not %flang_fc1 -cpp %s -o - 2>&1 | FileCheck %s --check-prefix=ERROR program main #if _CUDA integer :: var = _CUDA -- GitLab From db4170a4f3a701a62f5c1ef2e6a30f490f107f7d Mon Sep 17 00:00:00 2001 From: Stephen Tozer <stephen.tozer@sony.com> Date: Tue, 19 Mar 2024 14:37:26 +0000 Subject: [PATCH 084/307] Revert "[flang] Fix cuda-option test on Darwin (#85687)" Reverted due to buildbot failures: https://lab.llvm.org/buildbot/#/builders/139/builds/61717/ This reverts commit b4b7d988bdb48827a822d9c87fdc460dceae5cab. --- flang/test/Driver/cuda-option.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flang/test/Driver/cuda-option.f90 b/flang/test/Driver/cuda-option.f90 index 562f8683b0ff..112e1cb6c77f 100644 --- a/flang/test/Driver/cuda-option.f90 +++ b/flang/test/Driver/cuda-option.f90 @@ -1,6 +1,6 @@ ! Test -fcuda option -! RUN: %flang_fc1 -cpp -x cuda -fdebug-unparse %s -o - | FileCheck %s -! RUN: not %flang_fc1 -cpp %s -o - 2>&1 | FileCheck %s --check-prefix=ERROR +! RUN: %flang -fc1 -cpp -x cuda -fdebug-unparse %s -o - | FileCheck %s +! RUN: not %flang -fc1 -cpp %s -o - 2>&1 | FileCheck %s --check-prefix=ERROR program main #if _CUDA integer :: var = _CUDA -- GitLab From 885f93d62a0a7d2955a755cdc451d394577b36e2 Mon Sep 17 00:00:00 2001 From: Stephen Tozer <stephen.tozer@sony.com> Date: Tue, 19 Mar 2024 14:40:46 +0000 Subject: [PATCH 085/307] Reapply "[flang] Fix cuda-option test on Darwin (#85687)" This commit was mistakenly reverted in place of the actual failing commit prior; reapplying. This reverts commit db4170a4f3a701a62f5c1ef2e6a30f490f107f7d. --- flang/test/Driver/cuda-option.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flang/test/Driver/cuda-option.f90 b/flang/test/Driver/cuda-option.f90 index 112e1cb6c77f..562f8683b0ff 100644 --- a/flang/test/Driver/cuda-option.f90 +++ b/flang/test/Driver/cuda-option.f90 @@ -1,6 +1,6 @@ ! Test -fcuda option -! RUN: %flang -fc1 -cpp -x cuda -fdebug-unparse %s -o - | FileCheck %s -! RUN: not %flang -fc1 -cpp %s -o - 2>&1 | FileCheck %s --check-prefix=ERROR +! RUN: %flang_fc1 -cpp -x cuda -fdebug-unparse %s -o - | FileCheck %s +! RUN: not %flang_fc1 -cpp %s -o - 2>&1 | FileCheck %s --check-prefix=ERROR program main #if _CUDA integer :: var = _CUDA -- GitLab From ab851f7fe946e7eed700ef9d82082eb721860189 Mon Sep 17 00:00:00 2001 From: Stephen Tozer <stephen.tozer@sony.com> Date: Tue, 19 Mar 2024 14:41:27 +0000 Subject: [PATCH 086/307] Revert "[NFC][RemoveDIs] Switch ConstantExpr::getAsInstruction to not insert (#84737)" Reverted due to buildbot failures: https://lab.llvm.org/buildbot/#/builders/139/builds/61717/ This reverts commit 7ef433f62c199c414bffdcac1c8ee3159b29c5f5. --- llvm/include/llvm/IR/Constants.h | 5 +++-- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 13 ++++-------- llvm/lib/IR/Constants.cpp | 21 ++++++++++--------- llvm/lib/IR/ReplaceConstant.cpp | 13 ++++++------ .../Target/XCore/XCoreLowerThreadLocal.cpp | 9 +++----- 5 files changed, 27 insertions(+), 34 deletions(-) diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h index c5e1e19d6498..c0ac9a4aa675 100644 --- a/llvm/include/llvm/IR/Constants.h +++ b/llvm/include/llvm/IR/Constants.h @@ -1289,13 +1289,14 @@ public: Type *SrcTy = nullptr) const; /// Returns an Instruction which implements the same operation as this - /// ConstantExpr. It is not inserted into any basic block. + /// ConstantExpr. If \p InsertBefore is not null, the new instruction is + /// inserted before it, otherwise it is not inserted into any basic block. /// /// A better approach to this could be to have a constructor for Instruction /// which would take a ConstantExpr parameter, but that would have spread /// implementation details of ConstantExpr outside of Constants.cpp, which /// would make it harder to remove ConstantExprs altogether. - Instruction *getAsInstruction() const; + Instruction *getAsInstruction(Instruction *InsertBefore = nullptr) const; /// Whether creating a constant expression for this binary operator is /// desirable. diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index 16507a69ea85..c07ee34bfb7a 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -5073,15 +5073,10 @@ FunctionCallee OpenMPIRBuilder::createDispatchFiniFunction(unsigned IVSize, static void replaceConstatExprUsesInFuncWithInstr(ConstantExpr *ConstExpr, Function *Func) { - for (User *User : make_early_inc_range(ConstExpr->users())) { - if (auto *Instr = dyn_cast<Instruction>(User)) { - if (Instr->getFunction() == Func) { - Instruction *ConstInst = ConstExpr->getAsInstruction(); - ConstInst->insertBefore(*Instr->getParent(), Instr->getIterator()); - Instr->replaceUsesOfWith(ConstExpr, ConstInst); - } - } - } + for (User *User : make_early_inc_range(ConstExpr->users())) + if (auto *Instr = dyn_cast<Instruction>(User)) + if (Instr->getFunction() == Func) + Instr->replaceUsesOfWith(ConstExpr, ConstExpr->getAsInstruction(Instr)); } static void replaceConstantValueUsesInFuncWithInstr(llvm::Value *Input, diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 07b5bced96da..e6b92aad392f 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -3303,7 +3303,7 @@ Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV) { NewOps, this, From, To, NumUpdated, OperandNo); } -Instruction *ConstantExpr::getAsInstruction() const { +Instruction *ConstantExpr::getAsInstruction(Instruction *InsertBefore) const { SmallVector<Value *, 4> ValueOperands(operands()); ArrayRef<Value*> Ops(ValueOperands); @@ -3322,31 +3322,32 @@ Instruction *ConstantExpr::getAsInstruction() const { case Instruction::BitCast: case Instruction::AddrSpaceCast: return CastInst::Create((Instruction::CastOps)getOpcode(), Ops[0], - getType(), ""); + getType(), "", InsertBefore); case Instruction::InsertElement: - return InsertElementInst::Create(Ops[0], Ops[1], Ops[2], ""); + return InsertElementInst::Create(Ops[0], Ops[1], Ops[2], "", InsertBefore); case Instruction::ExtractElement: - return ExtractElementInst::Create(Ops[0], Ops[1], ""); + return ExtractElementInst::Create(Ops[0], Ops[1], "", InsertBefore); case Instruction::ShuffleVector: - return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask(), ""); + return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask(), "", + InsertBefore); case Instruction::GetElementPtr: { const auto *GO = cast<GEPOperator>(this); if (GO->isInBounds()) - return GetElementPtrInst::CreateInBounds(GO->getSourceElementType(), - Ops[0], Ops.slice(1), ""); + return GetElementPtrInst::CreateInBounds( + GO->getSourceElementType(), Ops[0], Ops.slice(1), "", InsertBefore); return GetElementPtrInst::Create(GO->getSourceElementType(), Ops[0], - Ops.slice(1), ""); + Ops.slice(1), "", InsertBefore); } case Instruction::ICmp: case Instruction::FCmp: return CmpInst::Create((Instruction::OtherOps)getOpcode(), (CmpInst::Predicate)getPredicate(), Ops[0], Ops[1], - ""); + "", InsertBefore); default: assert(getNumOperands() == 2 && "Must be binary operator?"); BinaryOperator *BO = BinaryOperator::Create( - (Instruction::BinaryOps)getOpcode(), Ops[0], Ops[1], ""); + (Instruction::BinaryOps)getOpcode(), Ops[0], Ops[1], "", InsertBefore); if (isa<OverflowingBinaryOperator>(BO)) { BO->setHasNoUnsignedWrap(SubclassOptionalData & OverflowingBinaryOperator::NoUnsignedWrap); diff --git a/llvm/lib/IR/ReplaceConstant.cpp b/llvm/lib/IR/ReplaceConstant.cpp index 9b07bd804049..42dec7c72328 100644 --- a/llvm/lib/IR/ReplaceConstant.cpp +++ b/llvm/lib/IR/ReplaceConstant.cpp @@ -22,13 +22,11 @@ static bool isExpandableUser(User *U) { return isa<ConstantExpr>(U) || isa<ConstantAggregate>(U); } -static SmallVector<Instruction *, 4> expandUser(BasicBlock::iterator InsertPt, +static SmallVector<Instruction *, 4> expandUser(Instruction *InsertPt, Constant *C) { SmallVector<Instruction *, 4> NewInsts; if (auto *CE = dyn_cast<ConstantExpr>(C)) { - Instruction *ConstInst = CE->getAsInstruction(); - ConstInst->insertBefore(*InsertPt->getParent(), InsertPt); - NewInsts.push_back(ConstInst); + NewInsts.push_back(CE->getAsInstruction(InsertPt)); } else if (isa<ConstantStruct>(C) || isa<ConstantArray>(C)) { Value *V = PoisonValue::get(C->getType()); for (auto [Idx, Op] : enumerate(C->operands())) { @@ -82,11 +80,12 @@ bool convertUsersOfConstantsToInstructions(ArrayRef<Constant *> Consts) { Instruction *I = InstructionWorklist.pop_back_val(); DebugLoc Loc = I->getDebugLoc(); for (Use &U : I->operands()) { - BasicBlock::iterator BI = I->getIterator(); + auto *BI = I; if (auto *Phi = dyn_cast<PHINode>(I)) { BasicBlock *BB = Phi->getIncomingBlock(U); - BI = BB->getFirstInsertionPt(); - assert(BI != BB->end() && "Unexpected empty basic block"); + BasicBlock::iterator It = BB->getFirstInsertionPt(); + assert(It != BB->end() && "Unexpected empty basic block"); + BI = &*It; } if (auto *C = dyn_cast<Constant>(U.get())) { diff --git a/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp b/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp index 5e91cce1068b..b5a683de33ab 100644 --- a/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp +++ b/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp @@ -88,15 +88,12 @@ static bool replaceConstantExprOp(ConstantExpr *CE, Pass *P) { BasicBlock *PredBB = PN->getIncomingBlock(I); if (PredBB->getTerminator()->getNumSuccessors() > 1) PredBB = SplitEdge(PredBB, PN->getParent()); - BasicBlock::iterator InsertPos = - PredBB->getTerminator()->getIterator(); - Instruction *NewInst = CE->getAsInstruction(); - NewInst->insertBefore(*PredBB, InsertPos); + Instruction *InsertPos = PredBB->getTerminator(); + Instruction *NewInst = CE->getAsInstruction(InsertPos); PN->setOperand(I, NewInst); } } else if (Instruction *Instr = dyn_cast<Instruction>(WU)) { - Instruction *NewInst = CE->getAsInstruction(); - NewInst->insertBefore(*Instr->getParent(), Instr->getIterator()); + Instruction *NewInst = CE->getAsInstruction(Instr); Instr->replaceUsesOfWith(CE, NewInst); } else { ConstantExpr *CExpr = dyn_cast<ConstantExpr>(WU); -- GitLab From b59c2a0eb499d8daf8086cd9875083d32496cc58 Mon Sep 17 00:00:00 2001 From: alx32 <103613512+alx32@users.noreply.github.com> Date: Tue, 19 Mar 2024 07:43:09 -0700 Subject: [PATCH 087/307] [llvm-objdump][macho] Fix relative method list dumping for little endian hosts (#85778) `macho-relative-method-lists.test` is failing on little endian platforms, when matching 'name'. ``` CHK32-NEXT: name 0x144 (0x{{[0-9a-f]*}}) instance_method_00 next:10'0 X error: no match found 18: name 0x144 (0x7ac) ``` This seems like the obvious fix. Co-authored-by: Alex B <alexborcan@meta.com> --- .../MachO/AArch64/macho-relative-method-lists.test | 1 - llvm/tools/llvm-objdump/MachODump.cpp | 12 ++++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test b/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test index 8e1a9b679704..b1b96a41a329 100644 --- a/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test +++ b/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test @@ -1,4 +1,3 @@ -XFAIL: system-aix RUN: llvm-objdump --macho --objc-meta-data %p/Inputs/rel-method-lists-arm64_32.dylib | FileCheck %s --check-prefix=CHK32 RUN: llvm-otool -ov %p/Inputs/rel-method-lists-arm64_32.dylib | FileCheck %s --check-prefix=CHK32 diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index 1b0e5ba279d0..5e0d69a68d69 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -4499,11 +4499,15 @@ static void print_relative_method_list(uint32_t structSizeAndFlags, outs() << indent << " (nameRefPtr extends past the end of the section)"; else { if (pointerSize == 64) { - name = get_pointer_64(*reinterpret_cast<const uint64_t *>(nameRefPtr), - xoffset, left, xS, info); + uint64_t nameOff_64 = *reinterpret_cast<const uint64_t *>(nameRefPtr); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + sys::swapByteOrder(nameOff_64); + name = get_pointer_64(nameOff_64, xoffset, left, xS, info); } else { - name = get_pointer_32(*reinterpret_cast<const uint32_t *>(nameRefPtr), - xoffset, left, xS, info); + uint32_t nameOff_32 = *reinterpret_cast<const uint32_t *>(nameRefPtr); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + sys::swapByteOrder(nameOff_32); + name = get_pointer_32(nameOff_32, xoffset, left, xS, info); } if (name != nullptr) outs() << format(" %.*s", left, name); -- GitLab From 0e7681867242ccf9138e7e6a9c2d9925b6ee1e49 Mon Sep 17 00:00:00 2001 From: Nikita Popov <npopov@redhat.com> Date: Tue, 19 Mar 2024 15:42:32 +0100 Subject: [PATCH 088/307] [ValueTracking] Test isKnownNonZero() range metadata with vector (NFC) --- llvm/test/Analysis/ValueTracking/known-non-zero.ll | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/llvm/test/Analysis/ValueTracking/known-non-zero.ll b/llvm/test/Analysis/ValueTracking/known-non-zero.ll index d804fe966490..f514968715c2 100644 --- a/llvm/test/Analysis/ValueTracking/known-non-zero.ll +++ b/llvm/test/Analysis/ValueTracking/known-non-zero.ll @@ -1292,4 +1292,18 @@ true: false: ret i1 %ne } + +define <2 x i1> @range_metadata_vec(ptr %p, <2 x i32> %x) { +; CHECK-LABEL: @range_metadata_vec( +; CHECK-NEXT: [[Z:%.*]] = load <2 x i32>, ptr [[P:%.*]], align 8, !range [[RNG0:![0-9]+]] +; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[Z]], [[X:%.*]] +; CHECK-NEXT: [[CMP0:%.*]] = icmp ne <2 x i32> [[OR]], zeroinitializer +; CHECK-NEXT: ret <2 x i1> [[CMP0]] +; + %v = load <2 x i32>, ptr %p, !range !{i32 1, i32 100} + %or = or <2 x i32> %v, %x + %cmp = icmp ne <2 x i32> %or, zeroinitializer + ret <2 x i1> %cmp +} + declare i32 @llvm.experimental.get.vector.length.i32(i32, i32, i1) -- GitLab From 6872a646523c1e85a98dfa20b2f4dd7774e10ba4 Mon Sep 17 00:00:00 2001 From: Nikita Popov <npopov@redhat.com> Date: Tue, 19 Mar 2024 15:46:43 +0100 Subject: [PATCH 089/307] [ValueTracking] Handle vector range metadata in isKnownNonZero() Nowadays !range can be placed on instructions with vector of int return value. Support this case in isKnownNonZero(). --- llvm/lib/Analysis/ValueTracking.cpp | 9 ++++----- llvm/test/Analysis/ValueTracking/known-non-zero.ll | 5 +---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 2e0a930cf0a3..bf6afad3636b 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2918,11 +2918,10 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, if (MDNode *Ranges = Q.IIQ.getMetadata(I, LLVMContext::MD_range)) { // If the possible ranges don't contain zero, then the value is // definitely non-zero. - if (auto *Ty = dyn_cast<IntegerType>(V->getType())) { - const APInt ZeroValue(Ty->getBitWidth(), 0); - if (rangeMetadataExcludesValue(Ranges, ZeroValue)) - return true; - } + assert(V->getType()->isIntOrIntVectorTy() && "Range on non-integer?"); + const APInt ZeroValue(Ty->getScalarSizeInBits(), 0); + if (rangeMetadataExcludesValue(Ranges, ZeroValue)) + return true; } } diff --git a/llvm/test/Analysis/ValueTracking/known-non-zero.ll b/llvm/test/Analysis/ValueTracking/known-non-zero.ll index f514968715c2..30d340dc725a 100644 --- a/llvm/test/Analysis/ValueTracking/known-non-zero.ll +++ b/llvm/test/Analysis/ValueTracking/known-non-zero.ll @@ -1295,10 +1295,7 @@ false: define <2 x i1> @range_metadata_vec(ptr %p, <2 x i32> %x) { ; CHECK-LABEL: @range_metadata_vec( -; CHECK-NEXT: [[Z:%.*]] = load <2 x i32>, ptr [[P:%.*]], align 8, !range [[RNG0:![0-9]+]] -; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[Z]], [[X:%.*]] -; CHECK-NEXT: [[CMP0:%.*]] = icmp ne <2 x i32> [[OR]], zeroinitializer -; CHECK-NEXT: ret <2 x i1> [[CMP0]] +; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> ; %v = load <2 x i32>, ptr %p, !range !{i32 1, i32 100} %or = or <2 x i32> %v, %x -- GitLab From 6503b015d4a8971dcb69a63de7d8d203e4be79b6 Mon Sep 17 00:00:00 2001 From: Zahira Ammarguellat <zahira.ammarguellat@intel.com> Date: Tue, 19 Mar 2024 07:55:49 -0700 Subject: [PATCH 090/307] [clang-cl] Fix value of __FUNCTION__ in MSVC mode. (#84014) Predefined macro FUNCTION in clang is not returning the same string than MS for templated functions. See https://godbolt.org/z/q3EKn5zq4 For the same test case MSVC is returning: function: TestClass::TestClass function: TestStruct::TestStruct function: TestEnum::TestEnum The initial work for this was in the reverted patch (https://github.com/llvm/llvm-project/pull/66120). This patch solves the issues raised in the reverted patch. --- clang/docs/ReleaseNotes.rst | 3 + clang/include/clang/AST/Expr.h | 3 +- clang/lib/AST/DeclPrinter.cpp | 22 +++++- clang/lib/AST/Expr.cpp | 26 ++++++- clang/lib/AST/TypePrinter.cpp | 24 +++++-- clang/lib/Sema/SemaExpr.cpp | 5 +- clang/test/Analysis/eval-predefined-exprs.cpp | 26 +++---- clang/test/SemaCXX/source_location.cpp | 70 +++++++++++++++++-- clang/unittests/AST/DeclPrinterTest.cpp | 53 ++++++++++++++ clang/unittests/AST/TypePrinterTest.cpp | 16 +++++ 10 files changed, 222 insertions(+), 26 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 5372a575071c..5ddad61e27c9 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -284,6 +284,9 @@ Bug Fixes in This Version for variables created through copy initialization having side-effects in C++17 and later. Fixes (#GH64356) (#GH79518). +- Fix value of predefined macro ``__FUNCTION__`` in MSVC compatibility mode. + Fixes (#GH66114). + - Clang now emits errors for explicit specializations/instatiations of lambda call operator. Fixes (#GH83267). diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 446bec4081e8..f9313f87be38 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -2045,7 +2045,8 @@ public: } static std::string ComputeName(PredefinedIdentKind IK, - const Decl *CurrentDecl); + const Decl *CurrentDecl, + bool ForceElaboratedPrinting = false); SourceLocation getBeginLoc() const { return getLocation(); } SourceLocation getEndLoc() const { return getLocation(); } diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index b701581b2474..ad45da6b8f56 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -679,6 +679,16 @@ static void printExplicitSpecifier(ExplicitSpecifier ES, llvm::raw_ostream &Out, Out << Proto; } +static void MaybePrintTagKeywordIfSupressingScopes(PrintingPolicy &Policy, + QualType T, + llvm::raw_ostream &Out) { + StringRef prefix = T->isClassType() ? "class " + : T->isStructureType() ? "struct " + : T->isUnionType() ? "union " + : ""; + Out << prefix; +} + void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { if (!D->getDescribedFunctionTemplate() && !D->isFunctionTemplateSpecialization()) @@ -855,6 +865,10 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { Out << Proto << " -> "; Proto.clear(); } + if (!Policy.SuppressTagKeyword && Policy.SuppressScope && + !Policy.SuppressUnwrittenScope) + MaybePrintTagKeywordIfSupressingScopes(Policy, AFT->getReturnType(), + Out); AFT->getReturnType().print(Out, Policy, Proto); Proto.clear(); } @@ -1022,7 +1036,13 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { ? D->getIdentifier()->deuglifiedName() : D->getName(); - printDeclType(T, Name); + if (!Policy.SuppressTagKeyword && Policy.SuppressScope && + !Policy.SuppressUnwrittenScope) { + MaybePrintTagKeywordIfSupressingScopes(Policy, T, Out); + printDeclType(T, Name); + } else { + printDeclType(T, Name); + } // Print the attributes that should be placed right before the end of the // decl. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 131dace77f9c..6221ebd5c9b4 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -676,7 +676,8 @@ StringRef PredefinedExpr::getIdentKindName(PredefinedIdentKind IK) { // FIXME: Maybe this should use DeclPrinter with a special "print predefined // expr" policy instead. std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK, - const Decl *CurrentDecl) { + const Decl *CurrentDecl, + bool ForceElaboratedPrinting) { ASTContext &Context = CurrentDecl->getASTContext(); if (IK == PredefinedIdentKind::FuncDName) { @@ -724,10 +725,21 @@ std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK, return std::string(Out.str()); } if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) { - if (IK != PredefinedIdentKind::PrettyFunction && + const auto &LO = Context.getLangOpts(); + bool IsFuncOrFunctionInNonMSVCCompatEnv = + ((IK == PredefinedIdentKind::Func || + IK == PredefinedIdentKind ::Function) && + !LO.MSVCCompat); + bool IsLFunctionInMSVCCommpatEnv = + IK == PredefinedIdentKind::LFunction && LO.MSVCCompat; + bool IsFuncOrFunctionOrLFunctionOrFuncDName = + IK != PredefinedIdentKind::PrettyFunction && IK != PredefinedIdentKind::PrettyFunctionNoVirtual && IK != PredefinedIdentKind::FuncSig && - IK != PredefinedIdentKind::LFuncSig) + IK != PredefinedIdentKind::LFuncSig; + if ((ForceElaboratedPrinting && + (IsFuncOrFunctionInNonMSVCCompatEnv || IsLFunctionInMSVCCommpatEnv)) || + (!ForceElaboratedPrinting && IsFuncOrFunctionOrLFunctionOrFuncDName)) return FD->getNameAsString(); SmallString<256> Name; @@ -755,6 +767,8 @@ std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK, PrintingPolicy Policy(Context.getLangOpts()); PrettyCallbacks PrettyCB(Context.getLangOpts()); Policy.Callbacks = &PrettyCB; + if (IK == PredefinedIdentKind::Function && ForceElaboratedPrinting) + Policy.SuppressTagKeyword = !LO.MSVCCompat; std::string Proto; llvm::raw_string_ostream POut(Proto); @@ -782,6 +796,12 @@ std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK, FD->printQualifiedName(POut, Policy); + if (IK == PredefinedIdentKind::Function) { + POut.flush(); + Out << Proto; + return std::string(Name); + } + POut << "("; if (FT) { for (unsigned i = 0, e = Decl->getNumParams(); i != e; ++i) { diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 7dcc4348f8e0..2a3e32bc6995 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1635,6 +1635,17 @@ void TypePrinter::printElaboratedBefore(const ElaboratedType *T, if (T->getKeyword() != ElaboratedTypeKeyword::None) OS << " "; NestedNameSpecifier *Qualifier = T->getQualifier(); + if (!Policy.SuppressTagKeyword && Policy.SuppressScope && + !Policy.SuppressUnwrittenScope) { + bool OldTagKeyword = Policy.SuppressTagKeyword; + bool OldSupressScope = Policy.SuppressScope; + Policy.SuppressTagKeyword = true; + Policy.SuppressScope = false; + printBefore(T->getNamedType(), OS); + Policy.SuppressTagKeyword = OldTagKeyword; + Policy.SuppressScope = OldSupressScope; + return; + } if (Qualifier) Qualifier->print(OS, Policy); } @@ -2260,10 +2271,15 @@ printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy, } else { if (!FirstArg) OS << Comma; - // Tries to print the argument with location info if exists. - printArgument(Arg, Policy, ArgOS, - TemplateParameterList::shouldIncludeTypeForArgument( - Policy, TPL, ParmIndex)); + if (!Policy.SuppressTagKeyword && + Argument.getKind() == TemplateArgument::Type && + isa<TagType>(Argument.getAsType())) + OS << Argument.getAsType().getAsString(); + else + // Tries to print the argument with location info if exists. + printArgument(Arg, Policy, ArgOS, + TemplateParameterList::shouldIncludeTypeForArgument( + Policy, TPL, ParmIndex)); } StringRef ArgString = ArgOS.str(); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8725b09f8546..db1bb70c2d69 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3740,7 +3740,10 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, else { // Pre-defined identifiers are of type char[x], where x is the length of // the string. - auto Str = PredefinedExpr::ComputeName(IK, currentDecl); + bool ForceElaboratedPrinting = + IK == PredefinedIdentKind::Function && getLangOpts().MSVCCompat; + auto Str = + PredefinedExpr::ComputeName(IK, currentDecl, ForceElaboratedPrinting); unsigned Length = Str.length(); llvm::APInt LengthI(32, Length + 1); diff --git a/clang/test/Analysis/eval-predefined-exprs.cpp b/clang/test/Analysis/eval-predefined-exprs.cpp index 1eec4476a065..b26091869cd0 100644 --- a/clang/test/Analysis/eval-predefined-exprs.cpp +++ b/clang/test/Analysis/eval-predefined-exprs.cpp @@ -52,12 +52,13 @@ void foo() { struct A { A() { - clang_analyzer_dump(__func__); - clang_analyzer_dump(__FUNCTION__); - clang_analyzer_dump(__PRETTY_FUNCTION__); - // expected-warning@-3 {{&Element{"A",0 S64b,char}}} - // expected-warning@-3 {{&Element{"A",0 S64b,char}}} - // expected-warning@-3 {{&Element{"A::A()",0 S64b,char}}} + clang_analyzer_dump(__func__); // expected-warning {{&Element{"A",0 S64b,char}}} +#ifdef ANALYZER_MS + clang_analyzer_dump(__FUNCTION__); // expected-warning {{&Element{"A::A",0 S64b,char}}} +#else + clang_analyzer_dump(__FUNCTION__); // expected-warning {{&Element{"A",0 S64b,char}}} +#endif + clang_analyzer_dump(__PRETTY_FUNCTION__); // expected-warning {{&Element{"A::A()",0 S64b,char}}} #ifdef ANALYZER_MS clang_analyzer_dump(__FUNCDNAME__); @@ -71,12 +72,13 @@ struct A { #endif } ~A() { - clang_analyzer_dump(__func__); - clang_analyzer_dump(__FUNCTION__); - clang_analyzer_dump(__PRETTY_FUNCTION__); - // expected-warning@-3 {{&Element{"~A",0 S64b,char}}} - // expected-warning@-3 {{&Element{"~A",0 S64b,char}}} - // expected-warning@-3 {{&Element{"A::~A()",0 S64b,char}}} + clang_analyzer_dump(__func__); // expected-warning {{&Element{"~A",0 S64b,char}}} +#ifdef ANALYZER_MS + clang_analyzer_dump(__FUNCTION__); // expected-warning {{&Element{"A::~A",0 S64b,char}}} +#else + clang_analyzer_dump(__FUNCTION__); // expected-warning {{&Element{"~A",0 S64b,char}}} +#endif + clang_analyzer_dump(__PRETTY_FUNCTION__); // expected-warning {{&Element{"A::~A()",0 S64b,char}}} #ifdef ANALYZER_MS clang_analyzer_dump(__FUNCDNAME__); diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp index b151fc45fdad..63157cfacdd9 100644 --- a/clang/test/SemaCXX/source_location.cpp +++ b/clang/test/SemaCXX/source_location.cpp @@ -1,14 +1,14 @@ // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify %s // RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -DUSE_CONSTEVAL -fexceptions -verify %s // RUN: %clang_cc1 -std=c++2b -fcxx-exceptions -DUSE_CONSTEVAL -DPAREN_INIT -fexceptions -verify %s -// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -verify %s -// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -verify %s +// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -fms-compatibility -verify %s +// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -fms-compatibility -verify %s // // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s // RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -DUSE_CONSTEVAL -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s // RUN: %clang_cc1 -std=c++2b -fcxx-exceptions -DUSE_CONSTEVAL -DPAREN_INIT -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s -// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s -// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s +// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -fms-compatibility -verify %s +// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify -fms-compatibility %s // expected-no-diagnostics #define assert(...) ((__VA_ARGS__) ? ((void)0) : throw 42) @@ -463,8 +463,70 @@ void ctor_tests() { constexpr SL global_sl = SL::current(); static_assert(is_equal(global_sl.function(), "")); +template <class T> +class TestBI { +public: + TestBI() { +#ifdef MS + static_assert(is_equal(__FUNCTION__, "test_func::TestBI<int>::TestBI")); +#else + static_assert(is_equal(__FUNCTION__, "TestBI")); +#endif + static_assert(is_equal(__func__, "TestBI")); + } +}; + +template <class T> +class TestClass { +public: + TestClass() { +#ifdef MS + static_assert(is_equal(__FUNCTION__, "test_func::TestClass<class test_func::C>::TestClass")); +#else + static_assert(is_equal(__FUNCTION__, "TestClass")); +#endif + static_assert(is_equal(__func__, "TestClass")); + } +}; + +template <class T> +class TestStruct { +public: + TestStruct() { +#ifdef MS + static_assert(is_equal(__FUNCTION__, "test_func::TestStruct<struct test_func::S>::TestStruct")); +#else + static_assert(is_equal(__FUNCTION__, "TestStruct")); +#endif + static_assert(is_equal(__func__, "TestStruct")); + } +}; + +template <class T> +class TestEnum { +public: + TestEnum() { +#ifdef MS + static_assert(is_equal(__FUNCTION__, "test_func::TestEnum<enum test_func::E>::TestEnum")); +#else + static_assert(is_equal(__FUNCTION__, "TestEnum")); +#endif + static_assert(is_equal(__func__, "TestEnum")); + } +}; + +class C {}; +struct S {}; +enum E {}; + +TestBI<int> t1; +TestClass<test_func::C> t2; +TestStruct<test_func::S> t3; +TestEnum<test_func::E> t4; + } // namespace test_func + //===----------------------------------------------------------------------===// // __builtin_FUNCSIG() //===----------------------------------------------------------------------===// diff --git a/clang/unittests/AST/DeclPrinterTest.cpp b/clang/unittests/AST/DeclPrinterTest.cpp index 0e09ab2a7bba..e024c41e03b4 100644 --- a/clang/unittests/AST/DeclPrinterTest.cpp +++ b/clang/unittests/AST/DeclPrinterTest.cpp @@ -358,6 +358,59 @@ TEST(DeclPrinter, TestCXXRecordDecl11) { "class A : virtual public Z, private Y {}")); } +TEST(DeclPrinter, TestCXXRecordDecl12) { + ASSERT_TRUE( + PrintedDeclCXX98Matches("struct S { int x; };" + "namespace NS { class C {};}" + "void foo() {using namespace NS; C c;}", + "foo", + "void foo() {\nusing namespace NS;\nclass " + "NS::C c;\n}\n", + [](PrintingPolicy &Policy) { + Policy.SuppressTagKeyword = false; + Policy.SuppressScope = true; + Policy.TerseOutput = false; + })); +} + +TEST(DeclPrinter, TestCXXRecordDecl13) { + ASSERT_TRUE(PrintedDeclCXX98Matches( + "struct S { int x; };" + "S s1;" + "S foo() {return s1;}", + "foo", "struct S foo() {\nreturn s1;\n}\n", [](PrintingPolicy &Policy) { + Policy.SuppressTagKeyword = false; + Policy.SuppressScope = true; + Policy.TerseOutput = false; + })); +} + +TEST(DeclPrinter, TestCXXRecordDecl14) { + ASSERT_TRUE(PrintedDeclCXX98Matches( + "struct S { int x; };" + "S foo(S s1) {return s1;}", + "foo", "struct S foo(struct S s1) {\nreturn s1;\n}\n", + [](PrintingPolicy &Policy) { + Policy.SuppressTagKeyword = false; + Policy.SuppressScope = true; + Policy.TerseOutput = false; + })); +} +TEST(DeclPrinter, TestCXXRecordDecl15) { + ASSERT_TRUE(PrintedDeclCXX98Matches( + "struct S { int x; };" + "namespace NS { class C {};}" + "S foo(S s1, NS::C c1) {using namespace NS; C c; return s1;}", + "foo", + "struct S foo(struct S s1, class NS::C c1) {\nusing namespace NS;\nclass " + "NS::C c;\nreturn s1;\n}\n", + [](PrintingPolicy &Policy) { + Policy.SuppressTagKeyword = false; + Policy.SuppressScope = true; + Policy.TerseOutput = false; + })); +} + TEST(DeclPrinter, TestFunctionDecl1) { ASSERT_TRUE(PrintedDeclCXX98Matches( "void A();", diff --git a/clang/unittests/AST/TypePrinterTest.cpp b/clang/unittests/AST/TypePrinterTest.cpp index f0a6eb7e9fd8..494085a2ebca 100644 --- a/clang/unittests/AST/TypePrinterTest.cpp +++ b/clang/unittests/AST/TypePrinterTest.cpp @@ -155,6 +155,22 @@ TEST(TypePrinter, TemplateIdWithNTTP) { })); } +TEST(TypePrinter, TemplateArgumentsSubstitution) { + constexpr char Code[] = R"cpp( + template <typename Y> class X {}; + typedef X<int> A; + int foo() { + return sizeof(A); + } + )cpp"; + auto Matcher = typedefNameDecl(hasName("A"), hasType(qualType().bind("id"))); + ASSERT_TRUE(PrintedTypeMatches(Code, {}, Matcher, "X<int>", + [](PrintingPolicy &Policy) { + Policy.SuppressTagKeyword = false; + Policy.SuppressScope = true; + })); +} + TEST(TypePrinter, TemplateArgumentsSubstitution_Expressions) { /// Tests clang::isSubstitutedDefaultArgument on TemplateArguments /// that are of kind TemplateArgument::Expression -- GitLab From d1e2305a6d70bbf565104644a4594cbf4f78e6ac Mon Sep 17 00:00:00 2001 From: Nikita Popov <npopov@redhat.com> Date: Tue, 19 Mar 2024 16:01:59 +0100 Subject: [PATCH 091/307] [ValueTracking] Fix release build Move the declaration of the Ty variable outside the NDEBUG guard and make use of it in the remainder of the function. --- llvm/lib/Analysis/ValueTracking.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index bf6afad3636b..70c87cb86e99 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2863,9 +2863,9 @@ static bool isKnownNonZeroFromOperator(const Operator *I, /// Supports values with integer or pointer type and vectors of integers. bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, const SimplifyQuery &Q) { + Type *Ty = V->getType(); #ifndef NDEBUG - Type *Ty = V->getType(); assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth"); if (auto *FVTy = dyn_cast<FixedVectorType>(Ty)) { @@ -2887,7 +2887,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, // For constant vectors, check that all elements are undefined or known // non-zero to determine that the whole vector is known non-zero. - if (auto *VecTy = dyn_cast<FixedVectorType>(C->getType())) { + if (auto *VecTy = dyn_cast<FixedVectorType>(Ty)) { for (unsigned i = 0, e = VecTy->getNumElements(); i != e; ++i) { if (!DemandedElts[i]) continue; @@ -2918,7 +2918,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, if (MDNode *Ranges = Q.IIQ.getMetadata(I, LLVMContext::MD_range)) { // If the possible ranges don't contain zero, then the value is // definitely non-zero. - assert(V->getType()->isIntOrIntVectorTy() && "Range on non-integer?"); + assert(Ty->isIntOrIntVectorTy() && "Range on non-integer?"); const APInt ZeroValue(Ty->getScalarSizeInBits(), 0); if (rangeMetadataExcludesValue(Ranges, ZeroValue)) return true; @@ -2934,7 +2934,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, // Check for pointer simplifications. - if (PointerType *PtrTy = dyn_cast<PointerType>(V->getType())) { + if (PointerType *PtrTy = dyn_cast<PointerType>(Ty)) { // A byval, inalloca may not be null in a non-default addres space. A // nonnull argument is assumed never 0. if (const Argument *A = dyn_cast<Argument>(V)) { -- GitLab From a1fb51453d9b47ea011f8b948f2f099da2edf2c9 Mon Sep 17 00:00:00 2001 From: lntue <35648136+lntue@users.noreply.github.com> Date: Tue, 19 Mar 2024 11:15:06 -0400 Subject: [PATCH 092/307] [libc] Prevent constant propagation for atanf(+-Inf) in gcc. (#85733) gcc bot failures with `atanf(+-Inf)`: https://lab.llvm.org/buildbot/#/builders/250/builds/20331/steps/8/logs/stdio --- libc/src/math/generic/atanf.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libc/src/math/generic/atanf.cpp b/libc/src/math/generic/atanf.cpp index 69fd45ddd767..5f66ea52d0d7 100644 --- a/libc/src/math/generic/atanf.cpp +++ b/libc/src/math/generic/atanf.cpp @@ -37,8 +37,10 @@ LLVM_LIBC_FUNCTION(float, atanf, (float x)) { double const_term = 0.0; if (LIBC_UNLIKELY(x_abs >= 0x4180'0000)) { // atan(+-Inf) = +-pi/2. - if (x_bits.is_inf()) - return static_cast<float>(SIGNED_PI_OVER_2[sign.is_neg()]); + if (x_bits.is_inf()) { + volatile double sign_pi_over_2 = SIGNED_PI_OVER_2[sign.is_neg()]; + return static_cast<float>(sign_pi_over_2); + } if (x_bits.is_nan()) return x; // x >= 16 -- GitLab From 2cc75aed0925f3c7e8e50b2f4bdc94daac4cb08d Mon Sep 17 00:00:00 2001 From: Nikita Popov <npopov@redhat.com> Date: Tue, 19 Mar 2024 16:14:21 +0100 Subject: [PATCH 093/307] [ValueTracking] Move MD_range handling to isKnownNonZeroFromOperator() All the isKnownNonZero() handling for instructions should be inside this function. This makes the structure more similar to computeKnownBitsFromOperator() as well. This may not be entirely NFC due to different depth handling. --- llvm/lib/Analysis/ValueTracking.cpp | 30 +++++++++++++---------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 70c87cb86e99..8be17b506af5 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2759,27 +2759,33 @@ static bool isKnownNonZeroFromOperator(const Operator *I, auto *LI = cast<LoadInst>(I); // A Load tagged with nonnull or dereferenceable with null pointer undefined // is never null. - if (auto *PtrT = dyn_cast<PointerType>(I->getType())) + if (auto *PtrT = dyn_cast<PointerType>(I->getType())) { if (Q.IIQ.getMetadata(LI, LLVMContext::MD_nonnull) || (Q.IIQ.getMetadata(LI, LLVMContext::MD_dereferenceable) && !NullPointerIsDefined(LI->getFunction(), PtrT->getAddressSpace()))) return true; + } else if (MDNode *Ranges = Q.IIQ.getMetadata(LI, LLVMContext::MD_range)) { + return rangeMetadataExcludesValue(Ranges, APInt::getZero(BitWidth)); + } // No need to fall through to computeKnownBits as range metadata is already // handled in isKnownNonZero. return false; } case Instruction::Call: - case Instruction::Invoke: + case Instruction::Invoke: { + const auto *Call = cast<CallBase>(I); if (I->getType()->isPointerTy()) { - const auto *Call = cast<CallBase>(I); if (Call->isReturnNonNull()) return true; if (const auto *RP = getArgumentAliasingToReturnedPointer(Call, true)) return isKnownNonZero(RP, Depth, Q); - } else if (const Value *RV = cast<CallBase>(I)->getReturnedArgOperand()) { - if (RV->getType() == I->getType() && isKnownNonZero(RV, Depth, Q)) - return true; + } else { + if (MDNode *Ranges = Q.IIQ.getMetadata(Call, LLVMContext::MD_range)) + return rangeMetadataExcludesValue(Ranges, APInt::getZero(BitWidth)); + if (const Value *RV = Call->getReturnedArgOperand()) + if (RV->getType() == I->getType() && isKnownNonZero(RV, Depth, Q)) + return true; } if (auto *II = dyn_cast<IntrinsicInst>(I)) { @@ -2849,6 +2855,7 @@ static bool isKnownNonZeroFromOperator(const Operator *I, return false; } + } KnownBits Known(BitWidth); computeKnownBits(I, DemandedElts, Known, Depth, Q); @@ -2914,17 +2921,6 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, return false; } - if (auto *I = dyn_cast<Instruction>(V)) { - if (MDNode *Ranges = Q.IIQ.getMetadata(I, LLVMContext::MD_range)) { - // If the possible ranges don't contain zero, then the value is - // definitely non-zero. - assert(Ty->isIntOrIntVectorTy() && "Range on non-integer?"); - const APInt ZeroValue(Ty->getScalarSizeInBits(), 0); - if (rangeMetadataExcludesValue(Ranges, ZeroValue)) - return true; - } - } - if (!isa<Constant>(V) && isKnownNonZeroFromAssume(V, Q)) return true; -- GitLab From 31eaf86a1e8f1870e6ee4c42088a5213bde294b8 Mon Sep 17 00:00:00 2001 From: Alexey Bataev <5361294+alexey-bataev@users.noreply.github.com> Date: Fri, 8 Mar 2024 13:57:02 -0500 Subject: [PATCH 094/307] [SLP]Improve minbitwidth analysis. This improves overall analysis for minbitwidth in SLP. It allows to analyze the trees with store/insertelement root nodes. Also, instead of using single minbitwidth, detected from the very first analysis stage, it tries to detect the best one for each trunc/ext subtree in the graph and use it for the subtree. Results in better code and less vector register pressure. Metric: size..text Program size..text results results0 diff test-suite :: SingleSource/Benchmarks/Adobe-C++/simple_types_loop_invariant.test 92549.00 92609.00 0.1% test-suite :: External/SPEC/CINT2017speed/625.x264_s/625.x264_s.test 663381.00 663493.00 0.0% test-suite :: External/SPEC/CINT2017rate/525.x264_r/525.x264_r.test 663381.00 663493.00 0.0% test-suite :: MultiSource/Benchmarks/Bullet/bullet.test 307182.00 307214.00 0.0% test-suite :: External/SPEC/CFP2017speed/638.imagick_s/638.imagick_s.test 1394420.00 1394484.00 0.0% test-suite :: External/SPEC/CFP2017rate/538.imagick_r/538.imagick_r.test 1394420.00 1394484.00 0.0% test-suite :: External/SPEC/CFP2017rate/510.parest_r/510.parest_r.test 2040257.00 2040273.00 0.0% test-suite :: External/SPEC/CFP2017rate/526.blender_r/526.blender_r.test 12396098.00 12395858.00 -0.0% test-suite :: External/SPEC/CINT2006/445.gobmk/445.gobmk.test 909944.00 909768.00 -0.0% SingleSource/Benchmarks/Adobe-C++/simple_types_loop_invariant - 4 scalar instructions remain scalar (good). Spec2017/x264 - the whole function idct4x4dc is vectorized using <16 x i16> instead of <16 x i32>, also zext/trunc are removed. In other places last vector zext/sext removed and replaced by extractelement + scalar zext/sext pair. MultiSource/Benchmarks/Bullet/bullet - reduce or <4 x i32> replaced by reduce or <4 x i8> Spec2017/imagick - Removed extra zext from 2 packs of the operations. Spec2017/parest - Removed extra zext, replaced by extractelement+scalar zext Spec2017/blender - the whole bunch of vector zext/sext replaced by extractelement+scalar zext/sext, some extra code vectorized in smaller types. Spec2006/gobmk - fixed cost estimation, some small code remains scalar. Original Pull Request: https://github.com/llvm/llvm-project/pull/84334 The patch has the same functionality (no test changes, no changes in benchmarks) as the original patch, just has some compile time improvements + fixes for xxhash unittest, discovered earlier in the previous version of the patch. Reviewers: Pull Request: https://github.com/llvm/llvm-project/pull/84536 --- .../Transforms/Vectorize/SLPVectorizer.cpp | 820 ++++++++++++------ .../SLPVectorizer/AArch64/ext-trunc.ll | 9 +- ...ather-buildvector-with-minbitwidth-user.ll | 7 +- .../AArch64/gather-with-minbith-user.ll | 11 +- .../SLPVectorizer/AArch64/getelementptr2.ll | 4 +- .../SLPVectorizer/AArch64/reduce-add-i64.ll | 20 +- .../SLPVectorizer/RISCV/reductions.ll | 7 +- .../Transforms/SLPVectorizer/X86/PR35777.ll | 9 +- .../X86/int-bitcast-minbitwidth.ll | 2 +- .../X86/minbitwidth-icmp-to-trunc.ll | 17 +- ...minbitwidth-multiuse-with-insertelement.ll | 17 +- .../X86/minbitwidth-transformed-operand.ll | 21 +- .../X86/minbitwidth-user-not-min.ll | 2 +- .../SLPVectorizer/X86/minimum-sizes.ll | 43 +- .../SLPVectorizer/X86/phi-undef-input.ll | 24 +- .../Transforms/SLPVectorizer/X86/resched.ll | 32 +- .../X86/reused-reductions-with-minbitwidth.ll | 10 +- .../X86/same-scalar-in-same-phi-extract.ll | 7 +- .../X86/store-insertelement-minbitwidth.ll | 22 +- .../SLPVectorizer/alt-cmp-vectorize.ll | 4 +- 20 files changed, 713 insertions(+), 375 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index f2ac060a2e3a..13943c13a232 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -1085,6 +1085,9 @@ public: BS->clear(); } MinBWs.clear(); + ReductionBitWidth = 0; + CastMaxMinBWSizes.reset(); + TruncNodes.clear(); InstrElementSize.clear(); UserIgnoreList = nullptr; PostponedGathers.clear(); @@ -2287,6 +2290,7 @@ public: void clearReductionData() { AnalyzedReductionsRoots.clear(); AnalyzedReductionVals.clear(); + AnalyzedMinBWVals.clear(); } /// Checks if the given value is gathered in one of the nodes. bool isAnyGathered(const SmallDenseSet<Value *> &Vals) const { @@ -2307,9 +2311,11 @@ private: /// constant and to be demoted. Required to correctly identify constant nodes /// to be demoted. bool collectValuesToDemote( - Value *V, SmallVectorImpl<Value *> &ToDemote, + Value *V, bool IsProfitableToDemoteRoot, unsigned &BitWidth, + SmallVectorImpl<Value *> &ToDemote, DenseMap<Instruction *, SmallVector<unsigned>> &DemotedConsts, - SmallVectorImpl<Value *> &Roots, DenseSet<Value *> &Visited) const; + DenseSet<Value *> &Visited, unsigned &MaxDepthLevel, + bool &IsProfitableToDemote, bool IsTruncRoot) const; /// Check if the operands on the edges \p Edges of the \p UserTE allows /// reordering (i.e. the operands can be reordered because they have only one @@ -2375,6 +2381,10 @@ private: /// \ returns the graph entry for the \p Idx operand of the \p E entry. const TreeEntry *getOperandEntry(const TreeEntry *E, unsigned Idx) const; + /// \returns Cast context for the given graph node. + TargetTransformInfo::CastContextHint + getCastContextHint(const TreeEntry &TE) const; + /// \returns the cost of the vectorizable entry. InstructionCost getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, @@ -2925,11 +2935,18 @@ private: } assert(!BundleMember && "Bundle and VL out of sync"); } else { - MustGather.insert(VL.begin(), VL.end()); // Build a map for gathered scalars to the nodes where they are used. + bool AllConstsOrCasts = true; for (Value *V : VL) - if (!isConstant(V)) + if (!isConstant(V)) { + auto *I = dyn_cast<CastInst>(V); + AllConstsOrCasts &= I && I->getType()->isIntegerTy(); ValueToGatherNodes.try_emplace(V).first->getSecond().insert(Last); + } + if (AllConstsOrCasts) + CastMaxMinBWSizes = + std::make_pair(std::numeric_limits<unsigned>::max(), 1); + MustGather.insert(VL.begin(), VL.end()); } if (UserTreeIdx.UserTE) @@ -3054,6 +3071,10 @@ private: /// Set of hashes for the list of reduction values already being analyzed. DenseSet<size_t> AnalyzedReductionVals; + /// Values, already been analyzed for mininmal bitwidth and found to be + /// non-profitable. + DenseSet<Value *> AnalyzedMinBWVals; + /// A list of values that need to extracted out of the tree. /// This list holds pairs of (Internal Scalar : External User). External User /// can be nullptr, it means that this Internal Scalar will be used later, @@ -3629,6 +3650,18 @@ private: /// value must be signed-extended, rather than zero-extended, back to its /// original width. DenseMap<const TreeEntry *, std::pair<uint64_t, bool>> MinBWs; + + /// Final size of the reduced vector, if the current graph represents the + /// input for the reduction and it was possible to narrow the size of the + /// reduction. + unsigned ReductionBitWidth = 0; + + /// If the tree contains any zext/sext/trunc nodes, contains max-min pair of + /// type sizes, used in the tree. + std::optional<std::pair<unsigned, unsigned>> CastMaxMinBWSizes; + + /// Indices of the vectorized trunc nodes. + DenseSet<unsigned> TruncNodes; }; } // end namespace slpvectorizer @@ -6543,6 +6576,26 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth, case Instruction::Trunc: case Instruction::FPTrunc: case Instruction::BitCast: { + auto [PrevMaxBW, PrevMinBW] = CastMaxMinBWSizes.value_or( + std::make_pair(std::numeric_limits<unsigned>::min(), + std::numeric_limits<unsigned>::max())); + if (ShuffleOrOp == Instruction::ZExt || + ShuffleOrOp == Instruction::SExt) { + CastMaxMinBWSizes = std::make_pair( + std::max<unsigned>(DL->getTypeSizeInBits(VL0->getType()), + PrevMaxBW), + std::min<unsigned>( + DL->getTypeSizeInBits(VL0->getOperand(0)->getType()), + PrevMinBW)); + } else if (ShuffleOrOp == Instruction::Trunc) { + CastMaxMinBWSizes = std::make_pair( + std::max<unsigned>( + DL->getTypeSizeInBits(VL0->getOperand(0)->getType()), + PrevMaxBW), + std::min<unsigned>(DL->getTypeSizeInBits(VL0->getType()), + PrevMinBW)); + TruncNodes.insert(VectorizableTree.size()); + } TreeEntry *TE = newTreeEntry(VL, Bundle /*vectorized*/, S, UserTreeIdx, ReuseShuffleIndicies); LLVM_DEBUG(dbgs() << "SLP: added a vector of casts.\n"); @@ -8376,6 +8429,22 @@ const BoUpSLP::TreeEntry *BoUpSLP::getOperandEntry(const TreeEntry *E, return It->get(); } +TTI::CastContextHint BoUpSLP::getCastContextHint(const TreeEntry &TE) const { + if (TE.State == TreeEntry::ScatterVectorize || + TE.State == TreeEntry::StridedVectorize) + return TTI::CastContextHint::GatherScatter; + if (TE.State == TreeEntry::Vectorize && TE.getOpcode() == Instruction::Load && + !TE.isAltShuffle()) { + if (TE.ReorderIndices.empty()) + return TTI::CastContextHint::Normal; + SmallVector<int> Mask; + inversePermutation(TE.ReorderIndices, Mask); + if (ShuffleVectorInst::isReverseMask(Mask, Mask.size())) + return TTI::CastContextHint::Reversed; + } + return TTI::CastContextHint::None; +} + InstructionCost BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, SmallPtrSetImpl<Value *> &CheckedExtracts) { @@ -8398,6 +8467,7 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, // If we have computed a smaller type for the expression, update VecTy so // that the costs will be accurate. auto It = MinBWs.find(E); + Type *OrigScalarTy = ScalarTy; if (It != MinBWs.end()) { ScalarTy = IntegerType::get(F->getContext(), It->second.first); VecTy = FixedVectorType::get(ScalarTy, VL.size()); @@ -8455,24 +8525,11 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, UsedScalars.set(I); } auto GetCastContextHint = [&](Value *V) { - if (const TreeEntry *OpTE = getTreeEntry(V)) { - if (OpTE->State == TreeEntry::ScatterVectorize || - OpTE->State == TreeEntry::StridedVectorize) - return TTI::CastContextHint::GatherScatter; - if (OpTE->State == TreeEntry::Vectorize && - OpTE->getOpcode() == Instruction::Load && !OpTE->isAltShuffle()) { - if (OpTE->ReorderIndices.empty()) - return TTI::CastContextHint::Normal; - SmallVector<int> Mask; - inversePermutation(OpTE->ReorderIndices, Mask); - if (ShuffleVectorInst::isReverseMask(Mask, Mask.size())) - return TTI::CastContextHint::Reversed; - } - } else { - InstructionsState SrcState = getSameOpcode(E->getOperand(0), *TLI); - if (SrcState.getOpcode() == Instruction::Load && !SrcState.isAltShuffle()) - return TTI::CastContextHint::GatherScatter; - } + if (const TreeEntry *OpTE = getTreeEntry(V)) + return getCastContextHint(*OpTE); + InstructionsState SrcState = getSameOpcode(E->getOperand(0), *TLI); + if (SrcState.getOpcode() == Instruction::Load && !SrcState.isAltShuffle()) + return TTI::CastContextHint::GatherScatter; return TTI::CastContextHint::None; }; auto GetCostDiff = @@ -8521,8 +8578,6 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, TTI::CastContextHint CCH = GetCastContextHint(VL0); VecCost += TTI->getCastInstrCost(VecOpcode, UserVecTy, VecTy, CCH, CostKind); - ScalarCost += Sz * TTI->getCastInstrCost(VecOpcode, UserScalarTy, - ScalarTy, CCH, CostKind); } } } @@ -8539,7 +8594,7 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, InstructionCost ScalarCost = 0; InstructionCost VecCost = 0; std::tie(ScalarCost, VecCost) = getGEPCosts( - *TTI, Ptrs, BasePtr, E->getOpcode(), CostKind, ScalarTy, VecTy); + *TTI, Ptrs, BasePtr, E->getOpcode(), CostKind, OrigScalarTy, VecTy); LLVM_DEBUG(dumpTreeCosts(E, 0, VecCost, ScalarCost, "Calculated GEPs cost for Tree")); @@ -8586,7 +8641,7 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, NumElts = ATy->getNumElements(); else NumElts = AggregateTy->getStructNumElements(); - SrcVecTy = FixedVectorType::get(ScalarTy, NumElts); + SrcVecTy = FixedVectorType::get(OrigScalarTy, NumElts); } if (I->hasOneUse()) { Instruction *Ext = I->user_back(); @@ -8754,13 +8809,7 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, } } auto GetScalarCost = [&](unsigned Idx) -> InstructionCost { - // Do not count cost here if minimum bitwidth is in effect and it is just - // a bitcast (here it is just a noop). - if (VecOpcode != Opcode && VecOpcode == Instruction::BitCast) - return TTI::TCC_Free; - auto *VI = VL0->getOpcode() == Opcode - ? cast<Instruction>(UniqueValues[Idx]) - : nullptr; + auto *VI = cast<Instruction>(UniqueValues[Idx]); return TTI->getCastInstrCost(Opcode, VL0->getType(), VL0->getOperand(0)->getType(), TTI::getCastContextHint(VI), CostKind, VI); @@ -8803,7 +8852,7 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, ? CmpInst::BAD_FCMP_PREDICATE : CmpInst::BAD_ICMP_PREDICATE; - return TTI->getCmpSelInstrCost(E->getOpcode(), ScalarTy, + return TTI->getCmpSelInstrCost(E->getOpcode(), OrigScalarTy, Builder.getInt1Ty(), CurrentPred, CostKind, VI); }; @@ -8858,7 +8907,7 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, TTI::OperandValueInfo Op2Info = TTI::getOperandInfo(VI->getOperand(OpIdx)); SmallVector<const Value *> Operands(VI->operand_values()); - return TTI->getArithmeticInstrCost(ShuffleOrOp, ScalarTy, CostKind, + return TTI->getArithmeticInstrCost(ShuffleOrOp, OrigScalarTy, CostKind, Op1Info, Op2Info, Operands, VI); }; auto GetVectorCost = [=](InstructionCost CommonCost) { @@ -8877,9 +8926,9 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, case Instruction::Load: { auto GetScalarCost = [&](unsigned Idx) { auto *VI = cast<LoadInst>(UniqueValues[Idx]); - return TTI->getMemoryOpCost(Instruction::Load, ScalarTy, VI->getAlign(), - VI->getPointerAddressSpace(), CostKind, - TTI::OperandValueInfo(), VI); + return TTI->getMemoryOpCost(Instruction::Load, OrigScalarTy, + VI->getAlign(), VI->getPointerAddressSpace(), + CostKind, TTI::OperandValueInfo(), VI); }; auto *LI0 = cast<LoadInst>(VL0); auto GetVectorCost = [&](InstructionCost CommonCost) { @@ -8922,9 +8971,9 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals, auto GetScalarCost = [=](unsigned Idx) { auto *VI = cast<StoreInst>(VL[Idx]); TTI::OperandValueInfo OpInfo = TTI::getOperandInfo(VI->getValueOperand()); - return TTI->getMemoryOpCost(Instruction::Store, ScalarTy, VI->getAlign(), - VI->getPointerAddressSpace(), CostKind, - OpInfo, VI); + return TTI->getMemoryOpCost(Instruction::Store, OrigScalarTy, + VI->getAlign(), VI->getPointerAddressSpace(), + CostKind, OpInfo, VI); }; auto *BaseSI = cast<StoreInst>(IsReorder ? VL[E->ReorderIndices.front()] : VL0); @@ -9786,6 +9835,44 @@ InstructionCost BoUpSLP::getTreeCost(ArrayRef<Value *> VectorizedVals) { Cost -= InsertCost; } + // Add the cost for reduced value resize (if required). + if (ReductionBitWidth != 0) { + assert(UserIgnoreList && "Expected reduction tree."); + const TreeEntry &E = *VectorizableTree.front().get(); + auto It = MinBWs.find(&E); + if (It != MinBWs.end() && It->second.first != ReductionBitWidth) { + unsigned SrcSize = It->second.first; + unsigned DstSize = ReductionBitWidth; + unsigned Opcode = Instruction::Trunc; + if (SrcSize < DstSize) + Opcode = It->second.second ? Instruction::SExt : Instruction::ZExt; + auto *SrcVecTy = + FixedVectorType::get(Builder.getIntNTy(SrcSize), E.getVectorFactor()); + auto *DstVecTy = + FixedVectorType::get(Builder.getIntNTy(DstSize), E.getVectorFactor()); + TTI::CastContextHint CCH = getCastContextHint(E); + InstructionCost CastCost; + switch (E.getOpcode()) { + case Instruction::SExt: + case Instruction::ZExt: + case Instruction::Trunc: { + const TreeEntry *OpTE = getOperandEntry(&E, 0); + CCH = getCastContextHint(*OpTE); + break; + } + default: + break; + } + CastCost += TTI->getCastInstrCost(Opcode, DstVecTy, SrcVecTy, CCH, + TTI::TCK_RecipThroughput); + Cost += CastCost; + LLVM_DEBUG(dbgs() << "SLP: Adding cost " << CastCost + << " for final resize for reduction from " << SrcVecTy + << " to " << DstVecTy << "\n"; + dbgs() << "SLP: Current total cost = " << Cost << "\n"); + } + } + #ifndef NDEBUG SmallString<256> Str; { @@ -10067,11 +10154,6 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry( Instruction &LastBundleInst = getLastInstructionInBundle(VTE); if (&LastBundleInst == TEInsertPt || !CheckOrdering(&LastBundleInst)) continue; - auto It = MinBWs.find(VTE); - // If vectorize node is demoted - do not match. - if (It != MinBWs.end() && - It->second.first != DL->getTypeSizeInBits(V->getType())) - continue; VToTEs.insert(VTE); } if (VToTEs.empty()) @@ -10635,8 +10717,20 @@ Value *BoUpSLP::gather(ArrayRef<Value *> VL, Value *Root) { PostponedInsts.emplace_back(Inst, I); } - auto &&CreateInsertElement = [this](Value *Vec, Value *V, unsigned Pos) { - Vec = Builder.CreateInsertElement(Vec, V, Builder.getInt32(Pos)); + auto &&CreateInsertElement = [this](Value *Vec, Value *V, unsigned Pos, + Type *Ty) { + Value *Scalar = V; + if (cast<VectorType>(Vec->getType())->getElementType() != Ty) { + assert(V->getType()->isIntegerTy() && Ty->isIntegerTy() && + "Expected integer types only."); + Vec = Builder.CreateIntCast( + Vec, + VectorType::get(Ty, + cast<VectorType>(Vec->getType())->getElementCount()), + !isKnownNonNegative(Vec, SimplifyQuery(*DL))); + } + + Vec = Builder.CreateInsertElement(Vec, Scalar, Builder.getInt32(Pos)); auto *InsElt = dyn_cast<InsertElementInst>(Vec); if (!InsElt) return Vec; @@ -10646,15 +10740,25 @@ Value *BoUpSLP::gather(ArrayRef<Value *> VL, Value *Root) { if (isa<Instruction>(V)) { if (TreeEntry *Entry = getTreeEntry(V)) { // Find which lane we need to extract. - unsigned FoundLane = Entry->findLaneForValue(V); - ExternalUses.emplace_back(V, InsElt, FoundLane); + User *UserOp = nullptr; + if (Scalar != V) { + if (auto *SI = dyn_cast<Instruction>(Scalar)) + UserOp = SI; + } else { + UserOp = InsElt; + } + if (UserOp) { + unsigned FoundLane = Entry->findLaneForValue(V); + ExternalUses.emplace_back(V, UserOp, FoundLane); + } } } return Vec; }; Value *Val0 = isa<StoreInst>(VL[0]) ? cast<StoreInst>(VL[0])->getValueOperand() : VL[0]; - FixedVectorType *VecTy = FixedVectorType::get(Val0->getType(), VL.size()); + Type *ScalarTy = Val0->getType(); + FixedVectorType *VecTy = FixedVectorType::get(ScalarTy, VL.size()); Value *Vec = Root ? Root : PoisonValue::get(VecTy); SmallVector<int> NonConsts; // Insert constant values at first. @@ -10677,15 +10781,15 @@ Value *BoUpSLP::gather(ArrayRef<Value *> VL, Value *Root) { continue; } } - Vec = CreateInsertElement(Vec, VL[I], I); + Vec = CreateInsertElement(Vec, VL[I], I, ScalarTy); } // Insert non-constant values. for (int I : NonConsts) - Vec = CreateInsertElement(Vec, VL[I], I); + Vec = CreateInsertElement(Vec, VL[I], I, ScalarTy); // Append instructions, which are/may be part of the loop, in the end to make // it possible to hoist non-loop-based instructions. for (const std::pair<Value *, unsigned> &Pair : PostponedInsts) - Vec = CreateInsertElement(Vec, Pair.first, Pair.second); + Vec = CreateInsertElement(Vec, Pair.first, Pair.second, ScalarTy); return Vec; } @@ -10742,16 +10846,35 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis { SetVector<Instruction *> &GatherShuffleExtractSeq; /// A list of blocks that we are going to CSE. DenseSet<BasicBlock *> &CSEBlocks; + /// Data layout. + const DataLayout &DL; public: ShuffleIRBuilder(IRBuilderBase &Builder, SetVector<Instruction *> &GatherShuffleExtractSeq, - DenseSet<BasicBlock *> &CSEBlocks) + DenseSet<BasicBlock *> &CSEBlocks, const DataLayout &DL) : Builder(Builder), GatherShuffleExtractSeq(GatherShuffleExtractSeq), - CSEBlocks(CSEBlocks) {} + CSEBlocks(CSEBlocks), DL(DL) {} ~ShuffleIRBuilder() = default; /// Creates shufflevector for the 2 operands with the given mask. Value *createShuffleVector(Value *V1, Value *V2, ArrayRef<int> Mask) { + if (V1->getType() != V2->getType()) { + assert(V1->getType()->isIntOrIntVectorTy() && + V1->getType()->isIntOrIntVectorTy() && + "Expected integer vector types only."); + if (V1->getType() != V2->getType()) { + if (cast<VectorType>(V2->getType()) + ->getElementType() + ->getIntegerBitWidth() < cast<VectorType>(V1->getType()) + ->getElementType() + ->getIntegerBitWidth()) + V2 = Builder.CreateIntCast( + V2, V1->getType(), !isKnownNonNegative(V2, SimplifyQuery(DL))); + else + V1 = Builder.CreateIntCast( + V1, V2->getType(), !isKnownNonNegative(V1, SimplifyQuery(DL))); + } + } Value *Vec = Builder.CreateShuffleVector(V1, V2, Mask); if (auto *I = dyn_cast<Instruction>(Vec)) { GatherShuffleExtractSeq.insert(I); @@ -10810,7 +10933,7 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis { Value *createShuffle(Value *V1, Value *V2, ArrayRef<int> Mask) { assert(V1 && "Expected at least one vector value."); ShuffleIRBuilder ShuffleBuilder(Builder, R.GatherShuffleExtractSeq, - R.CSEBlocks); + R.CSEBlocks, *R.DL); return BaseShuffleAnalysis::createShuffle<Value *>(V1, V2, Mask, ShuffleBuilder); } @@ -11696,10 +11819,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { } bool IsReverseOrder = isReverseOrder(E->ReorderIndices); - auto FinalShuffle = [&](Value *V, const TreeEntry *E, VectorType *VecTy, - bool IsSigned) { - if (V->getType() != VecTy) - V = Builder.CreateIntCast(V, VecTy, IsSigned); + auto FinalShuffle = [&](Value *V, const TreeEntry *E, VectorType *VecTy) { ShuffleInstructionBuilder ShuffleBuilder(Builder, *this); if (E->getOpcode() == Instruction::Store) { ArrayRef<int> Mask = @@ -11726,12 +11846,21 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { ScalarTy = Store->getValueOperand()->getType(); else if (auto *IE = dyn_cast<InsertElementInst>(VL0)) ScalarTy = IE->getOperand(1)->getType(); - bool IsSigned = false; auto It = MinBWs.find(E); - if (It != MinBWs.end()) { + if (It != MinBWs.end()) ScalarTy = IntegerType::get(F->getContext(), It->second.first); - IsSigned = It->second.second; - } + auto GetOperandSignedness = [&](unsigned Idx) { + const TreeEntry *OpE = getOperandEntry(E, Idx); + bool IsSigned = false; + auto It = MinBWs.find(OpE); + if (It != MinBWs.end()) + IsSigned = It->second.second; + else + IsSigned = any_of(OpE->Scalars, [&](Value *R) { + return !isKnownNonNegative(R, SimplifyQuery(*DL)); + }); + return IsSigned; + }; auto *VecTy = FixedVectorType::get(ScalarTy, E->Scalars.size()); switch (ShuffleOrOp) { case Instruction::PHI: { @@ -11755,7 +11884,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { PH->getParent()->getFirstInsertionPt()); Builder.SetCurrentDebugLocation(PH->getDebugLoc()); - V = FinalShuffle(V, E, VecTy, IsSigned); + V = FinalShuffle(V, E, VecTy); E->VectorizedValue = V; if (PostponedPHIs) @@ -11789,9 +11918,10 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { Builder.SetCurrentDebugLocation(PH->getDebugLoc()); Value *Vec = vectorizeOperand(E, I, /*PostponedPHIs=*/true); if (VecTy != Vec->getType()) { - assert(MinBWs.contains(getOperandEntry(E, I)) && + assert((getOperandEntry(E, I)->State == TreeEntry::NeedToGather || + MinBWs.contains(getOperandEntry(E, I))) && "Expected item in MinBWs."); - Vec = Builder.CreateIntCast(Vec, VecTy, It->second.second); + Vec = Builder.CreateIntCast(Vec, VecTy, GetOperandSignedness(I)); } NewPhi->addIncoming(Vec, IBB); } @@ -11806,7 +11936,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { if (const TreeEntry *TE = getTreeEntry(V)) V = TE->VectorizedValue; setInsertPointAfterBundle(E); - V = FinalShuffle(V, E, VecTy, IsSigned); + V = FinalShuffle(V, E, VecTy); E->VectorizedValue = V; return V; } @@ -11816,7 +11946,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { Value *Ptr = LI->getPointerOperand(); LoadInst *V = Builder.CreateAlignedLoad(VecTy, Ptr, LI->getAlign()); Value *NewV = propagateMetadata(V, E->Scalars); - NewV = FinalShuffle(NewV, E, VecTy, IsSigned); + NewV = FinalShuffle(NewV, E, VecTy); E->VectorizedValue = NewV; return NewV; } @@ -12002,10 +12132,11 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { auto *CI = cast<CastInst>(VL0); Instruction::CastOps VecOpcode = CI->getOpcode(); - Type *SrcScalarTy = VL0->getOperand(0)->getType(); + Type *SrcScalarTy = cast<VectorType>(InVec->getType())->getElementType(); auto SrcIt = MinBWs.find(getOperandEntry(E, 0)); if (!ScalarTy->isFloatingPointTy() && !SrcScalarTy->isFloatingPointTy() && - (SrcIt != MinBWs.end() || It != MinBWs.end())) { + (SrcIt != MinBWs.end() || It != MinBWs.end() || + SrcScalarTy != CI->getOperand(0)->getType())) { // Check if the values are candidates to demote. unsigned SrcBWSz = DL->getTypeSizeInBits(SrcScalarTy); if (SrcIt != MinBWs.end()) @@ -12024,7 +12155,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { Value *V = (VecOpcode != ShuffleOrOp && VecOpcode == Instruction::BitCast) ? InVec : Builder.CreateCast(VecOpcode, InVec, VecTy); - V = FinalShuffle(V, E, VecTy, IsSigned); + V = FinalShuffle(V, E, VecTy); E->VectorizedValue = V; ++NumVectorInstructions; @@ -12045,11 +12176,22 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { return E->VectorizedValue; } if (L->getType() != R->getType()) { - assert((MinBWs.contains(getOperandEntry(E, 0)) || + assert((getOperandEntry(E, 0)->State == TreeEntry::NeedToGather || + getOperandEntry(E, 1)->State == TreeEntry::NeedToGather || + MinBWs.contains(getOperandEntry(E, 0)) || MinBWs.contains(getOperandEntry(E, 1))) && "Expected item in MinBWs."); - L = Builder.CreateIntCast(L, VecTy, IsSigned); - R = Builder.CreateIntCast(R, VecTy, IsSigned); + if (cast<VectorType>(L->getType()) + ->getElementType() + ->getIntegerBitWidth() < cast<VectorType>(R->getType()) + ->getElementType() + ->getIntegerBitWidth()) { + Type *CastTy = R->getType(); + L = Builder.CreateIntCast(L, CastTy, GetOperandSignedness(0)); + } else { + Type *CastTy = L->getType(); + R = Builder.CreateIntCast(R, CastTy, GetOperandSignedness(1)); + } } CmpInst::Predicate P0 = cast<CmpInst>(VL0)->getPredicate(); @@ -12057,7 +12199,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { propagateIRFlags(V, E->Scalars, VL0); // Do not cast for cmps. VecTy = cast<FixedVectorType>(V->getType()); - V = FinalShuffle(V, E, VecTy, IsSigned); + V = FinalShuffle(V, E, VecTy); E->VectorizedValue = V; ++NumVectorInstructions; @@ -12081,16 +12223,20 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { LLVM_DEBUG(dbgs() << "SLP: Diamond merged for " << *VL0 << ".\n"); return E->VectorizedValue; } - if (True->getType() != False->getType()) { - assert((MinBWs.contains(getOperandEntry(E, 1)) || + if (True->getType() != VecTy || False->getType() != VecTy) { + assert((getOperandEntry(E, 1)->State == TreeEntry::NeedToGather || + getOperandEntry(E, 2)->State == TreeEntry::NeedToGather || + MinBWs.contains(getOperandEntry(E, 1)) || MinBWs.contains(getOperandEntry(E, 2))) && "Expected item in MinBWs."); - True = Builder.CreateIntCast(True, VecTy, IsSigned); - False = Builder.CreateIntCast(False, VecTy, IsSigned); + if (True->getType() != VecTy) + True = Builder.CreateIntCast(True, VecTy, GetOperandSignedness(1)); + if (False->getType() != VecTy) + False = Builder.CreateIntCast(False, VecTy, GetOperandSignedness(2)); } Value *V = Builder.CreateSelect(Cond, True, False); - V = FinalShuffle(V, E, VecTy, IsSigned); + V = FinalShuffle(V, E, VecTy); E->VectorizedValue = V; ++NumVectorInstructions; @@ -12112,7 +12258,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { if (auto *I = dyn_cast<Instruction>(V)) V = propagateMetadata(I, E->Scalars); - V = FinalShuffle(V, E, VecTy, IsSigned); + V = FinalShuffle(V, E, VecTy); E->VectorizedValue = V; ++NumVectorInstructions; @@ -12149,12 +12295,16 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { LLVM_DEBUG(dbgs() << "SLP: Diamond merged for " << *VL0 << ".\n"); return E->VectorizedValue; } - if (LHS->getType() != RHS->getType()) { - assert((MinBWs.contains(getOperandEntry(E, 0)) || + if (LHS->getType() != VecTy || RHS->getType() != VecTy) { + assert((getOperandEntry(E, 0)->State == TreeEntry::NeedToGather || + getOperandEntry(E, 1)->State == TreeEntry::NeedToGather || + MinBWs.contains(getOperandEntry(E, 0)) || MinBWs.contains(getOperandEntry(E, 1))) && "Expected item in MinBWs."); - LHS = Builder.CreateIntCast(LHS, VecTy, IsSigned); - RHS = Builder.CreateIntCast(RHS, VecTy, IsSigned); + if (LHS->getType() != VecTy) + LHS = Builder.CreateIntCast(LHS, VecTy, GetOperandSignedness(0)); + if (RHS->getType() != VecTy) + RHS = Builder.CreateIntCast(RHS, VecTy, GetOperandSignedness(1)); } Value *V = Builder.CreateBinOp( @@ -12164,7 +12314,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { if (auto *I = dyn_cast<Instruction>(V)) V = propagateMetadata(I, E->Scalars); - V = FinalShuffle(V, E, VecTy, IsSigned); + V = FinalShuffle(V, E, VecTy); E->VectorizedValue = V; ++NumVectorInstructions; @@ -12235,7 +12385,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { } Value *V = propagateMetadata(NewLI, E->Scalars); - V = FinalShuffle(V, E, VecTy, IsSigned); + V = FinalShuffle(V, E, VecTy); E->VectorizedValue = V; ++NumVectorInstructions; return V; @@ -12246,7 +12396,10 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { setInsertPointAfterBundle(E); Value *VecValue = vectorizeOperand(E, 0, PostponedPHIs); - VecValue = FinalShuffle(VecValue, E, VecTy, IsSigned); + if (VecValue->getType() != VecTy) + VecValue = + Builder.CreateIntCast(VecValue, VecTy, GetOperandSignedness(0)); + VecValue = FinalShuffle(VecValue, E, VecTy); Value *Ptr = SI->getPointerOperand(); StoreInst *ST = @@ -12288,7 +12441,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { V = propagateMetadata(I, GEPs); } - V = FinalShuffle(V, E, VecTy, IsSigned); + V = FinalShuffle(V, E, VecTy); E->VectorizedValue = V; ++NumVectorInstructions; @@ -12353,7 +12506,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { Value *V = Builder.CreateCall(CF, OpVecs, OpBundles); propagateIRFlags(V, E->Scalars, VL0); - V = FinalShuffle(V, E, VecTy, IsSigned); + V = FinalShuffle(V, E, VecTy); E->VectorizedValue = V; ++NumVectorInstructions; @@ -12385,12 +12538,30 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { LLVM_DEBUG(dbgs() << "SLP: Diamond merged for " << *VL0 << ".\n"); return E->VectorizedValue; } - if (LHS && RHS && LHS->getType() != RHS->getType()) { - assert((MinBWs.contains(getOperandEntry(E, 0)) || + if (LHS && RHS && + ((Instruction::isBinaryOp(E->getOpcode()) && + (LHS->getType() != VecTy || RHS->getType() != VecTy)) || + (isa<CmpInst>(VL0) && LHS->getType() != RHS->getType()))) { + assert((getOperandEntry(E, 0)->State == TreeEntry::NeedToGather || + getOperandEntry(E, 1)->State == TreeEntry::NeedToGather || + MinBWs.contains(getOperandEntry(E, 0)) || MinBWs.contains(getOperandEntry(E, 1))) && "Expected item in MinBWs."); - LHS = Builder.CreateIntCast(LHS, VecTy, IsSigned); - RHS = Builder.CreateIntCast(RHS, VecTy, IsSigned); + Type *CastTy = VecTy; + if (isa<CmpInst>(VL0) && LHS->getType() != RHS->getType()) { + if (cast<VectorType>(LHS->getType()) + ->getElementType() + ->getIntegerBitWidth() < cast<VectorType>(RHS->getType()) + ->getElementType() + ->getIntegerBitWidth()) + CastTy = RHS->getType(); + else + CastTy = LHS->getType(); + } + if (LHS->getType() != VecTy) + LHS = Builder.CreateIntCast(LHS, CastTy, GetOperandSignedness(0)); + if (RHS->getType() != VecTy) + RHS = Builder.CreateIntCast(RHS, CastTy, GetOperandSignedness(1)); } Value *V0, *V1; @@ -12442,9 +12613,6 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { CSEBlocks.insert(I->getParent()); } - if (V->getType() != VecTy && !isa<CmpInst>(VL0)) - V = Builder.CreateIntCast( - V, FixedVectorType::get(ScalarTy, E->getVectorFactor()), IsSigned); E->VectorizedValue = V; ++NumVectorInstructions; @@ -12540,6 +12708,15 @@ Value *BoUpSLP::vectorizeTree( } Builder.SetCurrentDebugLocation(UserI->getDebugLoc()); Value *Vec = vectorizeTree(TE, /*PostponedPHIs=*/false); + if (Vec->getType() != PrevVec->getType()) { + assert(Vec->getType()->isIntOrIntVectorTy() && + PrevVec->getType()->isIntOrIntVectorTy() && + "Expected integer vector types only."); + assert(MinBWs.contains(TE->UserTreeIndices.front().UserTE) && + "Expected user in MinBWs."); + bool IsSigned = MinBWs.lookup(TE->UserTreeIndices.front().UserTE).second; + Vec = Builder.CreateIntCast(Vec, PrevVec->getType(), IsSigned); + } PrevVec->replaceAllUsesWith(Vec); PostponedValues.try_emplace(Vec).first->second.push_back(TE); // Replace the stub vector node, if it was used before for one of the @@ -12959,7 +13136,21 @@ Value *BoUpSLP::vectorizeTree( Builder.ClearInsertionPoint(); InstrElementSize.clear(); - return VectorizableTree[0]->VectorizedValue; + const TreeEntry &RootTE = *VectorizableTree.front().get(); + Value *Vec = RootTE.VectorizedValue; + if (auto It = MinBWs.find(&RootTE); ReductionBitWidth != 0 && + It != MinBWs.end() && + ReductionBitWidth != It->second.first) { + IRBuilder<>::InsertPointGuard Guard(Builder); + Builder.SetInsertPoint(ReductionRoot->getParent(), + ReductionRoot->getIterator()); + Vec = Builder.CreateIntCast( + Vec, + VectorType::get(Builder.getIntNTy(ReductionBitWidth), + cast<VectorType>(Vec->getType())->getElementCount()), + It->second.second); + } + return Vec; } void BoUpSLP::optimizeGatherSequence() { @@ -13779,23 +13970,46 @@ unsigned BoUpSLP::getVectorElementSize(Value *V) { // smaller type with a truncation. We collect the values that will be demoted // in ToDemote and additional roots that require investigating in Roots. bool BoUpSLP::collectValuesToDemote( - Value *V, SmallVectorImpl<Value *> &ToDemote, + Value *V, bool IsProfitableToDemoteRoot, unsigned &BitWidth, + SmallVectorImpl<Value *> &ToDemote, DenseMap<Instruction *, SmallVector<unsigned>> &DemotedConsts, - SmallVectorImpl<Value *> &Roots, DenseSet<Value *> &Visited) const { + DenseSet<Value *> &Visited, unsigned &MaxDepthLevel, + bool &IsProfitableToDemote, bool IsTruncRoot) const { // We can always demote constants. if (isa<Constant>(V)) return true; + if (DL->getTypeSizeInBits(V->getType()) == BitWidth) { + MaxDepthLevel = 1; + return true; + } + // If the value is not a vectorized instruction in the expression and not used // by the insertelement instruction and not used in multiple vector nodes, it // cannot be demoted. + // TODO: improve handling of gathered values and others. auto *I = dyn_cast<Instruction>(V); - if (!I || !getTreeEntry(I) || MultiNodeScalars.contains(I) || - !Visited.insert(I).second || all_of(I->users(), [&](User *U) { + const TreeEntry *ITE = I ? getTreeEntry(I) : nullptr; + if (!ITE || !Visited.insert(I).second || MultiNodeScalars.contains(I) || + all_of(I->users(), [&](User *U) { return isa<InsertElementInst>(U) && !getTreeEntry(U); })) return false; + auto IsPotentiallyTruncated = [&](Value *V, unsigned &BitWidth) -> bool { + if (MultiNodeScalars.contains(V)) + return false; + uint32_t OrigBitWidth = DL->getTypeSizeInBits(V->getType()); + APInt Mask = APInt::getBitsSetFrom(OrigBitWidth, BitWidth); + if (MaskedValueIsZero(V, Mask, SimplifyQuery(*DL))) + return true; + auto NumSignBits = ComputeNumSignBits(V, *DL, 0, AC, nullptr, DT); + unsigned BitWidth1 = OrigBitWidth - NumSignBits; + if (!isKnownNonNegative(V, SimplifyQuery(*DL))) + ++BitWidth1; + BitWidth = std::max(BitWidth, BitWidth1); + return BitWidth > 0 && OrigBitWidth >= (BitWidth * 2); + }; unsigned Start = 0; unsigned End = I->getNumOperands(); switch (I->getOpcode()) { @@ -13803,12 +14017,16 @@ bool BoUpSLP::collectValuesToDemote( // We can always demote truncations and extensions. Since truncations can // seed additional demotion, we save the truncated value. case Instruction::Trunc: - Roots.push_back(I->getOperand(0)); + if (!IsTruncRoot) + MaxDepthLevel = 1; + if (IsProfitableToDemoteRoot) + IsProfitableToDemote = true; break; case Instruction::ZExt: case Instruction::SExt: - if (isa<ExtractElementInst, InsertElementInst>(I->getOperand(0))) - return false; + if (!IsTruncRoot) + MaxDepthLevel = 1; + IsProfitableToDemote = true; break; // We can demote certain binary operations if we can demote both of their @@ -13818,23 +14036,36 @@ bool BoUpSLP::collectValuesToDemote( case Instruction::Mul: case Instruction::And: case Instruction::Or: - case Instruction::Xor: - if (!collectValuesToDemote(I->getOperand(0), ToDemote, DemotedConsts, Roots, - Visited) || - !collectValuesToDemote(I->getOperand(1), ToDemote, DemotedConsts, Roots, - Visited)) + case Instruction::Xor: { + unsigned Level1 = MaxDepthLevel, Level2 = MaxDepthLevel; + if ((ITE->UserTreeIndices.size() > 1 && + !IsPotentiallyTruncated(I, BitWidth)) || + !collectValuesToDemote(I->getOperand(0), IsProfitableToDemoteRoot, + BitWidth, ToDemote, DemotedConsts, Visited, + Level1, IsProfitableToDemote, IsTruncRoot) || + !collectValuesToDemote(I->getOperand(1), IsProfitableToDemoteRoot, + BitWidth, ToDemote, DemotedConsts, Visited, + Level2, IsProfitableToDemote, IsTruncRoot)) return false; + MaxDepthLevel = std::max(Level1, Level2); break; + } // We can demote selects if we can demote their true and false values. case Instruction::Select: { Start = 1; + unsigned Level1 = MaxDepthLevel, Level2 = MaxDepthLevel; SelectInst *SI = cast<SelectInst>(I); - if (!collectValuesToDemote(SI->getTrueValue(), ToDemote, DemotedConsts, - Roots, Visited) || - !collectValuesToDemote(SI->getFalseValue(), ToDemote, DemotedConsts, - Roots, Visited)) + if ((ITE->UserTreeIndices.size() > 1 && + !IsPotentiallyTruncated(I, BitWidth)) || + !collectValuesToDemote(SI->getTrueValue(), IsProfitableToDemoteRoot, + BitWidth, ToDemote, DemotedConsts, Visited, + Level1, IsProfitableToDemote, IsTruncRoot) || + !collectValuesToDemote(SI->getFalseValue(), IsProfitableToDemoteRoot, + BitWidth, ToDemote, DemotedConsts, Visited, + Level2, IsProfitableToDemote, IsTruncRoot)) return false; + MaxDepthLevel = std::max(Level1, Level2); break; } @@ -13842,172 +14073,269 @@ bool BoUpSLP::collectValuesToDemote( // we don't need to worry about cycles since we ensure single use above. case Instruction::PHI: { PHINode *PN = cast<PHINode>(I); - for (Value *IncValue : PN->incoming_values()) - if (!collectValuesToDemote(IncValue, ToDemote, DemotedConsts, Roots, - Visited)) + if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) + return false; + unsigned InitLevel = MaxDepthLevel; + for (Value *IncValue : PN->incoming_values()) { + unsigned Level = InitLevel; + if (!collectValuesToDemote(IncValue, IsProfitableToDemoteRoot, BitWidth, + ToDemote, DemotedConsts, Visited, Level, + IsProfitableToDemote, IsTruncRoot)) return false; + MaxDepthLevel = std::max(MaxDepthLevel, Level); + } break; } // Otherwise, conservatively give up. default: - return false; + MaxDepthLevel = 1; + return IsProfitableToDemote && IsPotentiallyTruncated(I, BitWidth); } + ++MaxDepthLevel; // Gather demoted constant operands. for (unsigned Idx : seq<unsigned>(Start, End)) if (isa<Constant>(I->getOperand(Idx))) DemotedConsts.try_emplace(I).first->getSecond().push_back(Idx); // Record the value that we can demote. ToDemote.push_back(V); - return true; + return IsProfitableToDemote; } void BoUpSLP::computeMinimumValueSizes() { // We only attempt to truncate integer expressions. - auto &TreeRoot = VectorizableTree[0]->Scalars; - auto *TreeRootIT = dyn_cast<IntegerType>(TreeRoot[0]->getType()); - if (!TreeRootIT || VectorizableTree.front()->State == TreeEntry::NeedToGather) + bool IsStoreOrInsertElt = + VectorizableTree.front()->getOpcode() == Instruction::Store || + VectorizableTree.front()->getOpcode() == Instruction::InsertElement; + if ((IsStoreOrInsertElt || UserIgnoreList) && TruncNodes.size() <= 1 && + (!CastMaxMinBWSizes || CastMaxMinBWSizes->second == 0 || + CastMaxMinBWSizes->first / CastMaxMinBWSizes->second <= 2)) return; + unsigned NodeIdx = 0; + if (IsStoreOrInsertElt && + VectorizableTree.front()->State != TreeEntry::NeedToGather) + NodeIdx = 1; + // Ensure the roots of the vectorizable tree don't form a cycle. - if (!VectorizableTree.front()->UserTreeIndices.empty()) + if (VectorizableTree[NodeIdx]->State == TreeEntry::NeedToGather || + (NodeIdx == 0 && !VectorizableTree[NodeIdx]->UserTreeIndices.empty()) || + (NodeIdx != 0 && any_of(VectorizableTree[NodeIdx]->UserTreeIndices, + [NodeIdx](const EdgeInfo &EI) { + return EI.UserTE->Idx > + static_cast<int>(NodeIdx); + }))) return; - // Conservatively determine if we can actually truncate the roots of the - // expression. Collect the values that can be demoted in ToDemote and - // additional roots that require investigating in Roots. - SmallVector<Value *, 32> ToDemote; - DenseMap<Instruction *, SmallVector<unsigned>> DemotedConsts; - SmallVector<Value *, 4> Roots; - for (auto *Root : TreeRoot) { - DenseSet<Value *> Visited; - if (!collectValuesToDemote(Root, ToDemote, DemotedConsts, Roots, Visited)) - return; - } - - // The maximum bit width required to represent all the values that can be - // demoted without loss of precision. It would be safe to truncate the roots - // of the expression to this width. - auto MaxBitWidth = 1u; - - // We first check if all the bits of the roots are demanded. If they're not, - // we can truncate the roots to this narrower type. - for (auto *Root : TreeRoot) { - auto Mask = DB->getDemandedBits(cast<Instruction>(Root)); - MaxBitWidth = std::max<unsigned>(Mask.getBitWidth() - Mask.countl_zero(), - MaxBitWidth); - } - - // True if the roots can be zero-extended back to their original type, rather - // than sign-extended. We know that if the leading bits are not demanded, we - // can safely zero-extend. So we initialize IsKnownPositive to True. - bool IsKnownPositive = true; - - // If all the bits of the roots are demanded, we can try a little harder to - // compute a narrower type. This can happen, for example, if the roots are - // getelementptr indices. InstCombine promotes these indices to the pointer - // width. Thus, all their bits are technically demanded even though the - // address computation might be vectorized in a smaller type. - // - // We start by looking at each entry that can be demoted. We compute the - // maximum bit width required to store the scalar by using ValueTracking to - // compute the number of high-order bits we can truncate. - if (MaxBitWidth == DL->getTypeSizeInBits(TreeRoot[0]->getType()) && - all_of(TreeRoot, [](Value *V) { - return all_of(V->users(), - [](User *U) { return isa<GetElementPtrInst>(U); }); - })) { - MaxBitWidth = 8u; + // The first value node for store/insertelement is sext/zext/trunc? Skip it, + // resize to the final type. + bool IsProfitableToDemoteRoot = !IsStoreOrInsertElt; + if (NodeIdx != 0 && + VectorizableTree[NodeIdx]->State == TreeEntry::Vectorize && + (VectorizableTree[NodeIdx]->getOpcode() == Instruction::ZExt || + VectorizableTree[NodeIdx]->getOpcode() == Instruction::SExt || + VectorizableTree[NodeIdx]->getOpcode() == Instruction::Trunc)) { + assert(IsStoreOrInsertElt && "Expected store/insertelement seeded graph."); + ++NodeIdx; + IsProfitableToDemoteRoot = true; + } + + // Analyzed in reduction already and not profitable - exit. + if (AnalyzedMinBWVals.contains(VectorizableTree[NodeIdx]->Scalars.front())) + return; + SmallVector<Value *> ToDemote; + DenseMap<Instruction *, SmallVector<unsigned>> DemotedConsts; + auto ComputeMaxBitWidth = [&](ArrayRef<Value *> TreeRoot, unsigned VF, + bool IsTopRoot, bool IsProfitableToDemoteRoot, + unsigned Opcode, unsigned Limit, bool IsTruncRoot) { + ToDemote.clear(); + auto *TreeRootIT = dyn_cast<IntegerType>(TreeRoot[0]->getType()); + if (!TreeRootIT || !Opcode) + return 0u; + + if (AnalyzedMinBWVals.contains(TreeRoot.front())) + return 0u; + + unsigned NumParts = TTI->getNumberOfParts( + FixedVectorType::get(TreeRoot.front()->getType(), VF)); + + // The maximum bit width required to represent all the values that can be + // demoted without loss of precision. It would be safe to truncate the roots + // of the expression to this width. + unsigned MaxBitWidth = 1u; + + // True if the roots can be zero-extended back to their original type, + // rather than sign-extended. We know that if the leading bits are not + // demanded, we can safely zero-extend. So we initialize IsKnownPositive to + // True. // Determine if the sign bit of all the roots is known to be zero. If not, // IsKnownPositive is set to False. - IsKnownPositive = llvm::all_of(TreeRoot, [&](Value *R) { + bool IsKnownPositive = all_of(TreeRoot, [&](Value *R) { KnownBits Known = computeKnownBits(R, *DL); return Known.isNonNegative(); }); - // Determine the maximum number of bits required to store the scalar - // values. - for (auto *Scalar : ToDemote) { - auto NumSignBits = ComputeNumSignBits(Scalar, *DL, 0, AC, nullptr, DT); - auto NumTypeBits = DL->getTypeSizeInBits(Scalar->getType()); - MaxBitWidth = std::max<unsigned>(NumTypeBits - NumSignBits, MaxBitWidth); - } - - // If we can't prove that the sign bit is zero, we must add one to the - // maximum bit width to account for the unknown sign bit. This preserves - // the existing sign bit so we can safely sign-extend the root back to the - // original type. Otherwise, if we know the sign bit is zero, we will - // zero-extend the root instead. - // - // FIXME: This is somewhat suboptimal, as there will be cases where adding - // one to the maximum bit width will yield a larger-than-necessary - // type. In general, we need to add an extra bit only if we can't - // prove that the upper bit of the original type is equal to the - // upper bit of the proposed smaller type. If these two bits are the - // same (either zero or one) we know that sign-extending from the - // smaller type will result in the same value. Here, since we can't - // yet prove this, we are just making the proposed smaller type - // larger to ensure correctness. - if (!IsKnownPositive) - ++MaxBitWidth; - } - - // Round MaxBitWidth up to the next power-of-two. - MaxBitWidth = llvm::bit_ceil(MaxBitWidth); - - // If the maximum bit width we compute is less than the with of the roots' - // type, we can proceed with the narrowing. Otherwise, do nothing. - if (MaxBitWidth >= TreeRootIT->getBitWidth()) - return; + // We first check if all the bits of the roots are demanded. If they're not, + // we can truncate the roots to this narrower type. + for (auto *Root : TreeRoot) { + unsigned NumSignBits = ComputeNumSignBits(Root, *DL, 0, AC, nullptr, DT); + TypeSize NumTypeBits = DL->getTypeSizeInBits(Root->getType()); + unsigned BitWidth1 = NumTypeBits - NumSignBits; + // If we can't prove that the sign bit is zero, we must add one to the + // maximum bit width to account for the unknown sign bit. This preserves + // the existing sign bit so we can safely sign-extend the root back to the + // original type. Otherwise, if we know the sign bit is zero, we will + // zero-extend the root instead. + // + // FIXME: This is somewhat suboptimal, as there will be cases where adding + // one to the maximum bit width will yield a larger-than-necessary + // type. In general, we need to add an extra bit only if we can't + // prove that the upper bit of the original type is equal to the + // upper bit of the proposed smaller type. If these two bits are + // the same (either zero or one) we know that sign-extending from + // the smaller type will result in the same value. Here, since we + // can't yet prove this, we are just making the proposed smaller + // type larger to ensure correctness. + if (!IsKnownPositive) + ++BitWidth1; + + APInt Mask = DB->getDemandedBits(cast<Instruction>(Root)); + unsigned BitWidth2 = Mask.getBitWidth() - Mask.countl_zero(); + MaxBitWidth = + std::max<unsigned>(std::min(BitWidth1, BitWidth2), MaxBitWidth); + } + + if (MaxBitWidth < 8 && MaxBitWidth > 1) + MaxBitWidth = 8; + + // If the original type is large, but reduced type does not improve the reg + // use - ignore it. + if (NumParts > 1 && + NumParts == + TTI->getNumberOfParts(FixedVectorType::get( + IntegerType::get(F->getContext(), bit_ceil(MaxBitWidth)), VF))) + return 0u; + + bool IsProfitableToDemote = Opcode == Instruction::Trunc || + Opcode == Instruction::SExt || + Opcode == Instruction::ZExt || NumParts > 1; + // Conservatively determine if we can actually truncate the roots of the + // expression. Collect the values that can be demoted in ToDemote and + // additional roots that require investigating in Roots. + for (auto *Root : TreeRoot) { + DenseSet<Value *> Visited; + unsigned MaxDepthLevel = IsTruncRoot ? Limit : 1; + bool NeedToDemote = IsProfitableToDemote; + + if (!collectValuesToDemote(Root, IsProfitableToDemoteRoot, MaxBitWidth, + ToDemote, DemotedConsts, Visited, + MaxDepthLevel, NeedToDemote, IsTruncRoot) || + (MaxDepthLevel <= Limit && + !(((Opcode == Instruction::SExt || Opcode == Instruction::ZExt) && + (!IsTopRoot || !(IsStoreOrInsertElt || UserIgnoreList) || + DL->getTypeSizeInBits(Root->getType()) / + DL->getTypeSizeInBits( + cast<Instruction>(Root)->getOperand(0)->getType()) > + 2))))) + return 0u; + } + // Round MaxBitWidth up to the next power-of-two. + MaxBitWidth = bit_ceil(MaxBitWidth); + + return MaxBitWidth; + }; // If we can truncate the root, we must collect additional values that might // be demoted as a result. That is, those seeded by truncations we will // modify. - while (!Roots.empty()) { - DenseSet<Value *> Visited; - collectValuesToDemote(Roots.pop_back_val(), ToDemote, DemotedConsts, Roots, - Visited); - } - - // Check that all users are marked for demotion. - DenseSet<Value *> Demoted(ToDemote.begin(), ToDemote.end()); - DenseSet<const TreeEntry *> Visited; - for (Value *V: ToDemote) { - const TreeEntry *TE = getTreeEntry(V); - assert(TE && "Expected vectorized scalar."); - if (!Visited.insert(TE).second) - continue; - if (!all_of(TE->UserTreeIndices, [&](const EdgeInfo &EI) { - return all_of(EI.UserTE->Scalars, - [&](Value *V) { return Demoted.contains(V); }); - })) - return; - } - // Finally, map the values we can demote to the maximum bit with we computed. - for (auto *Scalar : ToDemote) { - auto *TE = getTreeEntry(Scalar); - assert(TE && "Expected vectorized scalar."); - if (MinBWs.contains(TE)) + // Add reduction ops sizes, if any. + if (UserIgnoreList && + isa<IntegerType>(VectorizableTree.front()->Scalars.front()->getType())) { + for (Value *V : *UserIgnoreList) { + auto NumSignBits = ComputeNumSignBits(V, *DL, 0, AC, nullptr, DT); + auto NumTypeBits = DL->getTypeSizeInBits(V->getType()); + unsigned BitWidth1 = NumTypeBits - NumSignBits; + if (!isKnownNonNegative(V, SimplifyQuery(*DL))) + ++BitWidth1; + auto Mask = DB->getDemandedBits(cast<Instruction>(V)); + unsigned BitWidth2 = Mask.getBitWidth() - Mask.countl_zero(); + ReductionBitWidth = + std::max(std::min(BitWidth1, BitWidth2), ReductionBitWidth); + } + if (ReductionBitWidth < 8 && ReductionBitWidth > 1) + ReductionBitWidth = 8; + + ReductionBitWidth = bit_ceil(ReductionBitWidth); + } + bool IsTopRoot = NodeIdx == 0; + bool IsTruncRoot = false; + while (NodeIdx < VectorizableTree.size() && + VectorizableTree[NodeIdx]->State == TreeEntry::Vectorize && + VectorizableTree[NodeIdx]->getOpcode() == Instruction::Trunc) { + ++NodeIdx; + IsTruncRoot = true; + } + while (NodeIdx < VectorizableTree.size()) { + ArrayRef<Value *> TreeRoot = VectorizableTree[NodeIdx]->Scalars; + unsigned Limit = 2; + unsigned Opcode = VectorizableTree[NodeIdx]->getOpcode(); + if (IsTopRoot && + ReductionBitWidth == + DL->getTypeSizeInBits( + VectorizableTree.front()->Scalars.front()->getType())) + Limit = 3; + unsigned MaxBitWidth = ComputeMaxBitWidth( + TreeRoot, VectorizableTree[NodeIdx]->getVectorFactor(), IsTopRoot, + IsProfitableToDemoteRoot, Opcode, Limit, IsTruncRoot); + IsTopRoot = false; + IsProfitableToDemoteRoot = true; + + if (TruncNodes.empty()) { + NodeIdx = VectorizableTree.size(); + } else { + NodeIdx = *TruncNodes.begin() + 1; + TruncNodes.erase(TruncNodes.begin()); + IsTruncRoot = true; + } + + // If the maximum bit width we compute is less than the with of the roots' + // type, we can proceed with the narrowing. Otherwise, do nothing. + if (MaxBitWidth == 0 || + MaxBitWidth >= + cast<IntegerType>(TreeRoot.front()->getType())->getBitWidth()) { + if (UserIgnoreList) + AnalyzedMinBWVals.insert(TreeRoot.begin(), TreeRoot.end()); continue; - bool IsSigned = any_of(TE->Scalars, [&](Value *R) { - KnownBits Known = computeKnownBits(R, *DL); - return !Known.isNonNegative(); - }); - MinBWs.try_emplace(TE, MaxBitWidth, IsSigned); - const auto *I = cast<Instruction>(Scalar); - auto DCIt = DemotedConsts.find(I); - if (DCIt != DemotedConsts.end()) { - for (unsigned Idx : DCIt->getSecond()) { - // Check that all instructions operands are demoted. - if (all_of(TE->Scalars, [&](Value *V) { - auto SIt = DemotedConsts.find(cast<Instruction>(V)); - return SIt != DemotedConsts.end() && - is_contained(SIt->getSecond(), Idx); - })) { + } + + // Finally, map the values we can demote to the maximum bit with we + // computed. + for (Value *Scalar : ToDemote) { + TreeEntry *TE = getTreeEntry(Scalar); + assert(TE && "Expected vectorized scalar."); + if (MinBWs.contains(TE)) + continue; + bool IsSigned = TE->getOpcode() == Instruction::SExt || + any_of(TE->Scalars, [&](Value *R) { + return !isKnownNonNegative(R, SimplifyQuery(*DL)); + }); + MinBWs.try_emplace(TE, MaxBitWidth, IsSigned); + const auto *I = cast<Instruction>(Scalar); + auto DCIt = DemotedConsts.find(I); + if (DCIt != DemotedConsts.end()) { + for (unsigned Idx : DCIt->getSecond()) { + // Check that all instructions operands are demoted. const TreeEntry *CTE = getOperandEntry(TE, Idx); - MinBWs.try_emplace(CTE, MaxBitWidth, IsSigned); + if (all_of(TE->Scalars, + [&](Value *V) { + auto SIt = DemotedConsts.find(cast<Instruction>(V)); + return SIt != DemotedConsts.end() && + is_contained(SIt->getSecond(), Idx); + }) || + all_of(CTE->Scalars, Constant::classof)) + MinBWs.try_emplace(CTE, MaxBitWidth, IsSigned); } } } diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/ext-trunc.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/ext-trunc.ll index cef791633655..5e3fd156666f 100644 --- a/llvm/test/Transforms/SLPVectorizer/AArch64/ext-trunc.ll +++ b/llvm/test/Transforms/SLPVectorizer/AArch64/ext-trunc.ll @@ -17,12 +17,13 @@ define void @test1(<4 x i16> %a, <4 x i16> %b, ptr %p) { ; CHECK-NEXT: [[GEP0:%.*]] = getelementptr inbounds i64, ptr [[P:%.*]], i64 [[S0]] ; CHECK-NEXT: [[LOAD0:%.*]] = load i64, ptr [[GEP0]], align 4 ; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <4 x i32> [[SUB0]], <4 x i32> poison, <2 x i32> <i32 1, i32 2> -; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i32> [[TMP0]] to <2 x i64> -; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x i64> [[TMP1]], i32 0 +; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x i32> [[TMP0]], i32 0 +; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 [[TMP2]] ; CHECK-NEXT: [[LOAD1:%.*]] = load i64, ptr [[GEP1]], align 4 -; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1 -; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 [[TMP3]] +; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x i32> [[TMP0]], i32 1 +; CHECK-NEXT: [[TMP4:%.*]] = sext i32 [[TMP3]] to i64 +; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 [[TMP4]] ; CHECK-NEXT: [[LOAD2:%.*]] = load i64, ptr [[GEP2]], align 4 ; CHECK-NEXT: [[E3:%.*]] = extractelement <4 x i32> [[SUB0]], i32 3 ; CHECK-NEXT: [[S3:%.*]] = sext i32 [[E3]] to i64 diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/gather-buildvector-with-minbitwidth-user.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/gather-buildvector-with-minbitwidth-user.ll index 705e425d3e44..690772472975 100644 --- a/llvm/test/Transforms/SLPVectorizer/AArch64/gather-buildvector-with-minbitwidth-user.ll +++ b/llvm/test/Transforms/SLPVectorizer/AArch64/gather-buildvector-with-minbitwidth-user.ll @@ -6,9 +6,10 @@ define void @h() { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr i8, ptr null, i64 16 ; CHECK-NEXT: [[TMP0:%.*]] = insertelement <8 x i32> <i32 undef, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>, i32 0, i32 0 -; CHECK-NEXT: [[TMP1:%.*]] = or <8 x i32> zeroinitializer, [[TMP0]] -; CHECK-NEXT: [[TMP2:%.*]] = or <8 x i32> [[TMP1]], zeroinitializer -; CHECK-NEXT: [[TMP3:%.*]] = trunc <8 x i32> [[TMP2]] to <8 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = trunc <8 x i32> [[TMP0]] to <8 x i1> +; CHECK-NEXT: [[TMP2:%.*]] = or <8 x i1> zeroinitializer, [[TMP1]] +; CHECK-NEXT: [[TMP4:%.*]] = or <8 x i1> [[TMP2]], zeroinitializer +; CHECK-NEXT: [[TMP3:%.*]] = zext <8 x i1> [[TMP4]] to <8 x i16> ; CHECK-NEXT: store <8 x i16> [[TMP3]], ptr [[ARRAYIDX2]], align 2 ; CHECK-NEXT: ret void ; diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/gather-with-minbith-user.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/gather-with-minbith-user.ll index 9566c00dd630..d51ef0bce3a4 100644 --- a/llvm/test/Transforms/SLPVectorizer/AArch64/gather-with-minbith-user.ll +++ b/llvm/test/Transforms/SLPVectorizer/AArch64/gather-with-minbith-user.ll @@ -5,11 +5,12 @@ define void @h() { ; CHECK-LABEL: define void @h() { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr i8, ptr null, i64 16 -; CHECK-NEXT: [[TMP0:%.*]] = sub <8 x i32> zeroinitializer, zeroinitializer -; CHECK-NEXT: [[TMP1:%.*]] = add <8 x i32> zeroinitializer, zeroinitializer -; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i32> [[TMP0]], <8 x i32> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15> -; CHECK-NEXT: [[TMP3:%.*]] = or <8 x i32> [[TMP2]], zeroinitializer -; CHECK-NEXT: [[TMP4:%.*]] = trunc <8 x i32> [[TMP3]] to <8 x i16> +; CHECK-NEXT: [[TMP0:%.*]] = trunc <8 x i32> zeroinitializer to <8 x i1> +; CHECK-NEXT: [[TMP1:%.*]] = sub <8 x i1> [[TMP0]], zeroinitializer +; CHECK-NEXT: [[TMP2:%.*]] = add <8 x i1> [[TMP0]], zeroinitializer +; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i1> [[TMP1]], <8 x i1> [[TMP2]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15> +; CHECK-NEXT: [[TMP5:%.*]] = or <8 x i1> [[TMP3]], zeroinitializer +; CHECK-NEXT: [[TMP4:%.*]] = zext <8 x i1> [[TMP5]] to <8 x i16> ; CHECK-NEXT: store <8 x i16> [[TMP4]], ptr [[ARRAYIDX2]], align 2 ; CHECK-NEXT: ret void ; diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/getelementptr2.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/getelementptr2.ll index 47485e514ec2..1cce52060c47 100644 --- a/llvm/test/Transforms/SLPVectorizer/AArch64/getelementptr2.ll +++ b/llvm/test/Transforms/SLPVectorizer/AArch64/getelementptr2.ll @@ -1,8 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ;test_i16_extend NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -mtriple=aarch64--linux-gnu -passes=slp-vectorizer,dce,instcombine -slp-threshold=-7 -pass-remarks-output=%t < %s | FileCheck %s +; RUN: opt -S -mtriple=aarch64--linux-gnu -passes=slp-vectorizer,dce,instcombine -slp-threshold=-5 -pass-remarks-output=%t < %s | FileCheck %s ; RUN: cat %t | FileCheck -check-prefix=YAML %s -; RUN: opt -S -mtriple=aarch64--linux-gnu -passes='slp-vectorizer,dce,instcombine' -slp-threshold=-7 -pass-remarks-output=%t < %s | FileCheck %s +; RUN: opt -S -mtriple=aarch64--linux-gnu -passes='slp-vectorizer,dce,instcombine' -slp-threshold=-5 -pass-remarks-output=%t < %s | FileCheck %s ; RUN: cat %t | FileCheck -check-prefix=YAML %s diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/reduce-add-i64.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/reduce-add-i64.ll index d67fdc1cd6aa..a7a7f642ced5 100644 --- a/llvm/test/Transforms/SLPVectorizer/AArch64/reduce-add-i64.ll +++ b/llvm/test/Transforms/SLPVectorizer/AArch64/reduce-add-i64.ll @@ -28,21 +28,11 @@ entry: define i64 @red_zext_ld_4xi64(ptr %ptr) { ; CHECK-LABEL: @red_zext_ld_4xi64( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LD0:%.*]] = load i8, ptr [[PTR:%.*]], align 1 -; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[LD0]] to i64 -; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 1 -; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[GEP]], align 1 -; CHECK-NEXT: [[ZEXT_1:%.*]] = zext i8 [[LD1]] to i64 -; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i64 [[ZEXT]], [[ZEXT_1]] -; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 2 -; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[GEP_1]], align 1 -; CHECK-NEXT: [[ZEXT_2:%.*]] = zext i8 [[LD2]] to i64 -; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i64 [[ADD_1]], [[ZEXT_2]] -; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3 -; CHECK-NEXT: [[LD3:%.*]] = load i8, ptr [[GEP_2]], align 1 -; CHECK-NEXT: [[ZEXT_3:%.*]] = zext i8 [[LD3]] to i64 -; CHECK-NEXT: [[ADD_3:%.*]] = add nuw nsw i64 [[ADD_2]], [[ZEXT_3]] -; CHECK-NEXT: ret i64 [[ADD_3]] +; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i8>, ptr [[PTR:%.*]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i8> [[TMP0]] to <4 x i16> +; CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.vector.reduce.add.v4i16(<4 x i16> [[TMP1]]) +; CHECK-NEXT: [[TMP3:%.*]] = zext i16 [[TMP2]] to i64 +; CHECK-NEXT: ret i64 [[TMP3]] ; entry: %ld0 = load i8, ptr %ptr diff --git a/llvm/test/Transforms/SLPVectorizer/RISCV/reductions.ll b/llvm/test/Transforms/SLPVectorizer/RISCV/reductions.ll index 000e7a56df37..500f10659f04 100644 --- a/llvm/test/Transforms/SLPVectorizer/RISCV/reductions.ll +++ b/llvm/test/Transforms/SLPVectorizer/RISCV/reductions.ll @@ -802,9 +802,10 @@ define i64 @red_zext_ld_4xi64(ptr %ptr) { ; CHECK-LABEL: @red_zext_ld_4xi64( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i8>, ptr [[PTR:%.*]], align 1 -; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i8> [[TMP0]] to <4 x i64> -; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> [[TMP1]]) -; CHECK-NEXT: ret i64 [[TMP2]] +; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i8> [[TMP0]] to <4 x i16> +; CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.vector.reduce.add.v4i16(<4 x i16> [[TMP1]]) +; CHECK-NEXT: [[TMP3:%.*]] = zext i16 [[TMP2]] to i64 +; CHECK-NEXT: ret i64 [[TMP3]] ; entry: %ld0 = load i8, ptr %ptr diff --git a/llvm/test/Transforms/SLPVectorizer/X86/PR35777.ll b/llvm/test/Transforms/SLPVectorizer/X86/PR35777.ll index 4565d4928ba4..05511f843a68 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/PR35777.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/PR35777.ll @@ -15,11 +15,12 @@ define { i64, i64 } @patatino(double %arg) { ; CHECK-NEXT: [[TMP6:%.*]] = load <2 x double>, ptr getelementptr inbounds ([6 x double], ptr @global, i64 0, i64 4), align 16 ; CHECK-NEXT: [[TMP7:%.*]] = fadd <2 x double> [[TMP6]], [[TMP5]] ; CHECK-NEXT: [[TMP8:%.*]] = fptosi <2 x double> [[TMP7]] to <2 x i32> -; CHECK-NEXT: [[TMP9:%.*]] = sext <2 x i32> [[TMP8]] to <2 x i64> -; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i64> [[TMP9]], i32 0 +; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x i32> [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP10:%.*]] = sext i32 [[TMP9]] to i64 ; CHECK-NEXT: [[T16:%.*]] = insertvalue { i64, i64 } undef, i64 [[TMP10]], 0 -; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x i64> [[TMP9]], i32 1 -; CHECK-NEXT: [[T17:%.*]] = insertvalue { i64, i64 } [[T16]], i64 [[TMP11]], 1 +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x i32> [[TMP8]], i32 1 +; CHECK-NEXT: [[TMP12:%.*]] = sext i32 [[TMP11]] to i64 +; CHECK-NEXT: [[T17:%.*]] = insertvalue { i64, i64 } [[T16]], i64 [[TMP12]], 1 ; CHECK-NEXT: ret { i64, i64 } [[T17]] ; bb: diff --git a/llvm/test/Transforms/SLPVectorizer/X86/int-bitcast-minbitwidth.ll b/llvm/test/Transforms/SLPVectorizer/X86/int-bitcast-minbitwidth.ll index a0af8e36b36c..5ee801607653 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/int-bitcast-minbitwidth.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/int-bitcast-minbitwidth.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 -; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -slp-threshold=-3 < %s | FileCheck %s +; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -slp-threshold=-6 < %s | FileCheck %s define void @t(i64 %v) { ; CHECK-LABEL: define void @t( diff --git a/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-icmp-to-trunc.ll b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-icmp-to-trunc.ll index 759cb65a1f08..fc28d7ab4ee7 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-icmp-to-trunc.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-icmp-to-trunc.ll @@ -18,17 +18,22 @@ define i1 @test(ptr noalias %0, i64 %1, ptr noalias %p, ptr %p1) { ; CHECK-NEXT: [[TMP8:%.*]] = and <2 x i24> [[TMP7]], <i24 255, i24 255> ; CHECK-NEXT: [[TMP9:%.*]] = icmp eq <2 x i24> [[TMP8]], <i24 24, i24 24> ; CHECK-NEXT: [[TMP10:%.*]] = select <2 x i1> [[TMP9]], <2 x i24> <i24 23, i24 23>, <2 x i24> [[TMP8]] -; CHECK-NEXT: [[TMP11:%.*]] = zext <2 x i24> [[TMP10]] to <2 x i32> +; CHECK-NEXT: [[TMP23:%.*]] = trunc <2 x i24> [[TMP10]] to <2 x i8> +; CHECK-NEXT: [[TMP11:%.*]] = zext <2 x i8> [[TMP23]] to <2 x i32> ; CHECK-NEXT: [[TMP12:%.*]] = and <2 x i32> [[TMP11]], <i32 254, i32 254> ; CHECK-NEXT: [[TMP13:%.*]] = icmp eq <2 x i32> [[TMP12]], <i32 4, i32 4> -; CHECK-NEXT: [[TMP14:%.*]] = select <2 x i1> [[TMP13]], <2 x i32> <i32 2, i32 2>, <2 x i32> [[TMP11]] +; CHECK-NEXT: [[TMP25:%.*]] = select <2 x i1> [[TMP13]], <2 x i8> <i8 2, i8 2>, <2 x i8> [[TMP23]] +; CHECK-NEXT: [[TMP14:%.*]] = zext <2 x i8> [[TMP25]] to <2 x i32> ; CHECK-NEXT: [[TMP15:%.*]] = icmp eq <2 x i32> [[TMP14]], <i32 32, i32 32> -; CHECK-NEXT: [[TMP16:%.*]] = select <2 x i1> [[TMP15]], <2 x i32> <i32 31, i32 31>, <2 x i32> [[TMP14]] +; CHECK-NEXT: [[TMP18:%.*]] = select <2 x i1> [[TMP15]], <2 x i8> <i8 31, i8 31>, <2 x i8> [[TMP25]] +; CHECK-NEXT: [[TMP16:%.*]] = zext <2 x i8> [[TMP18]] to <2 x i32> ; CHECK-NEXT: [[TMP17:%.*]] = icmp eq <2 x i32> [[TMP16]], <i32 54, i32 54> -; CHECK-NEXT: [[TMP18:%.*]] = select <2 x i1> [[TMP17]], <2 x i32> <i32 53, i32 53>, <2 x i32> [[TMP16]] -; CHECK-NEXT: [[TMP19:%.*]] = extractelement <2 x i32> [[TMP18]], i32 0 +; CHECK-NEXT: [[TMP21:%.*]] = select <2 x i1> [[TMP17]], <2 x i8> <i8 53, i8 53>, <2 x i8> [[TMP18]] +; CHECK-NEXT: [[TMP22:%.*]] = extractelement <2 x i8> [[TMP21]], i32 0 +; CHECK-NEXT: [[TMP19:%.*]] = zext i8 [[TMP22]] to i32 ; CHECK-NEXT: store i32 [[TMP19]], ptr [[P1]], align 4 -; CHECK-NEXT: [[TMP20:%.*]] = extractelement <2 x i32> [[TMP18]], i32 1 +; CHECK-NEXT: [[TMP24:%.*]] = extractelement <2 x i8> [[TMP21]], i32 1 +; CHECK-NEXT: [[TMP20:%.*]] = zext i8 [[TMP24]] to i32 ; CHECK-NEXT: [[CMP210_NOT:%.*]] = icmp eq i32 [[TMP19]], [[TMP20]] ; CHECK-NEXT: ret i1 [[CMP210_NOT]] ; diff --git a/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-multiuse-with-insertelement.ll b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-multiuse-with-insertelement.ll index 6e512fcbb739..6051638562b5 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-multiuse-with-insertelement.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-multiuse-with-insertelement.ll @@ -6,18 +6,17 @@ define void @test(i8 %0) { ; CHECK-SAME: i8 [[TMP0:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> <i8 0, i8 poison>, i8 [[TMP0]], i32 1 -; CHECK-NEXT: [[TMP2:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i16> -; CHECK-NEXT: [[TMP3:%.*]] = sext <2 x i16> [[TMP2]] to <2 x i32> -; CHECK-NEXT: [[TMP4:%.*]] = mul <2 x i16> [[TMP2]], zeroinitializer -; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i16> [[TMP4]], i32 0 -; CHECK-NEXT: [[TMP6:%.*]] = zext i16 [[TMP5]] to i32 -; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x i16> [[TMP4]], i32 1 -; CHECK-NEXT: [[TMP8:%.*]] = zext i16 [[TMP7]] to i32 -; CHECK-NEXT: [[ADD:%.*]] = or i32 [[TMP6]], [[TMP8]] +; CHECK-NEXT: [[TMP2:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i32> +; CHECK-NEXT: [[TMP3:%.*]] = mul <2 x i8> [[TMP1]], zeroinitializer +; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i8> [[TMP3]], i32 0 +; CHECK-NEXT: [[TMP5:%.*]] = zext i8 [[TMP4]] to i32 +; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i8> [[TMP3]], i32 1 +; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32 +; CHECK-NEXT: [[ADD:%.*]] = or i32 [[TMP5]], [[TMP7]] ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[ADD]], 1 ; CHECK-NEXT: [[CONV9:%.*]] = trunc i32 [[SHR]] to i8 ; CHECK-NEXT: store i8 [[CONV9]], ptr null, align 1 -; CHECK-NEXT: [[TMP9:%.*]] = shufflevector <2 x i32> [[TMP3]], <2 x i32> poison, <8 x i32> <i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> +; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <2 x i32> [[TMP2]], <2 x i32> poison, <8 x i32> <i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> ; CHECK-NEXT: ret void ; entry: diff --git a/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-transformed-operand.ll b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-transformed-operand.ll index 2c834616becc..4acd63078b82 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-transformed-operand.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-transformed-operand.ll @@ -6,15 +6,20 @@ define void @test(i64 %d.promoted.i) { ; CHECK-SAME: i64 [[D_PROMOTED_I:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[AND_1_I:%.*]] = and i64 0, [[D_PROMOTED_I]] +; CHECK-NEXT: [[TMP0:%.*]] = insertelement <8 x i64> <i64 0, i64 poison, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0>, i64 [[AND_1_I]], i32 1 +; CHECK-NEXT: [[TMP1:%.*]] = trunc <8 x i64> [[TMP0]] to <8 x i1> +; CHECK-NEXT: [[TMP2:%.*]] = mul <8 x i1> [[TMP1]], zeroinitializer ; CHECK-NEXT: [[AND_1_I_1:%.*]] = and i64 0, 0 -; CHECK-NEXT: [[TMP0:%.*]] = insertelement <16 x i64> <i64 0, i64 poison, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 poison, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0>, i64 [[AND_1_I_1]], i32 1 -; CHECK-NEXT: [[TMP1:%.*]] = insertelement <16 x i64> [[TMP0]], i64 [[AND_1_I]], i32 9 -; CHECK-NEXT: [[TMP2:%.*]] = trunc <16 x i64> [[TMP1]] to <16 x i1> -; CHECK-NEXT: [[TMP3:%.*]] = mul <16 x i1> [[TMP2]], zeroinitializer -; CHECK-NEXT: [[TMP4:%.*]] = call i1 @llvm.vector.reduce.or.v16i1(<16 x i1> [[TMP3]]) -; CHECK-NEXT: [[TMP5:%.*]] = zext i1 [[TMP4]] to i32 -; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP5]], 0 -; CHECK-NEXT: store i32 [[TMP6]], ptr null, align 4 +; CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i64> <i64 0, i64 poison, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0>, i64 [[AND_1_I_1]], i32 1 +; CHECK-NEXT: [[TMP4:%.*]] = trunc <8 x i64> [[TMP3]] to <8 x i1> +; CHECK-NEXT: [[TMP5:%.*]] = mul <8 x i1> [[TMP4]], zeroinitializer +; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v8i1(<8 x i1> [[TMP5]]) +; CHECK-NEXT: [[TMP7:%.*]] = zext i1 [[TMP6]] to i32 +; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v8i1(<8 x i1> [[TMP2]]) +; CHECK-NEXT: [[TMP9:%.*]] = zext i1 [[TMP8]] to i32 +; CHECK-NEXT: [[OP_RDX:%.*]] = or i32 [[TMP7]], [[TMP9]] +; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[OP_RDX]], 0 +; CHECK-NEXT: store i32 [[TMP10]], ptr null, align 4 ; CHECK-NEXT: ret void ; entry: diff --git a/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-user-not-min.ll b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-user-not-min.ll index 6922df8991b8..50b19d01ad58 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-user-not-min.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-user-not-min.ll @@ -6,10 +6,10 @@ define void @test(ptr %block, ptr noalias %pixels, i1 %b) { ; CHECK-SAME: ptr [[BLOCK:%.*]], ptr noalias [[PIXELS:%.*]], i1 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x i1> <i1 true, i1 poison, i1 false, i1 false>, i1 [[B]], i32 1 -; CHECK-NEXT: [[TMP1:%.*]] = sext <4 x i1> [[TMP0]] to <4 x i8> ; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i16>, ptr [[BLOCK]], align 2 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult <4 x i16> [[TMP2]], zeroinitializer ; CHECK-NEXT: [[TMP4:%.*]] = trunc <4 x i16> [[TMP2]] to <4 x i8> +; CHECK-NEXT: [[TMP1:%.*]] = sext <4 x i1> [[TMP0]] to <4 x i8> ; CHECK-NEXT: [[TMP5:%.*]] = select <4 x i1> [[TMP3]], <4 x i8> [[TMP4]], <4 x i8> [[TMP1]] ; CHECK-NEXT: store <4 x i8> [[TMP5]], ptr [[PIXELS]], align 1 ; CHECK-NEXT: ret void diff --git a/llvm/test/Transforms/SLPVectorizer/X86/minimum-sizes.ll b/llvm/test/Transforms/SLPVectorizer/X86/minimum-sizes.ll index 651631de2c35..a316415dcc6b 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/minimum-sizes.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/minimum-sizes.ll @@ -17,12 +17,15 @@ target triple = "x86_64-unknown-linux-gnu" define i8 @PR31243_zext(i8 %v0, i8 %v1, i8 %v2, i8 %v3, ptr %ptr) { ; SSE-LABEL: @PR31243_zext( ; SSE-NEXT: entry: -; SSE-NEXT: [[TMP0:%.*]] = or i8 [[V0:%.*]], 1 -; SSE-NEXT: [[TMP1:%.*]] = or i8 [[V1:%.*]], 1 -; SSE-NEXT: [[TMP2:%.*]] = zext i8 [[TMP0]] to i64 -; SSE-NEXT: [[T4:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[TMP2]] -; SSE-NEXT: [[TMP3:%.*]] = zext i8 [[TMP1]] to i64 -; SSE-NEXT: [[T5:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[TMP3]] +; SSE-NEXT: [[TMP0:%.*]] = insertelement <2 x i8> poison, i8 [[V0:%.*]], i64 0 +; SSE-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> [[TMP0]], i8 [[V1:%.*]], i64 1 +; SSE-NEXT: [[TMP2:%.*]] = or <2 x i8> [[TMP1]], <i8 1, i8 1> +; SSE-NEXT: [[TMP3:%.*]] = extractelement <2 x i8> [[TMP2]], i64 0 +; SSE-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i64 +; SSE-NEXT: [[T4:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[TMP4]] +; SSE-NEXT: [[TMP5:%.*]] = extractelement <2 x i8> [[TMP2]], i64 1 +; SSE-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i64 +; SSE-NEXT: [[T5:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[TMP6]] ; SSE-NEXT: [[T6:%.*]] = load i8, ptr [[T4]], align 1 ; SSE-NEXT: [[T7:%.*]] = load i8, ptr [[T5]], align 1 ; SSE-NEXT: [[T8:%.*]] = add i8 [[T6]], [[T7]] @@ -73,12 +76,15 @@ entry: define i8 @PR31243_sext(i8 %v0, i8 %v1, i8 %v2, i8 %v3, ptr %ptr) { ; SSE-LABEL: @PR31243_sext( ; SSE-NEXT: entry: -; SSE-NEXT: [[TMP0:%.*]] = or i8 [[V0:%.*]], 1 -; SSE-NEXT: [[TMP1:%.*]] = or i8 [[V1:%.*]], 1 -; SSE-NEXT: [[TMP2:%.*]] = sext i8 [[TMP0]] to i64 -; SSE-NEXT: [[T4:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[TMP2]] -; SSE-NEXT: [[TMP3:%.*]] = sext i8 [[TMP1]] to i64 -; SSE-NEXT: [[T5:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[TMP3]] +; SSE-NEXT: [[TMP0:%.*]] = insertelement <2 x i8> poison, i8 [[V0:%.*]], i64 0 +; SSE-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> [[TMP0]], i8 [[V1:%.*]], i64 1 +; SSE-NEXT: [[TMP2:%.*]] = or <2 x i8> [[TMP1]], <i8 1, i8 1> +; SSE-NEXT: [[TMP3:%.*]] = extractelement <2 x i8> [[TMP2]], i64 0 +; SSE-NEXT: [[TMP4:%.*]] = sext i8 [[TMP3]] to i64 +; SSE-NEXT: [[T4:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[TMP4]] +; SSE-NEXT: [[TMP5:%.*]] = extractelement <2 x i8> [[TMP2]], i64 1 +; SSE-NEXT: [[TMP6:%.*]] = sext i8 [[TMP5]] to i64 +; SSE-NEXT: [[T5:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[TMP6]] ; SSE-NEXT: [[T6:%.*]] = load i8, ptr [[T4]], align 1 ; SSE-NEXT: [[T7:%.*]] = load i8, ptr [[T5]], align 1 ; SSE-NEXT: [[T8:%.*]] = add i8 [[T6]], [[T7]] @@ -89,13 +95,12 @@ define i8 @PR31243_sext(i8 %v0, i8 %v1, i8 %v2, i8 %v3, ptr %ptr) { ; AVX-NEXT: [[TMP0:%.*]] = insertelement <2 x i8> poison, i8 [[V0:%.*]], i64 0 ; AVX-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> [[TMP0]], i8 [[V1:%.*]], i64 1 ; AVX-NEXT: [[TMP2:%.*]] = or <2 x i8> [[TMP1]], <i8 1, i8 1> -; AVX-NEXT: [[TMP3:%.*]] = sext <2 x i8> [[TMP2]] to <2 x i16> -; AVX-NEXT: [[TMP4:%.*]] = extractelement <2 x i16> [[TMP3]], i64 0 -; AVX-NEXT: [[TMP5:%.*]] = sext i16 [[TMP4]] to i64 -; AVX-NEXT: [[T4:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[TMP5]] -; AVX-NEXT: [[TMP6:%.*]] = extractelement <2 x i16> [[TMP3]], i64 1 -; AVX-NEXT: [[TMP7:%.*]] = sext i16 [[TMP6]] to i64 -; AVX-NEXT: [[T5:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[TMP7]] +; AVX-NEXT: [[TMP3:%.*]] = extractelement <2 x i8> [[TMP2]], i64 0 +; AVX-NEXT: [[TMP4:%.*]] = sext i8 [[TMP3]] to i64 +; AVX-NEXT: [[T4:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[TMP4]] +; AVX-NEXT: [[TMP5:%.*]] = extractelement <2 x i8> [[TMP2]], i64 1 +; AVX-NEXT: [[TMP6:%.*]] = sext i8 [[TMP5]] to i64 +; AVX-NEXT: [[T5:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[TMP6]] ; AVX-NEXT: [[T6:%.*]] = load i8, ptr [[T4]], align 1 ; AVX-NEXT: [[T7:%.*]] = load i8, ptr [[T5]], align 1 ; AVX-NEXT: [[T8:%.*]] = add i8 [[T6]], [[T7]] diff --git a/llvm/test/Transforms/SLPVectorizer/X86/phi-undef-input.ll b/llvm/test/Transforms/SLPVectorizer/X86/phi-undef-input.ll index 88f75c37846e..3cc32c1fc7b2 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/phi-undef-input.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/phi-undef-input.ll @@ -15,8 +15,8 @@ define i32 @phi3UndefInput(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 %arg3) { ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 undef, i8 undef, i8 undef>, [[ENTRY:%.*]] ] -; CHECK-NEXT: [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32> -; CHECK-NEXT: [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]]) +; CHECK-NEXT: [[TMP5:%.*]] = call i8 @llvm.vector.reduce.or.v4i8(<4 x i8> [[TMP4]]) +; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 ; CHECK-NEXT: ret i32 [[TMP6]] ; entry: @@ -52,8 +52,8 @@ define i32 @phi2UndefInput(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 %arg3) { ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 0, i8 undef, i8 undef>, [[ENTRY:%.*]] ] -; CHECK-NEXT: [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32> -; CHECK-NEXT: [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]]) +; CHECK-NEXT: [[TMP5:%.*]] = call i8 @llvm.vector.reduce.or.v4i8(<4 x i8> [[TMP4]]) +; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 ; CHECK-NEXT: ret i32 [[TMP6]] ; entry: @@ -89,8 +89,8 @@ define i32 @phi1UndefInput(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 %arg3) { ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 0, i8 0, i8 undef>, [[ENTRY:%.*]] ] -; CHECK-NEXT: [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32> -; CHECK-NEXT: [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]]) +; CHECK-NEXT: [[TMP5:%.*]] = call i8 @llvm.vector.reduce.or.v4i8(<4 x i8> [[TMP4]]) +; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 ; CHECK-NEXT: ret i32 [[TMP6]] ; entry: @@ -127,8 +127,8 @@ define i32 @phi1Undef1PoisonInput(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 %ar ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 0, i8 poison, i8 undef>, [[ENTRY:%.*]] ] -; CHECK-NEXT: [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32> -; CHECK-NEXT: [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]]) +; CHECK-NEXT: [[TMP5:%.*]] = call i8 @llvm.vector.reduce.or.v4i8(<4 x i8> [[TMP4]]) +; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 ; CHECK-NEXT: ret i32 [[TMP6]] ; entry: @@ -165,8 +165,8 @@ define i32 @phi1Undef2PoisonInputs(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 %a ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 poison, i8 poison, i8 undef>, [[ENTRY:%.*]] ] -; CHECK-NEXT: [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32> -; CHECK-NEXT: [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]]) +; CHECK-NEXT: [[TMP5:%.*]] = call i8 @llvm.vector.reduce.or.v4i8(<4 x i8> [[TMP4]]) +; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 ; CHECK-NEXT: ret i32 [[TMP6]] ; entry: @@ -202,8 +202,8 @@ define i32 @phi1Undef1PoisonGapInput(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 0, i8 poison, i8 undef>, [[ENTRY:%.*]] ] -; CHECK-NEXT: [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32> -; CHECK-NEXT: [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]]) +; CHECK-NEXT: [[TMP5:%.*]] = call i8 @llvm.vector.reduce.or.v4i8(<4 x i8> [[TMP4]]) +; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 ; CHECK-NEXT: ret i32 [[TMP6]] ; entry: diff --git a/llvm/test/Transforms/SLPVectorizer/X86/resched.ll b/llvm/test/Transforms/SLPVectorizer/X86/resched.ll index 78c6d9516a3d..b7237cbb02bb 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/resched.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/resched.ll @@ -11,26 +11,26 @@ define fastcc void @_ZN12_GLOBAL__N_127PolynomialMultiplyRecognize9recognizeEv() ; CHECK: if.then22.i: ; CHECK-NEXT: [[SUB_I:%.*]] = add nsw i32 undef, -1 ; CHECK-NEXT: [[CONV31_I:%.*]] = and i32 undef, [[SUB_I]] -; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i32> poison, i32 [[CONV31_I]], i32 0 -; CHECK-NEXT: [[SHUFFLE1:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: [[TMP2:%.*]] = lshr <4 x i32> [[SHUFFLE1]], <i32 1, i32 2, i32 3, i32 4> +; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x i32> poison, i32 [[CONV31_I]], i32 0 +; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[TMP0]], <4 x i32> poison, <4 x i32> zeroinitializer +; CHECK-NEXT: [[TMP2:%.*]] = lshr <4 x i32> [[TMP1]], <i32 1, i32 2, i32 3, i32 4> ; CHECK-NEXT: [[SHR_4_I_I:%.*]] = lshr i32 [[CONV31_I]], 5 ; CHECK-NEXT: [[SHR_5_I_I:%.*]] = lshr i32 [[CONV31_I]], 6 ; CHECK-NEXT: [[SHR_6_I_I:%.*]] = lshr i32 [[CONV31_I]], 7 ; CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i32> poison, i32 [[CONV31_I]], i32 0 -; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <8 x i32> [[TMP3]], <8 x i32> poison, <8 x i32> zeroinitializer -; CHECK-NEXT: [[TMP4:%.*]] = lshr <8 x i32> [[SHUFFLE]], <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> -; CHECK-NEXT: [[TMP5:%.*]] = insertelement <16 x i32> poison, i32 [[SUB_I]], i32 0 -; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <4 x i32> [[TMP2]], <4 x i32> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> -; CHECK-NEXT: [[TMP7:%.*]] = shufflevector <16 x i32> [[TMP5]], <16 x i32> [[TMP6]], <16 x i32> <i32 0, i32 16, i32 17, i32 18, i32 19, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> -; CHECK-NEXT: [[TMP8:%.*]] = insertelement <16 x i32> [[TMP7]], i32 [[SHR_4_I_I]], i32 5 -; CHECK-NEXT: [[TMP9:%.*]] = insertelement <16 x i32> [[TMP8]], i32 [[SHR_5_I_I]], i32 6 -; CHECK-NEXT: [[TMP10:%.*]] = insertelement <16 x i32> [[TMP9]], i32 [[SHR_6_I_I]], i32 7 -; CHECK-NEXT: [[TMP11:%.*]] = shufflevector <8 x i32> [[TMP4]], <8 x i32> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> -; CHECK-NEXT: [[TMP12:%.*]] = shufflevector <16 x i32> [[TMP10]], <16 x i32> [[TMP11]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23> -; CHECK-NEXT: [[TMP13:%.*]] = trunc <16 x i32> [[TMP12]] to <16 x i8> -; CHECK-NEXT: [[TMP14:%.*]] = and <16 x i8> [[TMP13]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> -; CHECK-NEXT: store <16 x i8> [[TMP14]], ptr undef, align 1 +; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <8 x i32> [[TMP3]], <8 x i32> poison, <8 x i32> zeroinitializer +; CHECK-NEXT: [[TMP5:%.*]] = lshr <8 x i32> [[TMP4]], <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <16 x i32> poison, i32 [[SUB_I]], i32 0 +; CHECK-NEXT: [[TMP7:%.*]] = shufflevector <4 x i32> [[TMP2]], <4 x i32> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> +; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <16 x i32> [[TMP6]], <16 x i32> [[TMP7]], <16 x i32> <i32 0, i32 16, i32 17, i32 18, i32 19, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> +; CHECK-NEXT: [[TMP9:%.*]] = insertelement <16 x i32> [[TMP8]], i32 [[SHR_4_I_I]], i32 5 +; CHECK-NEXT: [[TMP10:%.*]] = insertelement <16 x i32> [[TMP9]], i32 [[SHR_5_I_I]], i32 6 +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <16 x i32> [[TMP10]], i32 [[SHR_6_I_I]], i32 7 +; CHECK-NEXT: [[TMP12:%.*]] = shufflevector <8 x i32> [[TMP5]], <8 x i32> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> +; CHECK-NEXT: [[TMP13:%.*]] = shufflevector <16 x i32> [[TMP11]], <16 x i32> [[TMP12]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23> +; CHECK-NEXT: [[TMP14:%.*]] = trunc <16 x i32> [[TMP13]] to <16 x i8> +; CHECK-NEXT: [[TMP15:%.*]] = and <16 x i8> [[TMP14]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> +; CHECK-NEXT: store <16 x i8> [[TMP15]], ptr undef, align 1 ; CHECK-NEXT: unreachable ; CHECK: if.end50.i: ; CHECK-NEXT: ret void diff --git a/llvm/test/Transforms/SLPVectorizer/X86/reused-reductions-with-minbitwidth.ll b/llvm/test/Transforms/SLPVectorizer/X86/reused-reductions-with-minbitwidth.ll index 5d22b5a4873b..1d1fcec2a7ae 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/reused-reductions-with-minbitwidth.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/reused-reductions-with-minbitwidth.ll @@ -7,12 +7,10 @@ define i1 @test(i1 %cmp5.not.31) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x i1> <i1 poison, i1 false, i1 false, i1 false>, i1 [[CMP5_NOT_31]], i32 0 ; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> zeroinitializer, <4 x i32> zeroinitializer -; CHECK-NEXT: [[TMP2:%.*]] = trunc <4 x i32> [[TMP1]] to <4 x i1> -; CHECK-NEXT: [[TMP3:%.*]] = zext <4 x i1> [[TMP2]] to <4 x i32> -; CHECK-NEXT: [[TMP4:%.*]] = mul <4 x i32> [[TMP3]], <i32 2, i32 1, i32 1, i32 1> -; CHECK-NEXT: [[TMP5:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP4]]) -; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP5]], 0 -; CHECK-NEXT: [[CMP_NOT_I_I:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: [[TMP2:%.*]] = mul <4 x i32> [[TMP1]], <i32 2, i32 1, i32 1, i32 1> +; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP2]]) +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 0 +; CHECK-NEXT: [[CMP_NOT_I_I:%.*]] = icmp eq i32 [[TMP4]], 0 ; CHECK-NEXT: ret i1 [[CMP_NOT_I_I]] ; entry: diff --git a/llvm/test/Transforms/SLPVectorizer/X86/same-scalar-in-same-phi-extract.ll b/llvm/test/Transforms/SLPVectorizer/X86/same-scalar-in-same-phi-extract.ll index 35f2f9e052e7..f1be11d0d0fc 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/same-scalar-in-same-phi-extract.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/same-scalar-in-same-phi-extract.ll @@ -23,10 +23,11 @@ define void @test(i32 %arg) { ; CHECK-NEXT: ] ; CHECK: bb4: ; CHECK-NEXT: [[TMP3:%.*]] = phi <2 x i32> [ [[TMP0]], [[BB2]] ] -; CHECK-NEXT: [[TMP4:%.*]] = zext <2 x i32> [[TMP3]] to <2 x i64> -; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i64> [[TMP4]], i32 0 +; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i32> [[TMP3]], i32 0 +; CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64 ; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr i32, ptr null, i64 [[TMP5]] -; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i64> [[TMP4]], i32 1 +; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x i32> [[TMP3]], i32 1 +; CHECK-NEXT: [[TMP6:%.*]] = zext i32 [[TMP7]] to i64 ; CHECK-NEXT: [[GETELEMENTPTR6:%.*]] = getelementptr i32, ptr null, i64 [[TMP6]] ; CHECK-NEXT: ret void ; CHECK: bb7: diff --git a/llvm/test/Transforms/SLPVectorizer/X86/store-insertelement-minbitwidth.ll b/llvm/test/Transforms/SLPVectorizer/X86/store-insertelement-minbitwidth.ll index c1dd90d0e9a7..2f6868d8dfd6 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/store-insertelement-minbitwidth.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/store-insertelement-minbitwidth.ll @@ -8,17 +8,18 @@ ; YAML-NEXT: Function: stores ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'Stores SLP vectorized with cost ' -; YAML-NEXT: - Cost: '-3' +; YAML-NEXT: - Cost: '-7' ; YAML-NEXT: - String: ' and with tree size ' ; YAML-NEXT: - TreeSize: '6' define void @stores(ptr noalias %in, ptr noalias %inn, ptr noalias %out) { ; CHECK-LABEL: @stores( ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[IN:%.*]], align 1 ; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i8>, ptr [[INN:%.*]], align 1 -; CHECK-NEXT: [[TMP3:%.*]] = zext <4 x i8> [[TMP1]] to <4 x i64> -; CHECK-NEXT: [[TMP4:%.*]] = zext <4 x i8> [[TMP2]] to <4 x i64> -; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i64> [[TMP3]], [[TMP4]] -; CHECK-NEXT: store <4 x i64> [[TMP5]], ptr [[OUT:%.*]], align 4 +; CHECK-NEXT: [[TMP3:%.*]] = zext <4 x i8> [[TMP1]] to <4 x i16> +; CHECK-NEXT: [[TMP4:%.*]] = zext <4 x i8> [[TMP2]] to <4 x i16> +; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i16> [[TMP3]], [[TMP4]] +; CHECK-NEXT: [[TMP6:%.*]] = zext <4 x i16> [[TMP5]] to <4 x i64> +; CHECK-NEXT: store <4 x i64> [[TMP6]], ptr [[OUT:%.*]], align 4 ; CHECK-NEXT: ret void ; %load.1 = load i8, ptr %in, align 1 @@ -63,17 +64,18 @@ define void @stores(ptr noalias %in, ptr noalias %inn, ptr noalias %out) { ; YAML-NEXT: Function: insertelems ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'SLP vectorized with cost ' -; YAML-NEXT: - Cost: '-5' +; YAML-NEXT: - Cost: '-9' ; YAML-NEXT: - String: ' and with tree size ' ; YAML-NEXT: - TreeSize: '6' define <4 x i64> @insertelems(ptr noalias %in, ptr noalias %inn) { ; CHECK-LABEL: @insertelems( ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[IN:%.*]], align 1 ; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i8>, ptr [[INN:%.*]], align 1 -; CHECK-NEXT: [[TMP3:%.*]] = zext <4 x i8> [[TMP1]] to <4 x i64> -; CHECK-NEXT: [[TMP4:%.*]] = zext <4 x i8> [[TMP2]] to <4 x i64> -; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i64> [[TMP3]], [[TMP4]] -; CHECK-NEXT: ret <4 x i64> [[TMP5]] +; CHECK-NEXT: [[TMP3:%.*]] = zext <4 x i8> [[TMP1]] to <4 x i16> +; CHECK-NEXT: [[TMP4:%.*]] = zext <4 x i8> [[TMP2]] to <4 x i16> +; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i16> [[TMP3]], [[TMP4]] +; CHECK-NEXT: [[TMP6:%.*]] = zext <4 x i16> [[TMP5]] to <4 x i64> +; CHECK-NEXT: ret <4 x i64> [[TMP6]] ; %load.1 = load i8, ptr %in, align 1 %gep.1 = getelementptr inbounds i8, ptr %in, i64 1 diff --git a/llvm/test/Transforms/SLPVectorizer/alt-cmp-vectorize.ll b/llvm/test/Transforms/SLPVectorizer/alt-cmp-vectorize.ll index 061fbdb45a13..ff6f0bdd3db8 100644 --- a/llvm/test/Transforms/SLPVectorizer/alt-cmp-vectorize.ll +++ b/llvm/test/Transforms/SLPVectorizer/alt-cmp-vectorize.ll @@ -10,8 +10,8 @@ define i32 @alt_cmp(i16 %call46) { ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <4 x i16> [[TMP0]], [[TMP1]] ; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt <4 x i16> [[TMP0]], [[TMP1]] ; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <4 x i1> [[TMP2]], <4 x i1> [[TMP3]], <4 x i32> <i32 0, i32 5, i32 2, i32 3> -; CHECK-NEXT: [[TMP5:%.*]] = zext <4 x i1> [[TMP4]] to <4 x i16> -; CHECK-NEXT: [[TMP6:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[TMP5]]) +; CHECK-NEXT: [[TMP5:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP4]]) +; CHECK-NEXT: [[TMP6:%.*]] = zext i1 [[TMP5]] to i16 ; CHECK-NEXT: [[OP_RDX:%.*]] = or i16 [[TMP6]], 0 ; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[OP_RDX]] to i32 ; CHECK-NEXT: ret i32 [[EXT]] -- GitLab From 43a2ec483fe08064b53a6293682e9bab97df61a0 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jonas@devlieghere.com> Date: Tue, 19 Mar 2024 08:30:47 -0700 Subject: [PATCH 095/307] [dsymutil] Remove support for obfuscated bitcode (#85713) Remove support for obfuscated bitcode in dsymutil and the DWARF linker. We no longer support bitcode submissions and the obfuscation support has been removed from the rest of the compiler. rdar://123863918 --- llvm/docs/CommandGuide/dsymutil.rst | 4 - .../llvm/CodeGen/NonRelocatableStringpool.h | 6 +- .../llvm/DWARFLinker/Classic/DWARFStreamer.h | 8 +- .../llvm/DWARFLinker/DWARFLinkerBase.h | 1 - .../llvm/DWARFLinker/Parallel/DWARFLinker.h | 3 +- llvm/lib/CodeGen/NonRelocatableStringpool.cpp | 5 - llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 4 +- .../lib/DWARFLinker/Classic/DWARFStreamer.cpp | 12 +- llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp | 6 +- .../Parallel/DWARFLinkerGlobalData.h | 15 -- .../DWARFLinker/Parallel/DWARFLinkerImpl.cpp | 4 +- .../DWARFLinker/Parallel/DWARFLinkerImpl.h | 3 +- .../lib/DWARFLinker/Parallel/OutputSections.h | 2 +- .../StringEntryToDwarfStringPoolEntryMap.h | 2 +- llvm/test/tools/dsymutil/ARM/obfuscated.test | 200 ------------------ .../tools/dsymutil/Inputs/obfuscated.2.arm64 | Bin 10339 -> 0 bytes .../tools/dsymutil/Inputs/obfuscated.2.map | 22 -- .../tools/dsymutil/Inputs/obfuscated.arm64 | Bin 10434 -> 0 bytes .../test/tools/dsymutil/Inputs/obfuscated.map | 17 -- llvm/test/tools/dsymutil/cmdline.test | 1 - llvm/tools/dsymutil/CMakeLists.txt | 1 - llvm/tools/dsymutil/DwarfLinkerForBinary.cpp | 14 +- llvm/tools/dsymutil/LinkUtils.h | 5 - llvm/tools/dsymutil/MachOUtils.cpp | 7 +- llvm/tools/dsymutil/MachOUtils.h | 4 +- llvm/tools/dsymutil/Options.td | 6 - llvm/tools/dsymutil/SymbolMap.cpp | 157 -------------- llvm/tools/dsymutil/SymbolMap.h | 53 ----- llvm/tools/dsymutil/dsymutil.cpp | 15 +- llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp | 6 +- 30 files changed, 28 insertions(+), 555 deletions(-) delete mode 100644 llvm/test/tools/dsymutil/ARM/obfuscated.test delete mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.2.arm64 delete mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.2.map delete mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.arm64 delete mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.map delete mode 100644 llvm/tools/dsymutil/SymbolMap.cpp delete mode 100644 llvm/tools/dsymutil/SymbolMap.h diff --git a/llvm/docs/CommandGuide/dsymutil.rst b/llvm/docs/CommandGuide/dsymutil.rst index af9d7f16b361..e3f2f33224b0 100644 --- a/llvm/docs/CommandGuide/dsymutil.rst +++ b/llvm/docs/CommandGuide/dsymutil.rst @@ -140,10 +140,6 @@ OPTIONS (in bytes) to the linked dSYM. The table is sorted by the output size listing the object files with the largest contribution first. -.. option:: --symbol-map <bcsymbolmap> - - Update the existing dSYMs inplace using symbol map specified. - .. option:: -s, --symtab Dumps the symbol table found in *executable* or object file(s) and exits. diff --git a/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h b/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h index 3dc0731f5a04..4b8eed7bdb1b 100644 --- a/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h +++ b/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h @@ -27,10 +27,7 @@ public: /// order. using MapTy = StringMap<DwarfStringPoolEntry, BumpPtrAllocator>; - NonRelocatableStringpool( - std::function<StringRef(StringRef Input)> Translator = nullptr, - bool PutEmptyString = false) - : Translator(Translator) { + NonRelocatableStringpool(bool PutEmptyString = false) { if (PutEmptyString) getEntry(""); } @@ -59,7 +56,6 @@ private: MapTy Strings; uint64_t CurrentEndOffset = 0; unsigned NumEntries = 0; - std::function<StringRef(StringRef Input)> Translator; }; /// Helper for making strong types. diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h index bebdfd5e6025..e7a1a3cd838c 100644 --- a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h +++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h @@ -45,16 +45,13 @@ class DwarfStreamer : public DwarfEmitter { public: DwarfStreamer(DWARFLinkerBase::OutputFileType OutFileType, raw_pwrite_stream &OutFile, - DWARFLinkerBase::TranslatorFuncTy Translator, DWARFLinkerBase::MessageHandlerTy Warning) - : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator), - WarningHandler(Warning) {} + : OutFile(OutFile), OutFileType(OutFileType), WarningHandler(Warning) {} virtual ~DwarfStreamer() = default; static Expected<std::unique_ptr<DwarfStreamer>> createStreamer( const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType, - raw_pwrite_stream &OutFile, DWARFLinkerBase::TranslatorFuncTy Translator, - DWARFLinkerBase::MessageHandlerTy Warning); + raw_pwrite_stream &OutFile, DWARFLinkerBase::MessageHandlerTy Warning); Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName); @@ -295,7 +292,6 @@ private: /// The output file we stream the linked Dwarf to. raw_pwrite_stream &OutFile; DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object; - std::function<StringRef(StringRef Input)> Translator; uint64_t RangesSectionSize = 0; uint64_t RngListsSectionSize = 0; diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h index 5c811b668f0a..70b25cf02df7 100644 --- a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h +++ b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h @@ -82,7 +82,6 @@ public: std::function<void(const DWARFFile &File, llvm::StringRef Output)>; using ObjectPrefixMapTy = std::map<std::string, std::string>; using CompileUnitHandlerTy = function_ref<void(const DWARFUnit &Unit)>; - using TranslatorFuncTy = std::function<StringRef(StringRef)>; using SwiftInterfacesMapTy = std::map<std::string, std::string>; /// Type of output file. enum class OutputFileType : uint8_t { diff --git a/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h index 5312712a4a5b..8acc046d0724 100644 --- a/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h @@ -123,8 +123,7 @@ public: /// Creates dwarf linker instance. static std::unique_ptr<DWARFLinker> - createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler, - TranslatorFuncTy StringsTranslator = nullptr); + createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler); /// Set output DWARF handler. Result of linking DWARF is set of sections /// containing final debug info. DWARFLinkerBase::link() pass generated diff --git a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp index e8391afb8e3f..26857c6a4088 100644 --- a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp +++ b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp @@ -12,8 +12,6 @@ namespace llvm { DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) { - if (Translator) - S = Translator(S); auto I = Strings.insert({S, DwarfStringPoolEntry()}); auto &Entry = I.first->second; if (I.second || !Entry.isIndexed()) { @@ -28,9 +26,6 @@ DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) { StringRef NonRelocatableStringpool::internString(StringRef S) { DwarfStringPoolEntry Entry{nullptr, 0, DwarfStringPoolEntry::NotIndexed}; - if (Translator) - S = Translator(S); - auto InsertResult = Strings.insert({S, Entry}); return InsertResult.first->getKey(); } diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp index 9b581a6c9ab7..60f664ece7ee 100644 --- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp @@ -2701,8 +2701,8 @@ Error DWARFLinker::link() { // This Dwarf string pool which is used for emission. It must be used // serially as the order of calling getStringOffset matters for // reproducibility. - OffsetsStringPool DebugStrPool(StringsTranslator, true); - OffsetsStringPool DebugLineStrPool(StringsTranslator, false); + OffsetsStringPool DebugStrPool(true); + OffsetsStringPool DebugLineStrPool(false); DebugDieValuePool StringOffsetPool; // ODR Contexts for the optimize. diff --git a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp index 6d522370e440..8b31b5ead29a 100644 --- a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp +++ b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp @@ -32,10 +32,9 @@ using namespace dwarf_linker::classic; Expected<std::unique_ptr<DwarfStreamer>> DwarfStreamer::createStreamer( const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType, - raw_pwrite_stream &OutFile, DWARFLinkerBase::TranslatorFuncTy Translator, - DWARFLinkerBase::MessageHandlerTy Warning) { + raw_pwrite_stream &OutFile, DWARFLinkerBase::MessageHandlerTy Warning) { std::unique_ptr<DwarfStreamer> Streamer = - std::make_unique<DwarfStreamer>(FileType, OutFile, Translator, Warning); + std::make_unique<DwarfStreamer>(FileType, OutFile, Warning); if (Error Err = Streamer->init(TheTriple, "__DWARF")) return std::move(Err); @@ -977,11 +976,10 @@ void DwarfStreamer::emitLineTableString(const DWARFDebugLine::Prologue &P, switch (String.getForm()) { case dwarf::DW_FORM_string: { - StringRef TranslatedString = - (Translator) ? Translator(*StringVal) : *StringVal; - Asm->OutStreamer->emitBytes(TranslatedString.data()); + StringRef Str = *StringVal; + Asm->OutStreamer->emitBytes(Str.data()); Asm->emitInt8(0); - LineSectionSize += TranslatedString.size() + 1; + LineSectionSize += Str.size() + 1; } break; case dwarf::DW_FORM_strp: case dwarf::DW_FORM_line_strp: { diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp index ad8d28a64317..31c7e867767a 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp @@ -15,8 +15,6 @@ using namespace dwarf_linker::parallel; std::unique_ptr<DWARFLinker> DWARFLinker::createLinker(MessageHandlerTy ErrorHandler, - MessageHandlerTy WarningHandler, - TranslatorFuncTy StringsTranslator) { - return std::make_unique<DWARFLinkerImpl>(ErrorHandler, WarningHandler, - StringsTranslator); + MessageHandlerTy WarningHandler) { + return std::make_unique<DWARFLinkerImpl>(ErrorHandler, WarningHandler); } diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h index 38c261a8106f..7ca81eb34f00 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h @@ -21,7 +21,6 @@ class DWARFDie; namespace dwarf_linker { namespace parallel { -using TranslatorFuncTy = std::function<StringRef(StringRef)>; using MessageHandlerTy = std::function<void( const Twine &Warning, StringRef Context, const DWARFDie *DIE)>; @@ -95,19 +94,6 @@ public: /// Returns global string pool. StringPool &getStringPool() { return Strings; } - /// Set translation function. - void setTranslator(TranslatorFuncTy Translator) { - this->Translator = Translator; - } - - /// Translate specified string. - StringRef translateString(StringRef String) { - if (Translator) - return Translator(String); - - return String; - } - /// Returns linking options. const DWARFLinkerOptions &getOptions() const { return Options; } @@ -161,7 +147,6 @@ public: protected: llvm::parallel::PerThreadBumpPtrAllocator Allocator; StringPool Strings; - TranslatorFuncTy Translator; DWARFLinkerOptions Options; MessageHandlerTy WarningHandler; MessageHandlerTy ErrorHandler; diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp index 49b08997eb9c..e68bf0c227a0 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp @@ -20,11 +20,9 @@ using namespace dwarf_linker; using namespace dwarf_linker::parallel; DWARFLinkerImpl::DWARFLinkerImpl(MessageHandlerTy ErrorHandler, - MessageHandlerTy WarningHandler, - TranslatorFuncTy StringsTranslator) + MessageHandlerTy WarningHandler) : UniqueUnitID(0), DebugStrStrings(GlobalData), DebugLineStrStrings(GlobalData), CommonSections(GlobalData) { - GlobalData.setTranslator(StringsTranslator); GlobalData.setErrorHandler(ErrorHandler); GlobalData.setWarningHandler(WarningHandler); } diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h index 7c17c5b79c7c..597bb1b4da59 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h @@ -26,8 +26,7 @@ namespace parallel { class DWARFLinkerImpl : public DWARFLinker { public: DWARFLinkerImpl(MessageHandlerTy ErrorHandler, - MessageHandlerTy WarningHandler, - TranslatorFuncTy StringsTranslator); + MessageHandlerTy WarningHandler); /// Add object file to be linked. Pre-load compile unit die. Call /// \p OnCUDieLoaded for each compile unit die. If specified \p File diff --git a/llvm/lib/DWARFLinker/Parallel/OutputSections.h b/llvm/lib/DWARFLinker/Parallel/OutputSections.h index a21e4b2b75a5..0e1f2dae54bc 100644 --- a/llvm/lib/DWARFLinker/Parallel/OutputSections.h +++ b/llvm/lib/DWARFLinker/Parallel/OutputSections.h @@ -253,7 +253,7 @@ struct SectionDescriptor : SectionDescriptorBase { /// Emit specified inplace string value into the current section contents. void emitInplaceString(StringRef String) { - OS << GlobalData.translateString(String); + OS << String; emitIntVal(0, 1); } diff --git a/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h b/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h index 858f224777db..f67536ef7a1a 100644 --- a/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h +++ b/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h @@ -33,7 +33,7 @@ public: DwarfStringPoolEntryWithExtString *DataPtr = GlobalData.getAllocator() .Allocate<DwarfStringPoolEntryWithExtString>(); - DataPtr->String = GlobalData.translateString(String->getKey()); + DataPtr->String = String->getKey(); DataPtr->Index = DwarfStringPoolEntry::NotIndexed; DataPtr->Offset = 0; DataPtr->Symbol = nullptr; diff --git a/llvm/test/tools/dsymutil/ARM/obfuscated.test b/llvm/test/tools/dsymutil/ARM/obfuscated.test deleted file mode 100644 index 3443b8e63469..000000000000 --- a/llvm/test/tools/dsymutil/ARM/obfuscated.test +++ /dev/null @@ -1,200 +0,0 @@ -REQUIRES: system-darwin - -RUN: dsymutil --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck %s - -RUN: dsymutil --accelerator=Pub --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=PUB %s - -RUN: dsymutil --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=NOHIDDEN %s - -RUN: dsymutil --symbol-map %p/../Inputs/obfuscated.2.map %p/../Inputs/obfuscated.2.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=NOHIDDEN %s - -// Run with plist and make sure dsymutil finds it. -RUN: mkdir -p %t.dSYM/Contents/Resources/DWARF/ -RUN: mkdir -p %t.mapdir -RUN: cp %p/../Inputs/obfuscated.arm64 %t.dSYM/Contents/Resources/DWARF/ -RUN: cp %p/../Inputs/E828A486-8433-3A5E-B6DB-A6294D28133D.plist %t.dSYM/Contents/Resources/ -RUN: cp %p/../Inputs/obfuscated.map %t.mapdir/506AA50A-6B26-3B37-86D2-DC6EBD57B720.bcsymbolmap -RUN: dsymutil --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=OBFUSCATING %s - -// Run without plist and make sure dsymutil doesn't crash. -RUN: rm %t.dSYM/Contents/Resources/E828A486-8433-3A5E-B6DB-A6294D28133D.plist -RUN: dsymutil --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=NOTOBFUSCATING %s - -// ---------------------------------------- -// Repeat the same steps for --linker parallel. -RUN: dsymutil --linker parallel --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck %s - -RUN: dsymutil --linker parallel --accelerator=Pub --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=PUB %s - -RUN: dsymutil --linker parallel --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=NOHIDDEN %s - -RUN: dsymutil --linker parallel --symbol-map %p/../Inputs/obfuscated.2.map %p/../Inputs/obfuscated.2.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=NOHIDDEN %s - -// Run with plist and make sure dsymutil finds it. -RUN: mkdir -p %t.dSYM/Contents/Resources/DWARF/ -RUN: mkdir -p %t.mapdir -RUN: cp %p/../Inputs/obfuscated.arm64 %t.dSYM/Contents/Resources/DWARF/ -RUN: cp %p/../Inputs/E828A486-8433-3A5E-B6DB-A6294D28133D.plist %t.dSYM/Contents/Resources/ -RUN: cp %p/../Inputs/obfuscated.map %t.mapdir/506AA50A-6B26-3B37-86D2-DC6EBD57B720.bcsymbolmap -RUN: dsymutil --linker parallel --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=OBFUSCATING %s - -// Run without plist and make sure dsymutil doesn't crash. -RUN: rm %t.dSYM/Contents/Resources/E828A486-8433-3A5E-B6DB-A6294D28133D.plist -RUN: dsymutil --linker parallel --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=NOTOBFUSCATING %s - -OBFUSCATING-NOT: not unobfuscating - -NOTOBFUSCATING: not unobfuscating - -NOHIDDEN-NOT: __hidden# - -CHECK: .debug_info contents: - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "main.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "main") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "one.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "one") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "two.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "two") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "three.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "three") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "four.c") -CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x0000011e) -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "four") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "five.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "five") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "six.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "six") - -CHECK: .debug_line contents: -CHECK: file_names[ 1]: -CHECK: name: "main.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "one.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "two.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "three.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "four.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "five.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "six.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 - -PUB: .debug_pubnames contents: -PUB: length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000000, unit_size = 0x00000044 -PUB: 0x0000002e "main" -PUB: length = 0x00000016, format = DWARF32, version = 0x0002, unit_offset = 0x00000044, unit_size = 0x00000044 -PUB: 0x0000002e "one" -PUB: length = 0x00000016, format = DWARF32, version = 0x0002, unit_offset = 0x00000088, unit_size = 0x00000044 -PUB: 0x0000002e "two" -PUB: length = 0x00000018, format = DWARF32, version = 0x0002, unit_offset = 0x000000cc, unit_size = 0x00000044 -PUB: 0x0000002e "three" -PUB: length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000110, unit_size = 0x00000044 -PUB: 0x0000002e "four" -PUB: length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000154, unit_size = 0x00000044 -PUB: 0x0000002e "five" -PUB: length = 0x00000016, format = DWARF32, version = 0x0002, unit_offset = 0x00000198, unit_size = 0x00000044 -PUB: 0x0000002e "six" - -CHECK: .apple_names contents: - -CHECK: String: 0x00000091 "five" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x00000182 -CHECK-NEXT: ] -CHECK: String: 0x0000009c "six" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x000001c6 -CHECK-NEXT: ] -CHECK: String: 0x00000078 "three" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x000000fa -CHECK-NEXT: ] -CHECK: String: 0x0000006c "two" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x000000b6 -CHECK-NEXT: ] -CHECK: String: 0x00000057 "main" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x0000002e -CHECK-NEXT: ] -CHECK: String: 0x00000085 "four" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x0000013e -CHECK-NEXT: ] -CHECK: String: 0x00000062 "one" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x00000072 -CHECK-NEXT: ] diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.2.arm64 b/llvm/test/tools/dsymutil/Inputs/obfuscated.2.arm64 deleted file mode 100644 index b40e023eb4916cca1fe38388ce12b030c1a51eda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10339 zcmeHNO>A355Pr|jbJ8?*5>i!-f<mAz6jY#YY4{1ESZN@6<tGY(0s^i4^GIAdwy_;Z zq^hw{4hSwtRDxcRkjjA*qUxdT1rCS{pk6q@k)K1Qs1nFGkODJrXV%aAY$v(Gjx>Hd zv$NmM&dzSK``(SeZf*8imTdv`0(S%7jG-iH1Rnc=cYk|r@Y9)zKR<l-yUomzmu^K! zZw**h50q>0Ov7^+cp6xU+2qqxuTIT94}wO1XPQnI5$7i`6k>kr<@x4XzkRJ)$C3jD zX4DB$^;W7}8^-(Nyd3<6hKYq^Q`BYER2d3FRI1DAic;zRt*=Quh^eCBczXzs>m{C8 z^ztRI3@voL4+!s|LbJB;FH@<ObA<)6*YU0pURMAwSZo?QR0y$Lcsp0fid^B1qAxek z$5q0^IcL%_SdUMf*PFmXoJ!6oQA1RtBz%$;&Ce)^$c!z-LNPF{ZSf#26=8cOO!45n z2$4^T%IZ?Om=~pLIfOS*llGYFOhG(cH$l0v4xX8L?)22DnR#mUwKh(2@K>rvpMriN z&LRLqyv`)&o+2xJ*wT&%I3}wy<RJTlYZ^(2te0M15cyoelX7dkI(I&XR_%%LQsq=( z!K;M)tJ~7QS;DK|*&YjP7_YRPE~J*ciay@SsKl!i%;bUX;ZfR#{2T9*c)yW<<G}^i z0-F6xrPF2at?+yd$0Xie)OPsp79ar?<H2I}wfcA`2=9ApGqELJs#MB*!Vey_(eb*w zrGLK@UiUpzX!8&vfLBUobi571<FIXP6R)~jf@}%<*WV-kJ4*iaA8z9qsoB3``fLVO zx_>7LkNrEj1zzXgOs$E4iGYcKiGYcKiGYc~e<uQXo*K2~Ap-vu-sj7f#pmMNNq&va zdH0f>C3&3WJjs(JS4o~F`5eiwgWL}t&6AA(xh*XUZ^g?jS3Nifr?PMk7E7sI0cylz zE}QiV2abw>kO&ILg2M5j@DK<^dDwwI4Veg-2$%?%2$%?%2$%?%2$%?%2$%?%2$%@` zpCf=TPa+n+wX*HM<9py2UflVwAZ<8u)A9RZAw#q)!q)=PUfUVytvmZ;?>PHhXUug* zUFSa6IqW*eT_@o>kGsxet`m)&u1EF)=o5Z7_|C3FHwifA`?M><*8@XNw09`dvuy;p z4j=@+u-GXATpJJqUvcadVO$~brN~YZ9#IH<jj}_8V~t4i#Y+R>2#gP}edLE5jjNul zuM7W3`zdA5a}#_O9&9D;-&6KH6P@jED0_~3XZyX7rqY6=+}ZvWWzR9~Z2yU}=Loj5 z9|g~4JTXQO0;`2XsUR(|He~Uroa#G#42)UGA_4bZNYVtu6gGj2uZ9UmCTwydXoA5A zo6s_s9pU)HCgg4sdZQHbw~Ib&kMDr|zQg8Sf-^;J8>~2l)?ttYXcvI-qX(O9IepZg zzzW<`T7bBq{T$c_VO!3rh^{!(8U)wE27_>8PPB-wc(XOgc~IXEVe~!W#?>`{ceNtA z;{DbjAA`EcAl&#IgXoIST7z5$^_L97jn^4OSA2ya_Mm+z4x2`NAT|>JWvy?}z6}5( z4_H`;#?eHj`3bytZTziJW!T458J2=7<3_IpNGVlL_}96Fgo)p%!RuV^BjI24vRM;y z(3M26{{&>W0>J%I2?_9E`i0~)4A1}k4L_af!|?&3&bIJlA(`+|cy<9h!2bYYP50av z2VY#dc>OFqM^-Oh{|L%Mz&``yCrazU7l1DTUjhCG_(xz|1c;A21`=iw%9|(vVSb~G z7)UrRDF1*zK$tLCoFo}j8H?9|kuVofewXTbj3kD}h~v?1@Y6pe95cot3L|%{-B618 L<Jax=xFP1h4!zc3 diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.2.map b/llvm/test/tools/dsymutil/Inputs/obfuscated.2.map deleted file mode 100644 index 6efca5960311..000000000000 --- a/llvm/test/tools/dsymutil/Inputs/obfuscated.2.map +++ /dev/null @@ -1,22 +0,0 @@ -BCSymbolMap Version: 2.0 -_two -_three -_four -_five -_six -LLVM version 3.9.0 (ssh://git@stash.sd.apple.com/devtools/clang.git c74ae34bd917b77f9c848bd599dfde2813fb509f) -main -main.c -/Volumes/Data/dev/BitcodeBuildTests/unit -one -one.c -two -two.c -three -three.c -four -four.c -five -five.c -six -six.c diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.arm64 b/llvm/test/tools/dsymutil/Inputs/obfuscated.arm64 deleted file mode 100644 index 8395798be17ff1aaea4397cd38c2b0f26f465cb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10434 zcmeHNO>7%Q6y9BDoiv0rZ4nA8Y649lMW~7i2~a^5LqhWdC4@*Igc#ZJCUNE1R_s7p zA&5+bdV>Q8Bv4Ng;({twRaJ4K2sjmS;edc6sv;z~lv6>J@9n&|S&uhq(j)AXo@d^h zZ@!&*GduP^@Ao%;|EJBeYzxu~ZH8_n$<lHVMJIHlZ~eWsfn%><`uWo%&-Wd8%3;6N zVOcGxucADK@*e0IRH>=-iP2X_r(b|!h<`D|XPU(GBY;ZHjJ`5c-|F{Yt@nxLq9RH@ zrK;XaRazVQF2AiOe{~aL(cA)QvQ~pSDoRzV%h^icGRL>}j^;y50}0Q!h54ji^Qi@| zQ1+J4!{qyb`Fa92>lWjityGut#d*e?d>5IoDa049*3BIaN-Y=P%olSiUz{uXcKv!> zW<FYT5tBpwRMNU`K$RLv&!ox2vdWuqSRD0b0w$?&D>YvVE$fzi*p`7%e-YZ^;dN1} zkWrP>i`h~^m8(k)d>yMAPkUV?%t!Z4*xtMko*O?oIXW^fd-zLZo;<+cn3Tp89vAT} zfEe+5IX(R>qo}YoPA1r`o4(=!%6RCWCQ&NqWtZnwCYxRI-q@P2OT#UzTPo3Iz_*ks z&U=-H@pbX|rg$=4JLKbS*1%V?^?ZL}zS4cs;}WlouaGZ#<TK+pnb3THGvDN4=^0%L zUwJuO%q)5plkbG9`TpSUCwilK#4CKbS$&tuH<;9XDIVY81JX0PR4P+07d+(;4iJ-X zu37W_%H8K4jOG!q@KsNjvAT_X6D^vrpF2$SNzdp~`26veGqdLS&M=>xb7ywQSIVB6 zr7N0z=M27cx8RE&b?l8J5Jw=6KpcTM0&xW52>kaVK+jWq@f&l7pX2tj{Tkc%vYli5 z2-^j=huE&N{S4c0u|4J6`XPmW%I3ITp1bLnn_9@{a$fOpzX}<tu<=OP7zi7WhK)fo z78jJa;>|8sJv>!sa(Jp%i<x{8*Nr8PKpcTM0&xW52*eSHBM?U*jzAoNI0A75;t2d- zBVg~dd)p7ViS~}<!S;RjemtW)M=h!(+7Xk7q53aZ{lB6-wtuokyfl6Utr{<B1#LBU z()hChUeXTR<F5vINlR>x@4&1yLedu7<7WcAq&2q3e-z*)?XeYp7$fI+;tx&BYO|ik zC&@{uL|3Bbn2z@eISj4m_!yotlsKfXMA9)Gp8*uXaS`4NP~woj5?#l1TmdM8<2!i& zgc67Jm54j0<0pV3IIh7vgwPO&^p#a`Ovm+Tj+=0=Fo*P&m2pf*8?D1I)PZ83@Va!u z{RMMK-!)EZIi{nRI0{h5x*wmm{a5>)`1GmJWFsxbIj$!Z+97*_wN13zZb$2Nw=+56 z-d%IMYwn?%`%um8tGNR;H&t_=thvW(Zgb7upPY0P$%$mk=gwVVKMoqlqW`V8xn2r+ zG+*`v8v%EF>!j1PV+JJOm_fF|ZW)lVV+Pp-yJbL{j~QeO?3Q6LV2};4TZW;4L6(1$ z;Sffr_Ya+YN1?%rKd!rJ1hqCGkoP3fh_g`$UPO(c)31Sp7fB=NylX)4B4`Aia196! zvPRIE)_{;829tXX+1uNY&FJ8M2*^_Xw?U;s1PJvenV&!oXO_91@{`G8gnRgjWp1bg z`AKGO2!m3HM{vO~D22TeGypXAQhE&W^xv+dH*?ycB;>QLq;(S_Hf^IOD80o-Zz;X| z;`yFy&@6O(`h3qfDAUk&Xcg^i&<~;OP&&lFhW-Gh^Og8-KuPF~BKuqVfLwu6^%5Bn z`feecHZKXCi)7d6147>$RMqdRSQeeVWFO~tnIoJ2TZ3r!=R$K#U`DQW2Woo0CO#@A HJHh-5T*?4# diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.map b/llvm/test/tools/dsymutil/Inputs/obfuscated.map deleted file mode 100644 index 30fed8bf9b5a..000000000000 --- a/llvm/test/tools/dsymutil/Inputs/obfuscated.map +++ /dev/null @@ -1,17 +0,0 @@ -one -two -three -four -five -six -.str -Apple LLVM version 7.0.0 (clang-700.2.38.2) -main -main.c -/Users/steven/dev/alpena/tests/src -one.c -two.c -three.c -four.c -five.c -six.c diff --git a/llvm/test/tools/dsymutil/cmdline.test b/llvm/test/tools/dsymutil/cmdline.test index 36cf3f542695..814252b6e230 100644 --- a/llvm/test/tools/dsymutil/cmdline.test +++ b/llvm/test/tools/dsymutil/cmdline.test @@ -28,7 +28,6 @@ CHECK: -remarks-output-format <format> CHECK: -remarks-prepend-path <path> CHECK: -reproducer <mode> CHECK: -statistics -CHECK: -symbol-map CHECK: -symtab CHECK: {{-S}} CHECK: -toolchain diff --git a/llvm/tools/dsymutil/CMakeLists.txt b/llvm/tools/dsymutil/CMakeLists.txt index 53f882e90b4e..efe28bda68eb 100644 --- a/llvm/tools/dsymutil/CMakeLists.txt +++ b/llvm/tools/dsymutil/CMakeLists.txt @@ -32,7 +32,6 @@ add_llvm_tool(dsymutil MachOUtils.cpp Reproducer.cpp RelocationMap.cpp - SymbolMap.cpp DEPENDS intrinsics_gen diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp index 5ae5ecd556ad..677dfc44c54a 100644 --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -634,25 +634,19 @@ bool DwarfLinkerForBinary::linkImpl( DebugMap DebugMap(Map.getTriple(), Map.getBinaryPath()); - std::function<StringRef(StringRef)> TranslationLambda = [&](StringRef Input) { - assert(Options.Translator); - return Options.Translator(Input); - }; - std::unique_ptr<Linker> GeneralLinker = Linker::createLinker( [&](const Twine &Error, StringRef Context, const DWARFDie *DIE) { reportError(Error, Context, DIE); }, [&](const Twine &Warning, StringRef Context, const DWARFDie *DIE) { reportWarning(Warning, Context, DIE); - }, - Options.Translator ? TranslationLambda : nullptr); + }); std::unique_ptr<classic::DwarfStreamer> Streamer; if (!Options.NoOutput) { if (Expected<std::unique_ptr<classic::DwarfStreamer>> StreamerOrErr = classic::DwarfStreamer::createStreamer( - Map.getTriple(), ObjectType, OutFile, Options.Translator, + Map.getTriple(), ObjectType, OutFile, [&](const Twine &Warning, StringRef Context, const DWARFDie *DIE) { reportWarning(Warning, Context, DIE); @@ -866,8 +860,8 @@ bool DwarfLinkerForBinary::linkImpl( if (Map.getTriple().isOSDarwin() && !Map.getBinaryPath().empty() && ObjectType == Linker::OutputFileType::Object) return MachOUtils::generateDsymCompanion( - Options.VFS, Map, Options.Translator, - *Streamer->getAsmPrinter().OutStreamer, OutFile, RelocationsToApply); + Options.VFS, Map, *Streamer->getAsmPrinter().OutStreamer, OutFile, + RelocationsToApply); Streamer->finish(); return true; diff --git a/llvm/tools/dsymutil/LinkUtils.h b/llvm/tools/dsymutil/LinkUtils.h index fd9d985097d6..6aa0b847eebd 100644 --- a/llvm/tools/dsymutil/LinkUtils.h +++ b/llvm/tools/dsymutil/LinkUtils.h @@ -9,8 +9,6 @@ #ifndef LLVM_TOOLS_DSYMUTIL_LINKOPTIONS_H #define LLVM_TOOLS_DSYMUTIL_LINKOPTIONS_H -#include "SymbolMap.h" - #include "llvm/ADT/Twine.h" #include "llvm/Remarks/RemarkFormat.h" #include "llvm/Support/VirtualFileSystem.h" @@ -87,9 +85,6 @@ struct LinkOptions { /// The Resources directory in the .dSYM bundle. std::optional<std::string> ResourceDir; - /// Symbol map translator. - SymbolMapTranslator Translator; - /// Virtual File System. llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = vfs::getRealFileSystem(); diff --git a/llvm/tools/dsymutil/MachOUtils.cpp b/llvm/tools/dsymutil/MachOUtils.cpp index 3efc1aff8237..8e144d640ed0 100644 --- a/llvm/tools/dsymutil/MachOUtils.cpp +++ b/llvm/tools/dsymutil/MachOUtils.cpp @@ -373,7 +373,7 @@ static unsigned segmentLoadCommandSize(bool Is64Bit, unsigned NumSections) { // \a OutFile and it must be using a MachObjectWriter object to do so. bool generateDsymCompanion( llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, const DebugMap &DM, - SymbolMapTranslator &Translator, MCStreamer &MS, raw_fd_ostream &OutFile, + MCStreamer &MS, raw_fd_ostream &OutFile, const std::vector<MachOUtils::DwarfRelocationApplicationInfo> &RelocationsToApply) { auto &ObjectStreamer = static_cast<MCObjectStreamer &>(MS); @@ -509,12 +509,9 @@ bool generateDsymCompanion( } SmallString<0> NewSymtab; - std::function<StringRef(StringRef)> TranslationLambda = - Translator ? [&](StringRef Input) { return Translator(Input); } - : static_cast<std::function<StringRef(StringRef)>>(nullptr); // Legacy dsymutil puts an empty string at the start of the line table. // thus we set NonRelocatableStringpool(,PutEmptyString=true) - NonRelocatableStringpool NewStrings(TranslationLambda, true); + NonRelocatableStringpool NewStrings(true); unsigned NListSize = Is64Bit ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); unsigned NumSyms = 0; uint64_t NewStringsSize = 0; diff --git a/llvm/tools/dsymutil/MachOUtils.h b/llvm/tools/dsymutil/MachOUtils.h index 059d9fdd788a..0229647b00f8 100644 --- a/llvm/tools/dsymutil/MachOUtils.h +++ b/llvm/tools/dsymutil/MachOUtils.h @@ -8,8 +8,6 @@ #ifndef LLVM_TOOLS_DSYMUTIL_MACHOUTILS_H #define LLVM_TOOLS_DSYMUTIL_MACHOUTILS_H -#include "SymbolMap.h" - #include "llvm/ADT/StringRef.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/VirtualFileSystem.h" @@ -59,7 +57,7 @@ bool generateUniversalBinary(SmallVectorImpl<ArchAndFile> &ArchFiles, StringRef SDKPath, bool Fat64 = false); bool generateDsymCompanion( llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, const DebugMap &DM, - SymbolMapTranslator &Translator, MCStreamer &MS, raw_fd_ostream &OutFile, + MCStreamer &MS, raw_fd_ostream &OutFile, const std::vector<MachOUtils::DwarfRelocationApplicationInfo> &RelocationsToApply); diff --git a/llvm/tools/dsymutil/Options.td b/llvm/tools/dsymutil/Options.td index a4e4c6c4cdb9..d8cec0cb2c41 100644 --- a/llvm/tools/dsymutil/Options.td +++ b/llvm/tools/dsymutil/Options.td @@ -128,12 +128,6 @@ def object_prefix_map: Separate<["--", "-"], "object-prefix-map">, Group<grp_general>; def: Joined<["--", "-"], "object-prefix-map=">, Alias<object_prefix_map>; -def symbolmap: Separate<["--", "-"], "symbol-map">, - MetaVarName<"<bcsymbolmap>">, - HelpText<"Updates the existing dSYMs inplace using symbol map specified.">, - Group<grp_general>; -def: Joined<["--", "-"], "symbol-map=">, Alias<symbolmap>; - def arch: Separate<["--", "-"], "arch">, MetaVarName<"<arch>">, HelpText<"Link DWARF debug information only for specified CPU architecture" diff --git a/llvm/tools/dsymutil/SymbolMap.cpp b/llvm/tools/dsymutil/SymbolMap.cpp deleted file mode 100644 index c55362e5f775..000000000000 --- a/llvm/tools/dsymutil/SymbolMap.cpp +++ /dev/null @@ -1,157 +0,0 @@ -//===- tools/dsymutil/SymbolMap.cpp ---------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "SymbolMap.h" -#include "DebugMap.h" -#include "MachOUtils.h" - -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/WithColor.h" - -#ifdef __APPLE__ -#include <CoreFoundation/CoreFoundation.h> -#include <uuid/uuid.h> -#endif - -namespace llvm { -namespace dsymutil { - -StringRef SymbolMapTranslator::operator()(StringRef Input) { - if (!Input.starts_with("__hidden#") && !Input.starts_with("___hidden#")) - return Input; - - StringRef Line = Input.drop_front(sizeof("__hidden#") - 1); - bool MightNeedUnderscore = Line.consume_front("#"); - - std::size_t LineNumber = std::numeric_limits<std::size_t>::max(); - Line.split('_').first.getAsInteger(10, LineNumber); - if (LineNumber >= UnobfuscatedStrings.size()) { - WithColor::warning() << "reference to a unexisting unobfuscated string " - << Input << ": symbol map mismatch?\n" - << Line << '\n'; - return Input; - } - - const std::string &Translation = UnobfuscatedStrings[LineNumber]; - if (!MightNeedUnderscore || !MangleNames) - return Translation; - - // Objective-C symbols for the MachO symbol table start with a \1. Please see - // `MangleContext::mangleObjCMethodName` in clang. - if (Translation[0] == 1) - return StringRef(Translation).drop_front(); - - // We need permanent storage for the string we are about to create. Just - // append it to the vector containing translations. This should only happen - // during MachO symbol table translation, thus there should be no risk on - // exponential growth. - UnobfuscatedStrings.emplace_back("_" + Translation); - return UnobfuscatedStrings.back(); -} - -SymbolMapTranslator SymbolMapLoader::Load(StringRef InputFile, - const DebugMap &Map) const { - if (SymbolMap.empty()) - return {}; - - std::string SymbolMapPath = SymbolMap; - -#if __APPLE__ - // Look through the UUID Map. - if (sys::fs::is_directory(SymbolMapPath) && !Map.getUUID().empty()) { - uuid_string_t UUIDString; - uuid_unparse_upper((const uint8_t *)Map.getUUID().data(), UUIDString); - - SmallString<256> PlistPath( - sys::path::parent_path(sys::path::parent_path(InputFile))); - sys::path::append(PlistPath, StringRef(UUIDString).str() + ".plist"); - - CFStringRef plistFile = CFStringCreateWithCString( - kCFAllocatorDefault, PlistPath.c_str(), kCFStringEncodingUTF8); - CFURLRef fileURL = CFURLCreateWithFileSystemPath( - kCFAllocatorDefault, plistFile, kCFURLPOSIXPathStyle, false); - CFReadStreamRef resourceData = - CFReadStreamCreateWithFile(kCFAllocatorDefault, fileURL); - if (resourceData) { - CFReadStreamOpen(resourceData); - CFDictionaryRef plist = (CFDictionaryRef)CFPropertyListCreateWithStream( - kCFAllocatorDefault, resourceData, 0, kCFPropertyListImmutable, - nullptr, nullptr); - - if (plist) { - if (CFDictionaryContainsKey(plist, CFSTR("DBGOriginalUUID"))) { - CFStringRef OldUUID = (CFStringRef)CFDictionaryGetValue( - plist, CFSTR("DBGOriginalUUID")); - - StringRef UUID(CFStringGetCStringPtr(OldUUID, kCFStringEncodingUTF8)); - SmallString<256> BCSymbolMapPath(SymbolMapPath); - sys::path::append(BCSymbolMapPath, UUID.str() + ".bcsymbolmap"); - SymbolMapPath = std::string(BCSymbolMapPath); - } - CFRelease(plist); - } - CFReadStreamClose(resourceData); - CFRelease(resourceData); - } - CFRelease(fileURL); - CFRelease(plistFile); - } -#endif - - if (sys::fs::is_directory(SymbolMapPath)) { - SymbolMapPath += (Twine("/") + sys::path::filename(InputFile) + "-" + - MachOUtils::getArchName(Map.getTriple().getArchName()) + - ".bcsymbolmap") - .str(); - } - - auto ErrOrMemBuffer = MemoryBuffer::getFile(SymbolMapPath); - if (auto EC = ErrOrMemBuffer.getError()) { - WithColor::warning() << SymbolMapPath << ": " << EC.message() - << ": not unobfuscating.\n"; - return {}; - } - - std::vector<std::string> UnobfuscatedStrings; - auto &MemBuf = **ErrOrMemBuffer; - StringRef Data(MemBuf.getBufferStart(), - MemBuf.getBufferEnd() - MemBuf.getBufferStart()); - StringRef LHS; - std::tie(LHS, Data) = Data.split('\n'); - bool MangleNames = false; - - // Check version string first. - if (!LHS.starts_with("BCSymbolMap Version:")) { - // Version string not present, warns but try to parse it. - WithColor::warning() << SymbolMapPath - << " is missing version string: assuming 1.0.\n"; - UnobfuscatedStrings.emplace_back(LHS); - } else if (LHS.equals("BCSymbolMap Version: 1.0")) { - MangleNames = true; - } else if (LHS.equals("BCSymbolMap Version: 2.0")) { - MangleNames = false; - } else { - StringRef VersionNum; - std::tie(LHS, VersionNum) = LHS.split(':'); - WithColor::warning() << SymbolMapPath - << " has unsupported symbol map version" << VersionNum - << ": not unobfuscating.\n"; - return {}; - } - - while (!Data.empty()) { - std::tie(LHS, Data) = Data.split('\n'); - UnobfuscatedStrings.emplace_back(LHS); - } - - return SymbolMapTranslator(std::move(UnobfuscatedStrings), MangleNames); -} - -} // namespace dsymutil -} // namespace llvm diff --git a/llvm/tools/dsymutil/SymbolMap.h b/llvm/tools/dsymutil/SymbolMap.h deleted file mode 100644 index 977de31a5a17..000000000000 --- a/llvm/tools/dsymutil/SymbolMap.h +++ /dev/null @@ -1,53 +0,0 @@ -//=- tools/dsymutil/SymbolMap.h -----------------------------------*- C++ -*-=// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TOOLS_DSYMUTIL_SYMBOLMAP_H -#define LLVM_TOOLS_DSYMUTIL_SYMBOLMAP_H - -#include "llvm/ADT/StringRef.h" - -#include <string> -#include <vector> - -namespace llvm { -namespace dsymutil { -class DebugMap; - -/// Callable class to unobfuscate strings based on a BCSymbolMap. -class SymbolMapTranslator { -public: - SymbolMapTranslator() : MangleNames(false) {} - - SymbolMapTranslator(std::vector<std::string> UnobfuscatedStrings, - bool MangleNames) - : UnobfuscatedStrings(std::move(UnobfuscatedStrings)), - MangleNames(MangleNames) {} - - StringRef operator()(StringRef Input); - - operator bool() const { return !UnobfuscatedStrings.empty(); } - -private: - std::vector<std::string> UnobfuscatedStrings; - bool MangleNames; -}; - -/// Class to initialize SymbolMapTranslators from a BCSymbolMap. -class SymbolMapLoader { -public: - SymbolMapLoader(std::string SymbolMap) : SymbolMap(std::move(SymbolMap)) {} - - SymbolMapTranslator Load(StringRef InputFile, const DebugMap &Map) const; - -private: - const std::string SymbolMap; -}; -} // namespace dsymutil -} // namespace llvm - -#endif // LLVM_TOOLS_DSYMUTIL_SYMBOLMAP_H diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp index 25e281c415e7..bc968b6387b6 100644 --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/tools/dsymutil/dsymutil.cpp @@ -108,7 +108,6 @@ struct DsymutilOptions { bool Flat = false; bool InputIsYAMLDebugMap = false; bool ForceKeepFunctionForStatic = false; - std::string SymbolMap; std::string OutputFile; std::string Toolchain; std::string ReproducerPath; @@ -341,12 +340,6 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) { return DWARFLinkerType.takeError(); } - if (opt::Arg *SymbolMap = Args.getLastArg(OPT_symbolmap)) - Options.SymbolMap = SymbolMap->getValue(); - - if (Args.hasArg(OPT_symbolmap)) - Options.LinkOpts.Update = true; - if (Expected<std::vector<std::string>> InputFiles = getInputs(Args, Options.LinkOpts.Update)) { Options.InputFiles = std::move(*InputFiles); @@ -560,8 +553,7 @@ getOutputFileName(StringRef InputFile, const DsymutilOptions &Options) { return OutputLocation(Options.OutputFile); // When updating, do in place replacement. - if (Options.OutputFile.empty() && - (Options.LinkOpts.Update || !Options.SymbolMap.empty())) + if (Options.OutputFile.empty() && Options.LinkOpts.Update) return OutputLocation(std::string(InputFile)); // When dumping the debug map, just return an empty output location. This @@ -668,8 +660,6 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) { return EXIT_FAILURE; } - SymbolMapLoader SymMapLoader(Options.SymbolMap); - for (auto &InputFile : Options.InputFiles) { // Dump the symbol table for each input file and requested arch if (Options.DumpStab) { @@ -760,9 +750,6 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) { if (Options.DumpDebugMap) continue; - if (!Options.SymbolMap.empty()) - Options.LinkOpts.Translator = SymMapLoader.Load(InputFile, *Map); - if (Map->begin() == Map->end()) { std::lock_guard<std::mutex> Guard(ErrorHandlerMutex); WithColor::warning() diff --git a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp index bd17f3c4a659..285dcf75ecd9 100644 --- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp +++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp @@ -338,9 +338,9 @@ Error linkDebugInfoImpl(object::ObjectFile &File, const Options &Options, Triple TargetTriple = File.makeTriple(); std::unique_ptr<classic::DwarfStreamer> Streamer; if (Expected<std::unique_ptr<classic::DwarfStreamer>> StreamerOrErr = - classic::DwarfStreamer::createStreamer( - TargetTriple, Linker::OutputFileType::Object, OutStream, nullptr, - ReportWarn)) + classic::DwarfStreamer::createStreamer(TargetTriple, + Linker::OutputFileType::Object, + OutStream, ReportWarn)) Streamer = std::move(*StreamerOrErr); else return StreamerOrErr.takeError(); -- GitLab From 66125ad8e9978e6fdec0e1c3ff83e717eff07aca Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <llvm-dev@redking.me.uk> Date: Tue, 19 Mar 2024 14:36:17 +0000 Subject: [PATCH 096/307] [X86] Add test coverage for vector avgceils/avgceilu/avgfloors/avgflooru test patterns SSE only has AVGCEILU vXi8/vXi16 support - but for other types we should be trying to use the fixed width expansion instead of extensions --- llvm/test/CodeGen/X86/avgceils.ll | 3821 ++++++++++++++++++++++++++++ llvm/test/CodeGen/X86/avgceilu.ll | 2219 ++++++++++++++++ llvm/test/CodeGen/X86/avgfloors.ll | 3437 +++++++++++++++++++++++++ llvm/test/CodeGen/X86/avgflooru.ll | 2629 +++++++++++++++++++ 4 files changed, 12106 insertions(+) create mode 100644 llvm/test/CodeGen/X86/avgceils.ll create mode 100644 llvm/test/CodeGen/X86/avgceilu.ll create mode 100644 llvm/test/CodeGen/X86/avgfloors.ll create mode 100644 llvm/test/CodeGen/X86/avgflooru.ll diff --git a/llvm/test/CodeGen/X86/avgceils.ll b/llvm/test/CodeGen/X86/avgceils.ll new file mode 100644 index 000000000000..4529ea275df9 --- /dev/null +++ b/llvm/test/CodeGen/X86/avgceils.ll @@ -0,0 +1,3821 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE2 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE4 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2 +; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=AVX,AVX512 + +; +; 128-bit vectors +; + +define <16 x i8> @test_fixed_v16i8(<16 x i8> %a0, <16 x i8> %a1) { +; SSE-LABEL: test_fixed_v16i8: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: por %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm0 +; SSE-NEXT: psrlw $1, %xmm0 +; SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; SSE-NEXT: movdqa {{.*#+}} xmm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; SSE-NEXT: pxor %xmm1, %xmm0 +; SSE-NEXT: psubb %xmm0, %xmm2 +; SSE-NEXT: paddb %xmm1, %xmm2 +; SSE-NEXT: movdqa %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v16i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm2 +; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsubb %xmm0, %xmm2, %xmm0 +; AVX1-NEXT: vpaddb %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v16i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %xmm1, %xmm0, %xmm2 +; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX2-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX2-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 +; AVX2-NEXT: vpbroadcastb {{.*#+}} xmm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX2-NEXT: vpsubb %xmm0, %xmm2, %xmm0 +; AVX2-NEXT: vpaddb %xmm1, %xmm0, %xmm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v16i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpor %xmm1, %xmm0, %xmm2 +; AVX512-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX512-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX512-NEXT: vpbroadcastb {{.*#+}} xmm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX512-NEXT: vpternlogd $108, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm1, %xmm0 +; AVX512-NEXT: vpsubb %xmm0, %xmm2, %xmm0 +; AVX512-NEXT: vpaddb %xmm1, %xmm0, %xmm0 +; AVX512-NEXT: retq + %or = or <16 x i8> %a0, %a1 + %xor = xor <16 x i8> %a0, %a1 + %shift = ashr <16 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = sub <16 x i8> %or, %shift + ret <16 x i8> %res +} + +define <16 x i8> @test_ext_v16i8(<16 x i8> %a0, <16 x i8> %a1) { +; SSE2-LABEL: test_ext_v16i8: +; SSE2: # %bb.0: +; SSE2-NEXT: punpckhbw {{.*#+}} xmm2 = xmm2[8],xmm0[8],xmm2[9],xmm0[9],xmm2[10],xmm0[10],xmm2[11],xmm0[11],xmm2[12],xmm0[12],xmm2[13],xmm0[13],xmm2[14],xmm0[14],xmm2[15],xmm0[15] +; SSE2-NEXT: psraw $8, %xmm2 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3],xmm3[4],xmm0[4],xmm3[5],xmm0[5],xmm3[6],xmm0[6],xmm3[7],xmm0[7] +; SSE2-NEXT: psraw $8, %xmm3 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm1[8],xmm4[9],xmm1[9],xmm4[10],xmm1[10],xmm4[11],xmm1[11],xmm4[12],xmm1[12],xmm4[13],xmm1[13],xmm4[14],xmm1[14],xmm4[15],xmm1[15] +; SSE2-NEXT: psraw $8, %xmm4 +; SSE2-NEXT: paddw %xmm2, %xmm4 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7] +; SSE2-NEXT: psraw $8, %xmm0 +; SSE2-NEXT: paddw %xmm3, %xmm0 +; SSE2-NEXT: pcmpeqd %xmm1, %xmm1 +; SSE2-NEXT: psubw %xmm1, %xmm4 +; SSE2-NEXT: psubw %xmm1, %xmm0 +; SSE2-NEXT: psrlw $1, %xmm0 +; SSE2-NEXT: psrlw $1, %xmm4 +; SSE2-NEXT: movdqa {{.*#+}} xmm1 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0] +; SSE2-NEXT: pand %xmm1, %xmm4 +; SSE2-NEXT: pand %xmm1, %xmm0 +; SSE2-NEXT: packuswb %xmm4, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v16i8: +; SSE4: # %bb.0: +; SSE4-NEXT: pmovsxbw %xmm0, %xmm2 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm3 +; SSE4-NEXT: pmovsxbw %xmm1, %xmm0 +; SSE4-NEXT: paddw %xmm2, %xmm0 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm1, %xmm1 +; SSE4-NEXT: paddw %xmm3, %xmm1 +; SSE4-NEXT: pcmpeqd %xmm2, %xmm2 +; SSE4-NEXT: psubw %xmm2, %xmm0 +; SSE4-NEXT: psubw %xmm2, %xmm1 +; SSE4-NEXT: psrlw $1, %xmm1 +; SSE4-NEXT: psrlw $1, %xmm0 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] +; SSE4-NEXT: pand %xmm2, %xmm0 +; SSE4-NEXT: pand %xmm2, %xmm1 +; SSE4-NEXT: packuswb %xmm1, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v16i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vpmovsxbw %xmm0, %xmm2 +; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm0, %xmm0 +; AVX1-NEXT: vpmovsxbw %xmm1, %xmm3 +; AVX1-NEXT: vpaddw %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm1, %xmm1 +; AVX1-NEXT: vpaddw %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 +; AVX1-NEXT: vpsubw %xmm1, %xmm2, %xmm2 +; AVX1-NEXT: vpsubw %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm2, %xmm1 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] +; AVX1-NEXT: vpand %xmm2, %xmm1, %xmm1 +; AVX1-NEXT: vpand %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vpackuswb %xmm0, %xmm1, %xmm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v16i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxbw %xmm1, %ymm1 +; AVX2-NEXT: vpaddw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 +; AVX2-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 +; AVX2-NEXT: vzeroupper +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v16i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxbw %xmm0, %ymm0 +; AVX512-NEXT: vpmovsxbw %xmm1, %ymm1 +; AVX512-NEXT: vpaddw %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX512-NEXT: vpsubw %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX512-NEXT: vpmovwb %ymm0, %xmm0 +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %x0 = sext <16 x i8> %a0 to <16 x i16> + %x1 = sext <16 x i8> %a1 to <16 x i16> + %sum = add <16 x i16> %x0, %x1 + %inc = add <16 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %shift = ashr <16 x i16> %inc, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <16 x i16> %shift to <16 x i8> + ret <16 x i8> %res +} + +define <8 x i16> @test_fixed_v8i16(<8 x i16> %a0, <8 x i16> %a1) { +; SSE-LABEL: test_fixed_v8i16: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: por %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm0, %xmm1 +; SSE-NEXT: psraw $1, %xmm1 +; SSE-NEXT: psubw %xmm1, %xmm2 +; SSE-NEXT: movdqa %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_fixed_v8i16: +; AVX: # %bb.0: +; AVX-NEXT: vpor %xmm1, %xmm0, %xmm2 +; AVX-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX-NEXT: vpsraw $1, %xmm0, %xmm0 +; AVX-NEXT: vpsubw %xmm0, %xmm2, %xmm0 +; AVX-NEXT: retq + %or = or <8 x i16> %a0, %a1 + %xor = xor <8 x i16> %a1, %a0 + %shift = ashr <8 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = sub <8 x i16> %or, %shift + ret <8 x i16> %res +} + +define <8 x i16> @test_ext_v8i16(<8 x i16> %a0, <8 x i16> %a1) { +; SSE2-LABEL: test_ext_v8i16: +; SSE2: # %bb.0: +; SSE2-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3] +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4],xmm0[4],xmm3[5],xmm0[5],xmm3[6],xmm0[6],xmm3[7],xmm0[7] +; SSE2-NEXT: psrad $16, %xmm3 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3] +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: paddd %xmm2, %xmm0 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4,4,5,5,6,6,7,7] +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: paddd %xmm3, %xmm1 +; SSE2-NEXT: pcmpeqd %xmm2, %xmm2 +; SSE2-NEXT: psubd %xmm2, %xmm0 +; SSE2-NEXT: psubd %xmm2, %xmm1 +; SSE2-NEXT: pslld $15, %xmm1 +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: pslld $15, %xmm0 +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: packssdw %xmm1, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v8i16: +; SSE4: # %bb.0: +; SSE4-NEXT: pmovsxwd %xmm0, %xmm2 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm3 +; SSE4-NEXT: pmovsxwd %xmm1, %xmm0 +; SSE4-NEXT: paddd %xmm2, %xmm0 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm1, %xmm1 +; SSE4-NEXT: paddd %xmm3, %xmm1 +; SSE4-NEXT: pcmpeqd %xmm2, %xmm2 +; SSE4-NEXT: psubd %xmm2, %xmm0 +; SSE4-NEXT: psubd %xmm2, %xmm1 +; SSE4-NEXT: psrld $1, %xmm1 +; SSE4-NEXT: psrld $1, %xmm0 +; SSE4-NEXT: pxor %xmm2, %xmm2 +; SSE4-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3],xmm0[4],xmm2[5],xmm0[6],xmm2[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3],xmm1[4],xmm2[5],xmm1[6],xmm2[7] +; SSE4-NEXT: packusdw %xmm1, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v8i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vpmovsxwd %xmm0, %xmm2 +; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm0, %xmm0 +; AVX1-NEXT: vpmovsxwd %xmm1, %xmm3 +; AVX1-NEXT: vpaddd %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm1, %xmm1 +; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 +; AVX1-NEXT: vpsubd %xmm1, %xmm2, %xmm2 +; AVX1-NEXT: vpsubd %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm2, %xmm1 +; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 +; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3],xmm1[4],xmm2[5],xmm1[6],xmm2[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3],xmm0[4],xmm2[5],xmm0[6],xmm2[7] +; AVX1-NEXT: vpackusdw %xmm0, %xmm1, %xmm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v8i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxwd %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxwd %xmm1, %ymm1 +; AVX2-NEXT: vpaddd %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubd %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u] +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3] +; AVX2-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 +; AVX2-NEXT: vzeroupper +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v8i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxwd %xmm0, %ymm0 +; AVX512-NEXT: vpmovsxwd %xmm1, %ymm1 +; AVX512-NEXT: vpaddd %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX512-NEXT: vpsubd %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX512-NEXT: vpmovdw %ymm0, %xmm0 +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %x0 = sext <8 x i16> %a0 to <8 x i32> + %x1 = sext <8 x i16> %a1 to <8 x i32> + %sum = add <8 x i32> %x0, %x1 + %inc = add <8 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %shift = ashr <8 x i32> %inc, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <8 x i32> %shift to <8 x i16> + ret <8 x i16> %res +} + +define <4 x i32> @test_fixed_v4i32(<4 x i32> %a0, <4 x i32> %a1) { +; SSE-LABEL: test_fixed_v4i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: por %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm0, %xmm1 +; SSE-NEXT: psrad $1, %xmm1 +; SSE-NEXT: psubd %xmm1, %xmm2 +; SSE-NEXT: movdqa %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_fixed_v4i32: +; AVX: # %bb.0: +; AVX-NEXT: vpor %xmm1, %xmm0, %xmm2 +; AVX-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX-NEXT: vpsrad $1, %xmm0, %xmm0 +; AVX-NEXT: vpsubd %xmm0, %xmm2, %xmm0 +; AVX-NEXT: retq + %or = or <4 x i32> %a0, %a1 + %xor = xor <4 x i32> %a1, %a0 + %shift = ashr <4 x i32> %xor, <i32 1, i32 1, i32 1, i32 1> + %res = sub <4 x i32> %or, %shift + ret <4 x i32> %res +} + +define <4 x i32> @test_ext_v4i32(<4 x i32> %a0, <4 x i32> %a1) { +; SSE2-LABEL: test_ext_v4i32: +; SSE2: # %bb.0: +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; SSE2-NEXT: pxor %xmm3, %xmm3 +; SSE2-NEXT: pxor %xmm4, %xmm4 +; SSE2-NEXT: pcmpgtd %xmm2, %xmm4 +; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1] +; SSE2-NEXT: pxor %xmm4, %xmm4 +; SSE2-NEXT: pcmpgtd %xmm0, %xmm4 +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1] +; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3] +; SSE2-NEXT: pxor %xmm5, %xmm5 +; SSE2-NEXT: pcmpgtd %xmm4, %xmm5 +; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm5[0],xmm4[1],xmm5[1] +; SSE2-NEXT: paddq %xmm2, %xmm4 +; SSE2-NEXT: pcmpgtd %xmm1, %xmm3 +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1] +; SSE2-NEXT: paddq %xmm1, %xmm0 +; SSE2-NEXT: pcmpeqd %xmm1, %xmm1 +; SSE2-NEXT: psubq %xmm1, %xmm4 +; SSE2-NEXT: psubq %xmm1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm4 +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm4[0,2] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v4i32: +; SSE4: # %bb.0: +; SSE4-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm2, %xmm2 +; SSE4-NEXT: pmovsxdq %xmm0, %xmm3 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm4 +; SSE4-NEXT: paddq %xmm2, %xmm4 +; SSE4-NEXT: pmovsxdq %xmm1, %xmm0 +; SSE4-NEXT: paddq %xmm3, %xmm0 +; SSE4-NEXT: pcmpeqd %xmm1, %xmm1 +; SSE4-NEXT: psubq %xmm1, %xmm4 +; SSE4-NEXT: psubq %xmm1, %xmm0 +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: psrlq $1, %xmm4 +; SSE4-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm4[0,2] +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v4i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxdq %xmm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm3 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm3, %xmm3 +; AVX1-NEXT: vpaddq %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxdq %xmm1, %xmm1 +; AVX1-NEXT: vpaddq %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 +; AVX1-NEXT: vpsubq %xmm1, %xmm2, %xmm2 +; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm2, %xmm1 +; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v4i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxdq %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxdq %xmm1, %ymm1 +; AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 +; AVX2-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] +; AVX2-NEXT: vzeroupper +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v4i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxdq %xmm0, %ymm0 +; AVX512-NEXT: vpmovsxdq %xmm1, %ymm1 +; AVX512-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX512-NEXT: vpsubq %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX512-NEXT: vpmovqd %ymm0, %xmm0 +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %x0 = sext <4 x i32> %a0 to <4 x i64> + %x1 = sext <4 x i32> %a1 to <4 x i64> + %sum = add <4 x i64> %x0, %x1 + %inc = add <4 x i64> %sum, <i64 1, i64 1, i64 1, i64 1> + %shift = ashr <4 x i64> %inc, <i64 1, i64 1, i64 1, i64 1> + %res = trunc <4 x i64> %shift to <4 x i32> + ret <4 x i32> %res +} + +define <2 x i64> @test_fixed_v2i64(<2 x i64> %a0, <2 x i64> %a1) { +; SSE2-LABEL: test_fixed_v2i64: +; SSE2: # %bb.0: +; SSE2-NEXT: movdqa %xmm0, %xmm2 +; SSE2-NEXT: por %xmm1, %xmm2 +; SSE2-NEXT: pxor %xmm0, %xmm1 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm1 +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] +; SSE2-NEXT: psubq %xmm1, %xmm2 +; SSE2-NEXT: movdqa %xmm2, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_fixed_v2i64: +; SSE4: # %bb.0: +; SSE4-NEXT: movdqa %xmm0, %xmm2 +; SSE4-NEXT: por %xmm1, %xmm2 +; SSE4-NEXT: pxor %xmm0, %xmm1 +; SSE4-NEXT: movdqa %xmm1, %xmm0 +; SSE4-NEXT: psrad $1, %xmm0 +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm0[2,3],xmm1[4,5],xmm0[6,7] +; SSE4-NEXT: psubq %xmm1, %xmm2 +; SSE4-NEXT: movdqa %xmm2, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_fixed_v2i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm2 +; AVX1-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] +; AVX1-NEXT: vpsubq %xmm0, %xmm2, %xmm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v2i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %xmm1, %xmm0, %xmm2 +; AVX2-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX2-NEXT: vpsrad $1, %xmm0, %xmm1 +; AVX2-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] +; AVX2-NEXT: vpsubq %xmm0, %xmm2, %xmm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v2i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vpor %xmm1, %xmm0, %xmm2 +; AVX512-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX512-NEXT: vpsraq $1, %xmm0, %xmm0 +; AVX512-NEXT: vpsubq %xmm0, %xmm2, %xmm0 +; AVX512-NEXT: retq + %or = or <2 x i64> %a0, %a1 + %xor = xor <2 x i64> %a1, %a0 + %shift = ashr <2 x i64> %xor, <i64 1, i64 1> + %res = sub <2 x i64> %or, %shift + ret <2 x i64> %res +} + +define <2 x i64> @test_ext_v2i64(<2 x i64> %a0, <2 x i64> %a1) { +; SSE2-LABEL: test_ext_v2i64: +; SSE2: # %bb.0: +; SSE2-NEXT: movq %xmm0, %rax +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rdx +; SSE2-NEXT: movq %rdx, %rsi +; SSE2-NEXT: sarq $63, %rsi +; SSE2-NEXT: movq %xmm1, %rdi +; SSE2-NEXT: movq %rdi, %r8 +; SSE2-NEXT: sarq $63, %r8 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r9 +; SSE2-NEXT: movq %r9, %r10 +; SSE2-NEXT: sarq $63, %r10 +; SSE2-NEXT: addq %r9, %rdx +; SSE2-NEXT: adcq %rsi, %r10 +; SSE2-NEXT: addq %rdi, %rax +; SSE2-NEXT: adcq %rcx, %r8 +; SSE2-NEXT: addq $1, %rax +; SSE2-NEXT: adcq $0, %r8 +; SSE2-NEXT: addq $1, %rdx +; SSE2-NEXT: adcq $0, %r10 +; SSE2-NEXT: shldq $63, %rdx, %r10 +; SSE2-NEXT: shldq $63, %rax, %r8 +; SSE2-NEXT: movq %r8, %xmm0 +; SSE2-NEXT: movq %r10, %xmm1 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v2i64: +; SSE4: # %bb.0: +; SSE4-NEXT: pextrq $1, %xmm0, %rax +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: movq %xmm0, %rdx +; SSE4-NEXT: movq %rdx, %rsi +; SSE4-NEXT: sarq $63, %rsi +; SSE4-NEXT: pextrq $1, %xmm1, %rdi +; SSE4-NEXT: movq %rdi, %r8 +; SSE4-NEXT: sarq $63, %r8 +; SSE4-NEXT: movq %xmm1, %r9 +; SSE4-NEXT: movq %r9, %r10 +; SSE4-NEXT: sarq $63, %r10 +; SSE4-NEXT: addq %r9, %rdx +; SSE4-NEXT: adcq %rsi, %r10 +; SSE4-NEXT: addq %rdi, %rax +; SSE4-NEXT: adcq %rcx, %r8 +; SSE4-NEXT: addq $1, %rax +; SSE4-NEXT: adcq $0, %r8 +; SSE4-NEXT: addq $1, %rdx +; SSE4-NEXT: adcq $0, %r10 +; SSE4-NEXT: shldq $63, %rdx, %r10 +; SSE4-NEXT: shldq $63, %rax, %r8 +; SSE4-NEXT: movq %r8, %xmm1 +; SSE4-NEXT: movq %r10, %xmm0 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE4-NEXT: retq +; +; AVX-LABEL: test_ext_v2i64: +; AVX: # %bb.0: +; AVX-NEXT: vpextrq $1, %xmm0, %rax +; AVX-NEXT: movq %rax, %rcx +; AVX-NEXT: sarq $63, %rcx +; AVX-NEXT: vmovq %xmm0, %rdx +; AVX-NEXT: movq %rdx, %rsi +; AVX-NEXT: sarq $63, %rsi +; AVX-NEXT: vpextrq $1, %xmm1, %rdi +; AVX-NEXT: movq %rdi, %r8 +; AVX-NEXT: sarq $63, %r8 +; AVX-NEXT: vmovq %xmm1, %r9 +; AVX-NEXT: movq %r9, %r10 +; AVX-NEXT: sarq $63, %r10 +; AVX-NEXT: addq %r9, %rdx +; AVX-NEXT: adcq %rsi, %r10 +; AVX-NEXT: addq %rdi, %rax +; AVX-NEXT: adcq %rcx, %r8 +; AVX-NEXT: addq $1, %rax +; AVX-NEXT: adcq $0, %r8 +; AVX-NEXT: addq $1, %rdx +; AVX-NEXT: adcq $0, %r10 +; AVX-NEXT: shldq $63, %rdx, %r10 +; AVX-NEXT: shldq $63, %rax, %r8 +; AVX-NEXT: vmovq %r8, %xmm0 +; AVX-NEXT: vmovq %r10, %xmm1 +; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX-NEXT: retq + %x0 = sext <2 x i64> %a0 to <2 x i128> + %x1 = sext <2 x i64> %a1 to <2 x i128> + %sum = add <2 x i128> %x0, %x1 + %inc = add <2 x i128> %sum, <i128 1, i128 1> + %shift = ashr <2 x i128> %inc, <i128 1, i128 1> + %res = trunc <2 x i128> %shift to <2 x i64> + ret <2 x i64> %res +} + +; +; 256-bit vectors +; + +define <32 x i8> @test_fixed_v32i8(<32 x i8> %a0, <32 x i8> %a1) { +; SSE-LABEL: test_fixed_v32i8: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: por %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: por %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm0 +; SSE-NEXT: pxor %xmm3, %xmm1 +; SSE-NEXT: psrlw $1, %xmm1 +; SSE-NEXT: movdqa {{.*#+}} xmm2 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; SSE-NEXT: pand %xmm2, %xmm1 +; SSE-NEXT: movdqa {{.*#+}} xmm3 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; SSE-NEXT: pxor %xmm3, %xmm1 +; SSE-NEXT: psubb %xmm1, %xmm4 +; SSE-NEXT: psrlw $1, %xmm0 +; SSE-NEXT: pand %xmm2, %xmm0 +; SSE-NEXT: pxor %xmm3, %xmm0 +; SSE-NEXT: psubb %xmm0, %xmm5 +; SSE-NEXT: paddb %xmm3, %xmm5 +; SSE-NEXT: paddb %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm5, %xmm0 +; SSE-NEXT: movdqa %xmm4, %xmm1 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v32i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm1 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; AVX1-NEXT: vpand %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX1-NEXT: vpxor %xmm4, %xmm1, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpxor %xmm4, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpsubb %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpaddb %xmm4, %xmm0, %xmm0 +; AVX1-NEXT: vpsubb %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vpaddb %xmm4, %xmm1, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v32i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 +; AVX2-NEXT: vpbroadcastb {{.*#+}} ymm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX2-NEXT: vpxor %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsubb %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpaddb %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v32i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX512-NEXT: vpbroadcastb {{.*#+}} ymm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX512-NEXT: vpternlogd $108, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm1, %ymm0 +; AVX512-NEXT: vpsubb %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: vpaddb %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: retq + %or = or <32 x i8> %a0, %a1 + %xor = xor <32 x i8> %a0, %a1 + %shift = ashr <32 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = sub <32 x i8> %or, %shift + ret <32 x i8> %res +} + +define <32 x i8> @test_ext_v32i8(<32 x i8> %a0, <32 x i8> %a1) { +; SSE2-LABEL: test_ext_v32i8: +; SSE2: # %bb.0: +; SSE2-NEXT: punpckhbw {{.*#+}} xmm5 = xmm5[8],xmm0[8],xmm5[9],xmm0[9],xmm5[10],xmm0[10],xmm5[11],xmm0[11],xmm5[12],xmm0[12],xmm5[13],xmm0[13],xmm5[14],xmm0[14],xmm5[15],xmm0[15] +; SSE2-NEXT: psraw $8, %xmm5 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm6 = xmm6[0],xmm0[0],xmm6[1],xmm0[1],xmm6[2],xmm0[2],xmm6[3],xmm0[3],xmm6[4],xmm0[4],xmm6[5],xmm0[5],xmm6[6],xmm0[6],xmm6[7],xmm0[7] +; SSE2-NEXT: psraw $8, %xmm6 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm7 = xmm7[8],xmm1[8],xmm7[9],xmm1[9],xmm7[10],xmm1[10],xmm7[11],xmm1[11],xmm7[12],xmm1[12],xmm7[13],xmm1[13],xmm7[14],xmm1[14],xmm7[15],xmm1[15] +; SSE2-NEXT: psraw $8, %xmm7 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm8 = xmm8[0],xmm1[0],xmm8[1],xmm1[1],xmm8[2],xmm1[2],xmm8[3],xmm1[3],xmm8[4],xmm1[4],xmm8[5],xmm1[5],xmm8[6],xmm1[6],xmm8[7],xmm1[7] +; SSE2-NEXT: psraw $8, %xmm8 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm2[8],xmm4[9],xmm2[9],xmm4[10],xmm2[10],xmm4[11],xmm2[11],xmm4[12],xmm2[12],xmm4[13],xmm2[13],xmm4[14],xmm2[14],xmm4[15],xmm2[15] +; SSE2-NEXT: psraw $8, %xmm4 +; SSE2-NEXT: paddw %xmm5, %xmm4 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3],xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7] +; SSE2-NEXT: psraw $8, %xmm0 +; SSE2-NEXT: paddw %xmm6, %xmm0 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm2 = xmm2[8],xmm3[8],xmm2[9],xmm3[9],xmm2[10],xmm3[10],xmm2[11],xmm3[11],xmm2[12],xmm3[12],xmm2[13],xmm3[13],xmm2[14],xmm3[14],xmm2[15],xmm3[15] +; SSE2-NEXT: psraw $8, %xmm2 +; SSE2-NEXT: paddw %xmm7, %xmm2 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1],xmm1[2],xmm3[2],xmm1[3],xmm3[3],xmm1[4],xmm3[4],xmm1[5],xmm3[5],xmm1[6],xmm3[6],xmm1[7],xmm3[7] +; SSE2-NEXT: psraw $8, %xmm1 +; SSE2-NEXT: paddw %xmm8, %xmm1 +; SSE2-NEXT: pcmpeqd %xmm3, %xmm3 +; SSE2-NEXT: psubw %xmm3, %xmm4 +; SSE2-NEXT: psubw %xmm3, %xmm0 +; SSE2-NEXT: psubw %xmm3, %xmm2 +; SSE2-NEXT: psubw %xmm3, %xmm1 +; SSE2-NEXT: psrlw $1, %xmm1 +; SSE2-NEXT: psrlw $1, %xmm2 +; SSE2-NEXT: psrlw $1, %xmm0 +; SSE2-NEXT: psrlw $1, %xmm4 +; SSE2-NEXT: movdqa {{.*#+}} xmm3 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0] +; SSE2-NEXT: pand %xmm3, %xmm4 +; SSE2-NEXT: pand %xmm3, %xmm0 +; SSE2-NEXT: packuswb %xmm4, %xmm0 +; SSE2-NEXT: pand %xmm3, %xmm2 +; SSE2-NEXT: pand %xmm3, %xmm1 +; SSE2-NEXT: packuswb %xmm2, %xmm1 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v32i8: +; SSE4: # %bb.0: +; SSE4-NEXT: pmovsxbw %xmm0, %xmm4 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm5 +; SSE4-NEXT: pmovsxbw %xmm1, %xmm6 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm7 +; SSE4-NEXT: pmovsxbw %xmm2, %xmm0 +; SSE4-NEXT: paddw %xmm4, %xmm0 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm1, %xmm2 +; SSE4-NEXT: paddw %xmm5, %xmm2 +; SSE4-NEXT: pmovsxbw %xmm3, %xmm1 +; SSE4-NEXT: paddw %xmm6, %xmm1 +; SSE4-NEXT: pshufd {{.*#+}} xmm3 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm3, %xmm3 +; SSE4-NEXT: paddw %xmm7, %xmm3 +; SSE4-NEXT: pcmpeqd %xmm4, %xmm4 +; SSE4-NEXT: psubw %xmm4, %xmm0 +; SSE4-NEXT: psubw %xmm4, %xmm2 +; SSE4-NEXT: psubw %xmm4, %xmm1 +; SSE4-NEXT: psubw %xmm4, %xmm3 +; SSE4-NEXT: psrlw $1, %xmm3 +; SSE4-NEXT: psrlw $1, %xmm1 +; SSE4-NEXT: psrlw $1, %xmm2 +; SSE4-NEXT: psrlw $1, %xmm0 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm4 = [255,255,255,255,255,255,255,255] +; SSE4-NEXT: pand %xmm4, %xmm0 +; SSE4-NEXT: pand %xmm4, %xmm2 +; SSE4-NEXT: packuswb %xmm2, %xmm0 +; SSE4-NEXT: pand %xmm4, %xmm1 +; SSE4-NEXT: pand %xmm4, %xmm3 +; SSE4-NEXT: packuswb %xmm3, %xmm1 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v32i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 +; AVX1-NEXT: vpmovsxbw %xmm2, %xmm3 +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxbw %xmm0, %xmm4 +; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm5 +; AVX1-NEXT: vpmovsxbw %xmm5, %xmm6 +; AVX1-NEXT: vpaddw %xmm6, %xmm3, %xmm3 +; AVX1-NEXT: vpshufd {{.*#+}} xmm5 = xmm5[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm5, %xmm5 +; AVX1-NEXT: vpaddw %xmm5, %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxbw %xmm1, %xmm5 +; AVX1-NEXT: vpaddw %xmm5, %xmm4, %xmm4 +; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm1, %xmm1 +; AVX1-NEXT: vpaddw %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 +; AVX1-NEXT: vpsubw %xmm1, %xmm3, %xmm3 +; AVX1-NEXT: vpsubw %xmm1, %xmm2, %xmm2 +; AVX1-NEXT: vpsubw %xmm1, %xmm4, %xmm4 +; AVX1-NEXT: vpsubw %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm4, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm2, %xmm2 +; AVX1-NEXT: vpsrlw $1, %xmm3, %xmm3 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm4 = [255,255,255,255,255,255,255,255] +; AVX1-NEXT: vpand %xmm4, %xmm3, %xmm3 +; AVX1-NEXT: vpand %xmm4, %xmm2, %xmm2 +; AVX1-NEXT: vpackuswb %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vpand %xmm4, %xmm1, %xmm1 +; AVX1-NEXT: vpand %xmm4, %xmm0, %xmm0 +; AVX1-NEXT: vpackuswb %xmm0, %xmm1, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v32i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX2-NEXT: vpmovsxbw %xmm2, %ymm2 +; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm3 +; AVX2-NEXT: vpmovsxbw %xmm3, %ymm3 +; AVX2-NEXT: vpaddw %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vpmovsxbw %xmm1, %ymm1 +; AVX2-NEXT: vpaddw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubw %ymm1, %ymm2, %ymm2 +; AVX2-NEXT: vpsubw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm2, %ymm1 +; AVX2-NEXT: vpbroadcastw {{.*#+}} ymm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0] +; AVX2-NEXT: vpand %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpackuswb %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v32i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxbw %ymm0, %zmm0 +; AVX512-NEXT: vpmovsxbw %ymm1, %zmm1 +; AVX512-NEXT: vpaddw %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpternlogd $255, %zmm1, %zmm1, %zmm1 +; AVX512-NEXT: vpsubw %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovwb %zmm0, %ymm0 +; AVX512-NEXT: retq + %x0 = sext <32 x i8> %a0 to <32 x i16> + %x1 = sext <32 x i8> %a1 to <32 x i16> + %sum = add <32 x i16> %x0, %x1 + %inc = add <32 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %shift = ashr <32 x i16> %inc, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <32 x i16> %shift to <32 x i8> + ret <32 x i8> %res +} + +define <16 x i16> @test_fixed_v16i16(<16 x i16> %a0, <16 x i16> %a1) { +; SSE-LABEL: test_fixed_v16i16: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: por %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: por %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm0, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm3 +; SSE-NEXT: psraw $1, %xmm3 +; SSE-NEXT: psubw %xmm3, %xmm4 +; SSE-NEXT: psraw $1, %xmm2 +; SSE-NEXT: psubw %xmm2, %xmm5 +; SSE-NEXT: movdqa %xmm5, %xmm0 +; SSE-NEXT: movdqa %xmm4, %xmm1 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v16i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsraw $1, %xmm0, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsraw $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpsubw %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsubw %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v16i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsraw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsubw %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v16i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: vpsraw $1, %ymm0, %ymm0 +; AVX512-NEXT: vpsubw %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %or = or <16 x i16> %a0, %a1 + %xor = xor <16 x i16> %a1, %a0 + %shift = ashr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = sub <16 x i16> %or, %shift + ret <16 x i16> %res +} + +define <16 x i16> @test_ext_v16i16(<16 x i16> %a0, <16 x i16> %a1) { +; SSE2-LABEL: test_ext_v16i16: +; SSE2: # %bb.0: +; SSE2-NEXT: punpcklwd {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1],xmm4[2],xmm1[2],xmm4[3],xmm1[3] +; SSE2-NEXT: psrad $16, %xmm4 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm5 = xmm5[4],xmm1[4],xmm5[5],xmm1[5],xmm5[6],xmm1[6],xmm5[7],xmm1[7] +; SSE2-NEXT: psrad $16, %xmm5 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm6 = xmm6[0],xmm0[0],xmm6[1],xmm0[1],xmm6[2],xmm0[2],xmm6[3],xmm0[3] +; SSE2-NEXT: psrad $16, %xmm6 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm7 = xmm7[4],xmm0[4],xmm7[5],xmm0[5],xmm7[6],xmm0[6],xmm7[7],xmm0[7] +; SSE2-NEXT: psrad $16, %xmm7 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1],xmm1[2],xmm3[2],xmm1[3],xmm3[3] +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: paddd %xmm4, %xmm1 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4,4,5,5,6,6,7,7] +; SSE2-NEXT: psrad $16, %xmm3 +; SSE2-NEXT: paddd %xmm5, %xmm3 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: paddd %xmm6, %xmm0 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm2 = xmm2[4,4,5,5,6,6,7,7] +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: paddd %xmm7, %xmm2 +; SSE2-NEXT: pcmpeqd %xmm4, %xmm4 +; SSE2-NEXT: psubd %xmm4, %xmm1 +; SSE2-NEXT: psubd %xmm4, %xmm3 +; SSE2-NEXT: psubd %xmm4, %xmm0 +; SSE2-NEXT: psubd %xmm4, %xmm2 +; SSE2-NEXT: pslld $15, %xmm2 +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: pslld $15, %xmm0 +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: packssdw %xmm2, %xmm0 +; SSE2-NEXT: pslld $15, %xmm3 +; SSE2-NEXT: psrad $16, %xmm3 +; SSE2-NEXT: pslld $15, %xmm1 +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: packssdw %xmm3, %xmm1 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v16i16: +; SSE4: # %bb.0: +; SSE4-NEXT: pmovsxwd %xmm0, %xmm4 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm5 +; SSE4-NEXT: pmovsxwd %xmm1, %xmm6 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm7 +; SSE4-NEXT: pmovsxwd %xmm2, %xmm0 +; SSE4-NEXT: paddd %xmm4, %xmm0 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm1, %xmm2 +; SSE4-NEXT: paddd %xmm5, %xmm2 +; SSE4-NEXT: pmovsxwd %xmm3, %xmm1 +; SSE4-NEXT: paddd %xmm6, %xmm1 +; SSE4-NEXT: pshufd {{.*#+}} xmm3 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm3, %xmm3 +; SSE4-NEXT: paddd %xmm7, %xmm3 +; SSE4-NEXT: pcmpeqd %xmm4, %xmm4 +; SSE4-NEXT: psubd %xmm4, %xmm0 +; SSE4-NEXT: psubd %xmm4, %xmm2 +; SSE4-NEXT: psubd %xmm4, %xmm1 +; SSE4-NEXT: psubd %xmm4, %xmm3 +; SSE4-NEXT: psrld $1, %xmm3 +; SSE4-NEXT: psrld $1, %xmm1 +; SSE4-NEXT: psrld $1, %xmm2 +; SSE4-NEXT: psrld $1, %xmm0 +; SSE4-NEXT: pxor %xmm4, %xmm4 +; SSE4-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm4[1],xmm0[2],xmm4[3],xmm0[4],xmm4[5],xmm0[6],xmm4[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0],xmm4[1],xmm2[2],xmm4[3],xmm2[4],xmm4[5],xmm2[6],xmm4[7] +; SSE4-NEXT: packusdw %xmm2, %xmm0 +; SSE4-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm4[1],xmm1[2],xmm4[3],xmm1[4],xmm4[5],xmm1[6],xmm4[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0],xmm4[1],xmm3[2],xmm4[3],xmm3[4],xmm4[5],xmm3[6],xmm4[7] +; SSE4-NEXT: packusdw %xmm3, %xmm1 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v16i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 +; AVX1-NEXT: vpmovsxwd %xmm2, %xmm3 +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxwd %xmm0, %xmm4 +; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm5 +; AVX1-NEXT: vpmovsxwd %xmm5, %xmm6 +; AVX1-NEXT: vpaddd %xmm6, %xmm3, %xmm3 +; AVX1-NEXT: vpshufd {{.*#+}} xmm5 = xmm5[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm5, %xmm5 +; AVX1-NEXT: vpaddd %xmm5, %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxwd %xmm1, %xmm5 +; AVX1-NEXT: vpaddd %xmm5, %xmm4, %xmm4 +; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm1, %xmm1 +; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 +; AVX1-NEXT: vpsubd %xmm1, %xmm3, %xmm3 +; AVX1-NEXT: vpsubd %xmm1, %xmm2, %xmm2 +; AVX1-NEXT: vpsubd %xmm1, %xmm4, %xmm4 +; AVX1-NEXT: vpsubd %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm4, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm2, %xmm2 +; AVX1-NEXT: vpsrld $1, %xmm3, %xmm3 +; AVX1-NEXT: vpxor %xmm4, %xmm4, %xmm4 +; AVX1-NEXT: vpblendw {{.*#+}} xmm3 = xmm3[0],xmm4[1],xmm3[2],xmm4[3],xmm3[4],xmm4[5],xmm3[6],xmm4[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm2[0],xmm4[1],xmm2[2],xmm4[3],xmm2[4],xmm4[5],xmm2[6],xmm4[7] +; AVX1-NEXT: vpackusdw %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm4[1],xmm1[2],xmm4[3],xmm1[4],xmm4[5],xmm1[6],xmm4[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm4[1],xmm0[2],xmm4[3],xmm0[4],xmm4[5],xmm0[6],xmm4[7] +; AVX1-NEXT: vpackusdw %xmm0, %xmm1, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v16i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX2-NEXT: vpmovsxwd %xmm2, %ymm2 +; AVX2-NEXT: vpmovsxwd %xmm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm3 +; AVX2-NEXT: vpmovsxwd %xmm3, %ymm3 +; AVX2-NEXT: vpaddd %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vpmovsxwd %xmm1, %ymm1 +; AVX2-NEXT: vpaddd %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubd %ymm1, %ymm2, %ymm2 +; AVX2-NEXT: vpsubd %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm2, %ymm1 +; AVX2-NEXT: vpxor %xmm2, %xmm2, %xmm2 +; AVX2-NEXT: vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1],ymm1[2],ymm2[3],ymm1[4],ymm2[5],ymm1[6],ymm2[7],ymm1[8],ymm2[9],ymm1[10],ymm2[11],ymm1[12],ymm2[13],ymm1[14],ymm2[15] +; AVX2-NEXT: vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1],ymm0[2],ymm2[3],ymm0[4],ymm2[5],ymm0[6],ymm2[7],ymm0[8],ymm2[9],ymm0[10],ymm2[11],ymm0[12],ymm2[13],ymm0[14],ymm2[15] +; AVX2-NEXT: vpackusdw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v16i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxwd %ymm0, %zmm0 +; AVX512-NEXT: vpmovsxwd %ymm1, %zmm1 +; AVX512-NEXT: vpaddd %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpternlogd $255, %zmm1, %zmm1, %zmm1 +; AVX512-NEXT: vpsubd %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrld $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovdw %zmm0, %ymm0 +; AVX512-NEXT: retq + %x0 = sext <16 x i16> %a0 to <16 x i32> + %x1 = sext <16 x i16> %a1 to <16 x i32> + %sum = add <16 x i32> %x0, %x1 + %inc = add <16 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %shift = ashr <16 x i32> %inc, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <16 x i32> %shift to <16 x i16> + ret <16 x i16> %res +} + +define <8 x i32> @test_fixed_v8i32(<8 x i32> %a0, <8 x i32> %a1) { +; SSE-LABEL: test_fixed_v8i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: por %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: por %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm0, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm3 +; SSE-NEXT: psrad $1, %xmm3 +; SSE-NEXT: psubd %xmm3, %xmm4 +; SSE-NEXT: psrad $1, %xmm2 +; SSE-NEXT: psubd %xmm2, %xmm5 +; SSE-NEXT: movdqa %xmm5, %xmm0 +; SSE-NEXT: movdqa %xmm4, %xmm1 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v8i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpsubd %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsubd %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v8i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsrad $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsubd %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v8i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: vpsrad $1, %ymm0, %ymm0 +; AVX512-NEXT: vpsubd %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %or = or <8 x i32> %a0, %a1 + %xor = xor <8 x i32> %a1, %a0 + %shift = ashr <8 x i32> %xor, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = sub <8 x i32> %or, %shift + ret <8 x i32> %res +} + +define <8 x i32> @test_ext_v8i32(<8 x i32> %a0, <8 x i32> %a1) { +; SSE2-LABEL: test_ext_v8i32: +; SSE2: # %bb.0: +; SSE2-NEXT: pshufd {{.*#+}} xmm6 = xmm0[2,3,2,3] +; SSE2-NEXT: pxor %xmm5, %xmm5 +; SSE2-NEXT: pxor %xmm4, %xmm4 +; SSE2-NEXT: pcmpgtd %xmm6, %xmm4 +; SSE2-NEXT: punpckldq {{.*#+}} xmm6 = xmm6[0],xmm4[0],xmm6[1],xmm4[1] +; SSE2-NEXT: pxor %xmm4, %xmm4 +; SSE2-NEXT: pcmpgtd %xmm0, %xmm4 +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1] +; SSE2-NEXT: pshufd {{.*#+}} xmm7 = xmm1[2,3,2,3] +; SSE2-NEXT: pxor %xmm4, %xmm4 +; SSE2-NEXT: pcmpgtd %xmm7, %xmm4 +; SSE2-NEXT: punpckldq {{.*#+}} xmm7 = xmm7[0],xmm4[0],xmm7[1],xmm4[1] +; SSE2-NEXT: pxor %xmm4, %xmm4 +; SSE2-NEXT: pcmpgtd %xmm1, %xmm4 +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm4[0],xmm1[1],xmm4[1] +; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm2[2,3,2,3] +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: pcmpgtd %xmm4, %xmm8 +; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm8[0],xmm4[1],xmm8[1] +; SSE2-NEXT: paddq %xmm6, %xmm4 +; SSE2-NEXT: pxor %xmm6, %xmm6 +; SSE2-NEXT: pcmpgtd %xmm2, %xmm6 +; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm6[0],xmm2[1],xmm6[1] +; SSE2-NEXT: paddq %xmm2, %xmm0 +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm3[2,3,2,3] +; SSE2-NEXT: pxor %xmm6, %xmm6 +; SSE2-NEXT: pcmpgtd %xmm2, %xmm6 +; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm6[0],xmm2[1],xmm6[1] +; SSE2-NEXT: paddq %xmm7, %xmm2 +; SSE2-NEXT: pcmpgtd %xmm3, %xmm5 +; SSE2-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm5[0],xmm3[1],xmm5[1] +; SSE2-NEXT: paddq %xmm3, %xmm1 +; SSE2-NEXT: pcmpeqd %xmm3, %xmm3 +; SSE2-NEXT: psubq %xmm3, %xmm4 +; SSE2-NEXT: psubq %xmm3, %xmm0 +; SSE2-NEXT: psubq %xmm3, %xmm2 +; SSE2-NEXT: psubq %xmm3, %xmm1 +; SSE2-NEXT: psrlq $1, %xmm1 +; SSE2-NEXT: psrlq $1, %xmm2 +; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm2[0,2] +; SSE2-NEXT: psrlq $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm4 +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm4[0,2] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v8i32: +; SSE4: # %bb.0: +; SSE4-NEXT: pshufd {{.*#+}} xmm4 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm4, %xmm5 +; SSE4-NEXT: pmovsxdq %xmm0, %xmm6 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm7 +; SSE4-NEXT: pmovsxdq %xmm1, %xmm8 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm4 +; SSE4-NEXT: paddq %xmm5, %xmm4 +; SSE4-NEXT: pmovsxdq %xmm2, %xmm0 +; SSE4-NEXT: paddq %xmm6, %xmm0 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm1, %xmm2 +; SSE4-NEXT: paddq %xmm7, %xmm2 +; SSE4-NEXT: pmovsxdq %xmm3, %xmm1 +; SSE4-NEXT: paddq %xmm8, %xmm1 +; SSE4-NEXT: pcmpeqd %xmm3, %xmm3 +; SSE4-NEXT: psubq %xmm3, %xmm4 +; SSE4-NEXT: psubq %xmm3, %xmm0 +; SSE4-NEXT: psubq %xmm3, %xmm2 +; SSE4-NEXT: psubq %xmm3, %xmm1 +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm2[0,2] +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: psrlq $1, %xmm4 +; SSE4-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm4[0,2] +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v8i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vpmovsxdq %xmm0, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 +; AVX1-NEXT: vpmovsxdq %xmm3, %xmm4 +; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm3 = xmm3[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm3, %xmm3 +; AVX1-NEXT: vpmovsxdq %xmm1, %xmm5 +; AVX1-NEXT: vpaddq %xmm5, %xmm2, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm5 +; AVX1-NEXT: vpmovsxdq %xmm5, %xmm6 +; AVX1-NEXT: vpaddq %xmm6, %xmm4, %xmm4 +; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm1, %xmm1 +; AVX1-NEXT: vpaddq %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm5[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm1, %xmm1 +; AVX1-NEXT: vpaddq %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpcmpeqd %xmm3, %xmm3, %xmm3 +; AVX1-NEXT: vpsubq %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vpsubq %xmm3, %xmm4, %xmm4 +; AVX1-NEXT: vpsubq %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpsubq %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm4, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm2, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm3, %ymm2, %ymm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 +; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm2[0,2],ymm0[0,2],ymm2[4,6],ymm0[4,6] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v8i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxdq %xmm0, %ymm2 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vpmovsxdq %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxdq %xmm1, %ymm3 +; AVX2-NEXT: vpaddq %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX2-NEXT: vpmovsxdq %xmm1, %ymm1 +; AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubq %ymm1, %ymm2, %ymm2 +; AVX2-NEXT: vpsubq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm1 = ymm2[2,3],ymm0[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm2, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm1[0,2],ymm0[4,6],ymm1[4,6] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v8i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxdq %ymm0, %zmm0 +; AVX512-NEXT: vpmovsxdq %ymm1, %zmm1 +; AVX512-NEXT: vpaddq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpternlogd $255, %zmm1, %zmm1, %zmm1 +; AVX512-NEXT: vpsubq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovqd %zmm0, %ymm0 +; AVX512-NEXT: retq + %x0 = sext <8 x i32> %a0 to <8 x i64> + %x1 = sext <8 x i32> %a1 to <8 x i64> + %sum = add <8 x i64> %x0, %x1 + %inc = add <8 x i64> %sum, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %shift = ashr <8 x i64> %inc, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = trunc <8 x i64> %shift to <8 x i32> + ret <8 x i32> %res +} + +define <4 x i64> @test_fixed_v4i64(<4 x i64> %a0, <4 x i64> %a1) { +; SSE2-LABEL: test_fixed_v4i64: +; SSE2: # %bb.0: +; SSE2-NEXT: movdqa %xmm1, %xmm4 +; SSE2-NEXT: por %xmm3, %xmm4 +; SSE2-NEXT: movdqa %xmm0, %xmm5 +; SSE2-NEXT: por %xmm2, %xmm5 +; SSE2-NEXT: pxor %xmm0, %xmm2 +; SSE2-NEXT: pxor %xmm1, %xmm3 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm3[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm3 +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm3[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] +; SSE2-NEXT: psubq %xmm1, %xmm4 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm2 +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm2[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] +; SSE2-NEXT: psubq %xmm1, %xmm5 +; SSE2-NEXT: movdqa %xmm5, %xmm0 +; SSE2-NEXT: movdqa %xmm4, %xmm1 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_fixed_v4i64: +; SSE4: # %bb.0: +; SSE4-NEXT: movdqa %xmm1, %xmm4 +; SSE4-NEXT: por %xmm3, %xmm4 +; SSE4-NEXT: movdqa %xmm0, %xmm5 +; SSE4-NEXT: por %xmm2, %xmm5 +; SSE4-NEXT: pxor %xmm0, %xmm2 +; SSE4-NEXT: pxor %xmm1, %xmm3 +; SSE4-NEXT: movdqa %xmm3, %xmm0 +; SSE4-NEXT: psrad $1, %xmm0 +; SSE4-NEXT: psrlq $1, %xmm3 +; SSE4-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0,1],xmm0[2,3],xmm3[4,5],xmm0[6,7] +; SSE4-NEXT: psubq %xmm3, %xmm4 +; SSE4-NEXT: movdqa %xmm2, %xmm0 +; SSE4-NEXT: psrad $1, %xmm0 +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0,1],xmm0[2,3],xmm2[4,5],xmm0[6,7] +; SSE4-NEXT: psubq %xmm2, %xmm5 +; SSE4-NEXT: movdqa %xmm5, %xmm0 +; SSE4-NEXT: movdqa %xmm4, %xmm1 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_fixed_v4i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm3 +; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm3[0,1],xmm1[2,3],xmm3[4,5],xmm1[6,7] +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm3[2,3],xmm0[4,5],xmm3[6,7] +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpsubq %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsubq %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v4i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsrad $1, %ymm0, %ymm1 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[3],ymm0[4],ymm1[5],ymm0[6],ymm1[7] +; AVX2-NEXT: vpsubq %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v4i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: vpsraq $1, %ymm0, %ymm0 +; AVX512-NEXT: vpsubq %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %or = or <4 x i64> %a0, %a1 + %xor = xor <4 x i64> %a1, %a0 + %shift = ashr <4 x i64> %xor, <i64 1, i64 1, i64 1, i64 1> + %res = sub <4 x i64> %or, %shift + ret <4 x i64> %res +} + +define <4 x i64> @test_ext_v4i64(<4 x i64> %a0, <4 x i64> %a1) { +; SSE2-LABEL: test_ext_v4i64: +; SSE2: # %bb.0: +; SSE2-NEXT: pushq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: pushq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: pushq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: pushq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: pushq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: pushq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 56 +; SSE2-NEXT: .cfi_offset %rbx, -56 +; SSE2-NEXT: .cfi_offset %r12, -48 +; SSE2-NEXT: .cfi_offset %r13, -40 +; SSE2-NEXT: .cfi_offset %r14, -32 +; SSE2-NEXT: .cfi_offset %r15, -24 +; SSE2-NEXT: .cfi_offset %rbp, -16 +; SSE2-NEXT: movq %xmm0, %r11 +; SSE2-NEXT: movq %r11, %r12 +; SSE2-NEXT: sarq $63, %r12 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rcx +; SSE2-NEXT: movq %rcx, %rbx +; SSE2-NEXT: sarq $63, %rbx +; SSE2-NEXT: movq %xmm1, %rdx +; SSE2-NEXT: movq %rdx, %r14 +; SSE2-NEXT: sarq $63, %r14 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r9 +; SSE2-NEXT: movq %r9, %r15 +; SSE2-NEXT: sarq $63, %r15 +; SSE2-NEXT: movq %xmm2, %rsi +; SSE2-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %rsi +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r13 +; SSE2-NEXT: movq %r13, %r8 +; SSE2-NEXT: sarq $63, %r8 +; SSE2-NEXT: movq %xmm3, %rbp +; SSE2-NEXT: movq %rbp, %rdi +; SSE2-NEXT: sarq $63, %rdi +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rax +; SSE2-NEXT: movq %rax, %r10 +; SSE2-NEXT: sarq $63, %r10 +; SSE2-NEXT: addq %rax, %r9 +; SSE2-NEXT: adcq %r15, %r10 +; SSE2-NEXT: addq %rbp, %rdx +; SSE2-NEXT: adcq %r14, %rdi +; SSE2-NEXT: addq %r13, %rcx +; SSE2-NEXT: adcq %rbx, %r8 +; SSE2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; SSE2-NEXT: adcq %r12, %rsi +; SSE2-NEXT: addq $1, %r11 +; SSE2-NEXT: adcq $0, %rsi +; SSE2-NEXT: addq $1, %rcx +; SSE2-NEXT: adcq $0, %r8 +; SSE2-NEXT: addq $1, %rdx +; SSE2-NEXT: adcq $0, %rdi +; SSE2-NEXT: addq $1, %r9 +; SSE2-NEXT: adcq $0, %r10 +; SSE2-NEXT: shldq $63, %r9, %r10 +; SSE2-NEXT: shldq $63, %rdx, %rdi +; SSE2-NEXT: shldq $63, %rcx, %r8 +; SSE2-NEXT: shldq $63, %r11, %rsi +; SSE2-NEXT: movq %rsi, %xmm0 +; SSE2-NEXT: movq %r8, %xmm2 +; SSE2-NEXT: movq %rdi, %xmm1 +; SSE2-NEXT: movq %r10, %xmm3 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0] +; SSE2-NEXT: popq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: popq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: popq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: popq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: popq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: popq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 8 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v4i64: +; SSE4: # %bb.0: +; SSE4-NEXT: pushq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: pushq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: pushq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: pushq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: pushq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: pushq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 56 +; SSE4-NEXT: .cfi_offset %rbx, -56 +; SSE4-NEXT: .cfi_offset %r12, -48 +; SSE4-NEXT: .cfi_offset %r13, -40 +; SSE4-NEXT: .cfi_offset %r14, -32 +; SSE4-NEXT: .cfi_offset %r15, -24 +; SSE4-NEXT: .cfi_offset %rbp, -16 +; SSE4-NEXT: pextrq $1, %xmm0, %r11 +; SSE4-NEXT: movq %r11, %r12 +; SSE4-NEXT: sarq $63, %r12 +; SSE4-NEXT: movq %xmm0, %rcx +; SSE4-NEXT: movq %rcx, %rbx +; SSE4-NEXT: sarq $63, %rbx +; SSE4-NEXT: pextrq $1, %xmm1, %rdx +; SSE4-NEXT: movq %rdx, %r14 +; SSE4-NEXT: sarq $63, %r14 +; SSE4-NEXT: movq %xmm1, %r9 +; SSE4-NEXT: movq %r9, %r15 +; SSE4-NEXT: sarq $63, %r15 +; SSE4-NEXT: pextrq $1, %xmm2, %rsi +; SSE4-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %rsi +; SSE4-NEXT: movq %xmm2, %r13 +; SSE4-NEXT: movq %r13, %r8 +; SSE4-NEXT: sarq $63, %r8 +; SSE4-NEXT: pextrq $1, %xmm3, %rbp +; SSE4-NEXT: movq %rbp, %rdi +; SSE4-NEXT: sarq $63, %rdi +; SSE4-NEXT: movq %xmm3, %rax +; SSE4-NEXT: movq %rax, %r10 +; SSE4-NEXT: sarq $63, %r10 +; SSE4-NEXT: addq %rax, %r9 +; SSE4-NEXT: adcq %r15, %r10 +; SSE4-NEXT: addq %rbp, %rdx +; SSE4-NEXT: adcq %r14, %rdi +; SSE4-NEXT: addq %r13, %rcx +; SSE4-NEXT: adcq %rbx, %r8 +; SSE4-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; SSE4-NEXT: adcq %r12, %rsi +; SSE4-NEXT: addq $1, %r11 +; SSE4-NEXT: adcq $0, %rsi +; SSE4-NEXT: addq $1, %rcx +; SSE4-NEXT: adcq $0, %r8 +; SSE4-NEXT: addq $1, %rdx +; SSE4-NEXT: adcq $0, %rdi +; SSE4-NEXT: addq $1, %r9 +; SSE4-NEXT: adcq $0, %r10 +; SSE4-NEXT: shldq $63, %r9, %r10 +; SSE4-NEXT: shldq $63, %rdx, %rdi +; SSE4-NEXT: shldq $63, %rcx, %r8 +; SSE4-NEXT: shldq $63, %r11, %rsi +; SSE4-NEXT: movq %rsi, %xmm2 +; SSE4-NEXT: movq %r8, %xmm0 +; SSE4-NEXT: movq %rdi, %xmm3 +; SSE4-NEXT: movq %r10, %xmm1 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0] +; SSE4-NEXT: popq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: popq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: popq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: popq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: popq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: popq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 8 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v4i64: +; AVX1: # %bb.0: +; AVX1-NEXT: pushq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: pushq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: pushq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: pushq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: pushq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: pushq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 56 +; AVX1-NEXT: .cfi_offset %rbx, -56 +; AVX1-NEXT: .cfi_offset %r12, -48 +; AVX1-NEXT: .cfi_offset %r13, -40 +; AVX1-NEXT: .cfi_offset %r14, -32 +; AVX1-NEXT: .cfi_offset %r15, -24 +; AVX1-NEXT: .cfi_offset %rbp, -16 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 +; AVX1-NEXT: vpextrq $1, %xmm2, %r11 +; AVX1-NEXT: movq %r11, %r12 +; AVX1-NEXT: sarq $63, %r12 +; AVX1-NEXT: vmovq %xmm2, %rcx +; AVX1-NEXT: movq %rcx, %rbx +; AVX1-NEXT: sarq $63, %rbx +; AVX1-NEXT: vpextrq $1, %xmm0, %rdx +; AVX1-NEXT: movq %rdx, %r14 +; AVX1-NEXT: sarq $63, %r14 +; AVX1-NEXT: vmovq %xmm0, %r8 +; AVX1-NEXT: movq %r8, %r15 +; AVX1-NEXT: sarq $63, %r15 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm0 +; AVX1-NEXT: vpextrq $1, %xmm0, %rsi +; AVX1-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %rsi +; AVX1-NEXT: vmovq %xmm0, %r13 +; AVX1-NEXT: movq %r13, %rdi +; AVX1-NEXT: sarq $63, %rdi +; AVX1-NEXT: vpextrq $1, %xmm1, %rbp +; AVX1-NEXT: movq %rbp, %r9 +; AVX1-NEXT: sarq $63, %r9 +; AVX1-NEXT: vmovq %xmm1, %rax +; AVX1-NEXT: movq %rax, %r10 +; AVX1-NEXT: sarq $63, %r10 +; AVX1-NEXT: addq %rax, %r8 +; AVX1-NEXT: adcq %r15, %r10 +; AVX1-NEXT: addq %rbp, %rdx +; AVX1-NEXT: adcq %r14, %r9 +; AVX1-NEXT: addq %r13, %rcx +; AVX1-NEXT: adcq %rbx, %rdi +; AVX1-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; AVX1-NEXT: adcq %r12, %rsi +; AVX1-NEXT: addq $1, %r11 +; AVX1-NEXT: adcq $0, %rsi +; AVX1-NEXT: addq $1, %rcx +; AVX1-NEXT: adcq $0, %rdi +; AVX1-NEXT: addq $1, %rdx +; AVX1-NEXT: adcq $0, %r9 +; AVX1-NEXT: addq $1, %r8 +; AVX1-NEXT: adcq $0, %r10 +; AVX1-NEXT: shldq $63, %r8, %r10 +; AVX1-NEXT: shldq $63, %rdx, %r9 +; AVX1-NEXT: shldq $63, %rcx, %rdi +; AVX1-NEXT: shldq $63, %r11, %rsi +; AVX1-NEXT: vmovq %rsi, %xmm0 +; AVX1-NEXT: vmovq %rdi, %xmm1 +; AVX1-NEXT: vmovq %r9, %xmm2 +; AVX1-NEXT: vmovq %r10, %xmm3 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: popq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: popq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: popq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: popq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: popq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: popq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 8 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v4i64: +; AVX2: # %bb.0: +; AVX2-NEXT: pushq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: pushq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: pushq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: pushq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: pushq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: pushq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 56 +; AVX2-NEXT: .cfi_offset %rbx, -56 +; AVX2-NEXT: .cfi_offset %r12, -48 +; AVX2-NEXT: .cfi_offset %r13, -40 +; AVX2-NEXT: .cfi_offset %r14, -32 +; AVX2-NEXT: .cfi_offset %r15, -24 +; AVX2-NEXT: .cfi_offset %rbp, -16 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX2-NEXT: vpextrq $1, %xmm2, %r11 +; AVX2-NEXT: movq %r11, %r12 +; AVX2-NEXT: sarq $63, %r12 +; AVX2-NEXT: vmovq %xmm2, %rcx +; AVX2-NEXT: movq %rcx, %rbx +; AVX2-NEXT: sarq $63, %rbx +; AVX2-NEXT: vpextrq $1, %xmm0, %rdx +; AVX2-NEXT: movq %rdx, %r14 +; AVX2-NEXT: sarq $63, %r14 +; AVX2-NEXT: vmovq %xmm0, %r8 +; AVX2-NEXT: movq %r8, %r15 +; AVX2-NEXT: sarq $63, %r15 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm0 +; AVX2-NEXT: vpextrq $1, %xmm0, %rsi +; AVX2-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %rsi +; AVX2-NEXT: vmovq %xmm0, %r13 +; AVX2-NEXT: movq %r13, %rdi +; AVX2-NEXT: sarq $63, %rdi +; AVX2-NEXT: vpextrq $1, %xmm1, %rbp +; AVX2-NEXT: movq %rbp, %r9 +; AVX2-NEXT: sarq $63, %r9 +; AVX2-NEXT: vmovq %xmm1, %rax +; AVX2-NEXT: movq %rax, %r10 +; AVX2-NEXT: sarq $63, %r10 +; AVX2-NEXT: addq %rax, %r8 +; AVX2-NEXT: adcq %r15, %r10 +; AVX2-NEXT: addq %rbp, %rdx +; AVX2-NEXT: adcq %r14, %r9 +; AVX2-NEXT: addq %r13, %rcx +; AVX2-NEXT: adcq %rbx, %rdi +; AVX2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; AVX2-NEXT: adcq %r12, %rsi +; AVX2-NEXT: addq $1, %r11 +; AVX2-NEXT: adcq $0, %rsi +; AVX2-NEXT: addq $1, %rcx +; AVX2-NEXT: adcq $0, %rdi +; AVX2-NEXT: addq $1, %rdx +; AVX2-NEXT: adcq $0, %r9 +; AVX2-NEXT: addq $1, %r8 +; AVX2-NEXT: adcq $0, %r10 +; AVX2-NEXT: shldq $63, %r8, %r10 +; AVX2-NEXT: shldq $63, %rdx, %r9 +; AVX2-NEXT: shldq $63, %rcx, %rdi +; AVX2-NEXT: shldq $63, %r11, %rsi +; AVX2-NEXT: vmovq %rsi, %xmm0 +; AVX2-NEXT: vmovq %rdi, %xmm1 +; AVX2-NEXT: vmovq %r9, %xmm2 +; AVX2-NEXT: vmovq %r10, %xmm3 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX2-NEXT: popq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: popq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: popq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: popq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: popq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: popq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 8 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v4i64: +; AVX512: # %bb.0: +; AVX512-NEXT: pushq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: pushq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: pushq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: pushq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: pushq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: pushq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 56 +; AVX512-NEXT: .cfi_offset %rbx, -56 +; AVX512-NEXT: .cfi_offset %r12, -48 +; AVX512-NEXT: .cfi_offset %r13, -40 +; AVX512-NEXT: .cfi_offset %r14, -32 +; AVX512-NEXT: .cfi_offset %r15, -24 +; AVX512-NEXT: .cfi_offset %rbp, -16 +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX512-NEXT: vpextrq $1, %xmm2, %r11 +; AVX512-NEXT: movq %r11, %r12 +; AVX512-NEXT: sarq $63, %r12 +; AVX512-NEXT: vmovq %xmm2, %rcx +; AVX512-NEXT: movq %rcx, %rbx +; AVX512-NEXT: vpextrq $1, %xmm0, %rdx +; AVX512-NEXT: sarq $63, %rbx +; AVX512-NEXT: movq %rdx, %r14 +; AVX512-NEXT: sarq $63, %r14 +; AVX512-NEXT: vmovq %xmm0, %rdi +; AVX512-NEXT: movq %rdi, %r15 +; AVX512-NEXT: vextracti128 $1, %ymm1, %xmm0 +; AVX512-NEXT: vpextrq $1, %xmm0, %rsi +; AVX512-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r15 +; AVX512-NEXT: sarq $63, %rsi +; AVX512-NEXT: vmovq %xmm0, %r13 +; AVX512-NEXT: movq %r13, %r8 +; AVX512-NEXT: sarq $63, %r8 +; AVX512-NEXT: vpextrq $1, %xmm1, %rbp +; AVX512-NEXT: movq %rbp, %r9 +; AVX512-NEXT: sarq $63, %r9 +; AVX512-NEXT: vmovq %xmm1, %rax +; AVX512-NEXT: movq %rax, %r10 +; AVX512-NEXT: sarq $63, %r10 +; AVX512-NEXT: addq %rax, %rdi +; AVX512-NEXT: adcq %r15, %r10 +; AVX512-NEXT: addq %rbp, %rdx +; AVX512-NEXT: adcq %r14, %r9 +; AVX512-NEXT: addq %r13, %rcx +; AVX512-NEXT: adcq %rbx, %r8 +; AVX512-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; AVX512-NEXT: adcq %r12, %rsi +; AVX512-NEXT: addq $1, %r11 +; AVX512-NEXT: adcq $0, %rsi +; AVX512-NEXT: addq $1, %rcx +; AVX512-NEXT: adcq $0, %r8 +; AVX512-NEXT: addq $1, %rdx +; AVX512-NEXT: adcq $0, %r9 +; AVX512-NEXT: addq $1, %rdi +; AVX512-NEXT: adcq $0, %r10 +; AVX512-NEXT: shldq $63, %rdi, %r10 +; AVX512-NEXT: shldq $63, %rdx, %r9 +; AVX512-NEXT: shldq $63, %rcx, %r8 +; AVX512-NEXT: shldq $63, %r11, %rsi +; AVX512-NEXT: vmovq %rsi, %xmm0 +; AVX512-NEXT: vmovq %r8, %xmm1 +; AVX512-NEXT: vmovq %r9, %xmm2 +; AVX512-NEXT: vmovq %r10, %xmm3 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX512-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX512-NEXT: popq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: popq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: popq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: popq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: popq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: popq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 8 +; AVX512-NEXT: retq + %x0 = sext <4 x i64> %a0 to <4 x i128> + %x1 = sext <4 x i64> %a1 to <4 x i128> + %sum = add <4 x i128> %x0, %x1 + %inc = add <4 x i128> %sum, <i128 1, i128 1, i128 1, i128 1> + %shift = ashr <4 x i128> %inc, <i128 1, i128 1, i128 1, i128 1> + %res = trunc <4 x i128> %shift to <4 x i64> + ret <4 x i64> %res +} + +; +; 512-bit vectors +; + +define <64 x i8> @test_fixed_v64i8(<64 x i8> %a0, <64 x i8> %a1) { +; SSE-LABEL: test_fixed_v64i8: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm11 +; SSE-NEXT: movdqa %xmm2, %xmm8 +; SSE-NEXT: movdqa %xmm1, %xmm9 +; SSE-NEXT: movdqa %xmm0, %xmm10 +; SSE-NEXT: por %xmm7, %xmm3 +; SSE-NEXT: por %xmm6, %xmm2 +; SSE-NEXT: por %xmm5, %xmm1 +; SSE-NEXT: por %xmm4, %xmm0 +; SSE-NEXT: pxor %xmm4, %xmm10 +; SSE-NEXT: pxor %xmm5, %xmm9 +; SSE-NEXT: pxor %xmm6, %xmm8 +; SSE-NEXT: pxor %xmm7, %xmm11 +; SSE-NEXT: psrlw $1, %xmm11 +; SSE-NEXT: movdqa {{.*#+}} xmm5 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; SSE-NEXT: pand %xmm5, %xmm11 +; SSE-NEXT: movdqa {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; SSE-NEXT: pxor %xmm4, %xmm11 +; SSE-NEXT: psubb %xmm11, %xmm3 +; SSE-NEXT: psrlw $1, %xmm8 +; SSE-NEXT: pand %xmm5, %xmm8 +; SSE-NEXT: pxor %xmm4, %xmm8 +; SSE-NEXT: psubb %xmm8, %xmm2 +; SSE-NEXT: psrlw $1, %xmm9 +; SSE-NEXT: pand %xmm5, %xmm9 +; SSE-NEXT: pxor %xmm4, %xmm9 +; SSE-NEXT: psubb %xmm9, %xmm1 +; SSE-NEXT: psrlw $1, %xmm10 +; SSE-NEXT: pand %xmm5, %xmm10 +; SSE-NEXT: pxor %xmm4, %xmm10 +; SSE-NEXT: psubb %xmm10, %xmm0 +; SSE-NEXT: paddb %xmm4, %xmm0 +; SSE-NEXT: paddb %xmm4, %xmm1 +; SSE-NEXT: paddb %xmm4, %xmm2 +; SSE-NEXT: paddb %xmm4, %xmm3 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v64i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vorps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm2, %ymm0, %ymm0 +; AVX1-NEXT: vxorps %ymm3, %ymm1, %ymm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm2 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; AVX1-NEXT: vpand %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm6 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX1-NEXT: vpxor %xmm6, %xmm2, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpand %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpxor %xmm6, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm7 +; AVX1-NEXT: vpand %xmm3, %xmm7, %xmm7 +; AVX1-NEXT: vpxor %xmm6, %xmm7, %xmm7 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpxor %xmm6, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm3 +; AVX1-NEXT: vpsubb %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpaddb %xmm6, %xmm0, %xmm0 +; AVX1-NEXT: vpsubb %xmm7, %xmm5, %xmm3 +; AVX1-NEXT: vpaddb %xmm6, %xmm3, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpsubb %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpaddb %xmm6, %xmm1, %xmm1 +; AVX1-NEXT: vpsubb %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vpaddb %xmm6, %xmm2, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v64i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpor %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpxor %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm1, %ymm1 +; AVX2-NEXT: vpbroadcastb {{.*#+}} ymm2 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; AVX2-NEXT: vpand %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vpbroadcastb {{.*#+}} ymm3 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX2-NEXT: vpxor %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpsubb %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpxor %ymm3, %ymm0, %ymm0 +; AVX2-NEXT: vpsubb %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: vpaddb %ymm3, %ymm0, %ymm0 +; AVX2-NEXT: vpaddb %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v64i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vporq %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxorq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpbroadcastb {{.*#+}} zmm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX512-NEXT: vpternlogd $108, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to16}, %zmm1, %zmm0 +; AVX512-NEXT: vpsubb %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: vpaddb %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %or = or <64 x i8> %a0, %a1 + %xor = xor <64 x i8> %a0, %a1 + %shift = ashr <64 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = sub <64 x i8> %or, %shift + ret <64 x i8> %res +} + +define <64 x i8> @test_ext_v64i8(<64 x i8> %a0, <64 x i8> %a1) { +; SSE2-LABEL: test_ext_v64i8: +; SSE2: # %bb.0: +; SSE2-NEXT: movdqa %xmm3, %xmm8 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm14 = xmm14[8],xmm0[8],xmm14[9],xmm0[9],xmm14[10],xmm0[10],xmm14[11],xmm0[11],xmm14[12],xmm0[12],xmm14[13],xmm0[13],xmm14[14],xmm0[14],xmm14[15],xmm0[15] +; SSE2-NEXT: psraw $8, %xmm14 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm15 = xmm15[0],xmm0[0],xmm15[1],xmm0[1],xmm15[2],xmm0[2],xmm15[3],xmm0[3],xmm15[4],xmm0[4],xmm15[5],xmm0[5],xmm15[6],xmm0[6],xmm15[7],xmm0[7] +; SSE2-NEXT: psraw $8, %xmm15 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm1[8],xmm3[9],xmm1[9],xmm3[10],xmm1[10],xmm3[11],xmm1[11],xmm3[12],xmm1[12],xmm3[13],xmm1[13],xmm3[14],xmm1[14],xmm3[15],xmm1[15] +; SSE2-NEXT: psraw $8, %xmm3 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm13 = xmm13[0],xmm1[0],xmm13[1],xmm1[1],xmm13[2],xmm1[2],xmm13[3],xmm1[3],xmm13[4],xmm1[4],xmm13[5],xmm1[5],xmm13[6],xmm1[6],xmm13[7],xmm1[7] +; SSE2-NEXT: psraw $8, %xmm13 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm12 = xmm12[8],xmm2[8],xmm12[9],xmm2[9],xmm12[10],xmm2[10],xmm12[11],xmm2[11],xmm12[12],xmm2[12],xmm12[13],xmm2[13],xmm12[14],xmm2[14],xmm12[15],xmm2[15] +; SSE2-NEXT: psraw $8, %xmm12 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm11 = xmm11[0],xmm2[0],xmm11[1],xmm2[1],xmm11[2],xmm2[2],xmm11[3],xmm2[3],xmm11[4],xmm2[4],xmm11[5],xmm2[5],xmm11[6],xmm2[6],xmm11[7],xmm2[7] +; SSE2-NEXT: psraw $8, %xmm11 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm10 = xmm10[8],xmm8[8],xmm10[9],xmm8[9],xmm10[10],xmm8[10],xmm10[11],xmm8[11],xmm10[12],xmm8[12],xmm10[13],xmm8[13],xmm10[14],xmm8[14],xmm10[15],xmm8[15] +; SSE2-NEXT: psraw $8, %xmm10 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm9 = xmm9[0],xmm8[0],xmm9[1],xmm8[1],xmm9[2],xmm8[2],xmm9[3],xmm8[3],xmm9[4],xmm8[4],xmm9[5],xmm8[5],xmm9[6],xmm8[6],xmm9[7],xmm8[7] +; SSE2-NEXT: psraw $8, %xmm9 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm8 = xmm8[8],xmm4[8],xmm8[9],xmm4[9],xmm8[10],xmm4[10],xmm8[11],xmm4[11],xmm8[12],xmm4[12],xmm8[13],xmm4[13],xmm8[14],xmm4[14],xmm8[15],xmm4[15] +; SSE2-NEXT: psraw $8, %xmm8 +; SSE2-NEXT: paddw %xmm14, %xmm8 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1],xmm0[2],xmm4[2],xmm0[3],xmm4[3],xmm0[4],xmm4[4],xmm0[5],xmm4[5],xmm0[6],xmm4[6],xmm0[7],xmm4[7] +; SSE2-NEXT: psraw $8, %xmm0 +; SSE2-NEXT: paddw %xmm15, %xmm0 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm5[8],xmm4[9],xmm5[9],xmm4[10],xmm5[10],xmm4[11],xmm5[11],xmm4[12],xmm5[12],xmm4[13],xmm5[13],xmm4[14],xmm5[14],xmm4[15],xmm5[15] +; SSE2-NEXT: psraw $8, %xmm4 +; SSE2-NEXT: paddw %xmm3, %xmm4 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm5[0],xmm1[1],xmm5[1],xmm1[2],xmm5[2],xmm1[3],xmm5[3],xmm1[4],xmm5[4],xmm1[5],xmm5[5],xmm1[6],xmm5[6],xmm1[7],xmm5[7] +; SSE2-NEXT: psraw $8, %xmm1 +; SSE2-NEXT: paddw %xmm13, %xmm1 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm5 = xmm5[8],xmm6[8],xmm5[9],xmm6[9],xmm5[10],xmm6[10],xmm5[11],xmm6[11],xmm5[12],xmm6[12],xmm5[13],xmm6[13],xmm5[14],xmm6[14],xmm5[15],xmm6[15] +; SSE2-NEXT: psraw $8, %xmm5 +; SSE2-NEXT: paddw %xmm12, %xmm5 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm6[0],xmm2[1],xmm6[1],xmm2[2],xmm6[2],xmm2[3],xmm6[3],xmm2[4],xmm6[4],xmm2[5],xmm6[5],xmm2[6],xmm6[6],xmm2[7],xmm6[7] +; SSE2-NEXT: psraw $8, %xmm2 +; SSE2-NEXT: paddw %xmm11, %xmm2 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm6 = xmm6[8],xmm7[8],xmm6[9],xmm7[9],xmm6[10],xmm7[10],xmm6[11],xmm7[11],xmm6[12],xmm7[12],xmm6[13],xmm7[13],xmm6[14],xmm7[14],xmm6[15],xmm7[15] +; SSE2-NEXT: psraw $8, %xmm6 +; SSE2-NEXT: paddw %xmm10, %xmm6 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm7[0],xmm3[1],xmm7[1],xmm3[2],xmm7[2],xmm3[3],xmm7[3],xmm3[4],xmm7[4],xmm3[5],xmm7[5],xmm3[6],xmm7[6],xmm3[7],xmm7[7] +; SSE2-NEXT: psraw $8, %xmm3 +; SSE2-NEXT: paddw %xmm9, %xmm3 +; SSE2-NEXT: pcmpeqd %xmm7, %xmm7 +; SSE2-NEXT: psubw %xmm7, %xmm8 +; SSE2-NEXT: psubw %xmm7, %xmm0 +; SSE2-NEXT: psubw %xmm7, %xmm4 +; SSE2-NEXT: psubw %xmm7, %xmm1 +; SSE2-NEXT: psubw %xmm7, %xmm5 +; SSE2-NEXT: psubw %xmm7, %xmm2 +; SSE2-NEXT: psubw %xmm7, %xmm6 +; SSE2-NEXT: psubw %xmm7, %xmm3 +; SSE2-NEXT: psrlw $1, %xmm3 +; SSE2-NEXT: psrlw $1, %xmm6 +; SSE2-NEXT: psrlw $1, %xmm2 +; SSE2-NEXT: psrlw $1, %xmm5 +; SSE2-NEXT: psrlw $1, %xmm1 +; SSE2-NEXT: psrlw $1, %xmm4 +; SSE2-NEXT: psrlw $1, %xmm0 +; SSE2-NEXT: psrlw $1, %xmm8 +; SSE2-NEXT: movdqa {{.*#+}} xmm7 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0] +; SSE2-NEXT: pand %xmm7, %xmm8 +; SSE2-NEXT: pand %xmm7, %xmm0 +; SSE2-NEXT: packuswb %xmm8, %xmm0 +; SSE2-NEXT: pand %xmm7, %xmm4 +; SSE2-NEXT: pand %xmm7, %xmm1 +; SSE2-NEXT: packuswb %xmm4, %xmm1 +; SSE2-NEXT: pand %xmm7, %xmm5 +; SSE2-NEXT: pand %xmm7, %xmm2 +; SSE2-NEXT: packuswb %xmm5, %xmm2 +; SSE2-NEXT: pand %xmm7, %xmm6 +; SSE2-NEXT: pand %xmm7, %xmm3 +; SSE2-NEXT: packuswb %xmm6, %xmm3 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v64i8: +; SSE4: # %bb.0: +; SSE4-NEXT: pmovsxbw %xmm0, %xmm8 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm9 +; SSE4-NEXT: pmovsxbw %xmm1, %xmm10 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm11 +; SSE4-NEXT: pmovsxbw %xmm2, %xmm12 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm13 +; SSE4-NEXT: pmovsxbw %xmm3, %xmm14 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm15 +; SSE4-NEXT: pmovsxbw %xmm4, %xmm0 +; SSE4-NEXT: paddw %xmm8, %xmm0 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm4[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm1, %xmm4 +; SSE4-NEXT: paddw %xmm9, %xmm4 +; SSE4-NEXT: pmovsxbw %xmm5, %xmm1 +; SSE4-NEXT: paddw %xmm10, %xmm1 +; SSE4-NEXT: pshufd {{.*#+}} xmm2 = xmm5[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm2, %xmm5 +; SSE4-NEXT: paddw %xmm11, %xmm5 +; SSE4-NEXT: pmovsxbw %xmm6, %xmm2 +; SSE4-NEXT: paddw %xmm12, %xmm2 +; SSE4-NEXT: pshufd {{.*#+}} xmm3 = xmm6[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm3, %xmm6 +; SSE4-NEXT: paddw %xmm13, %xmm6 +; SSE4-NEXT: pmovsxbw %xmm7, %xmm3 +; SSE4-NEXT: paddw %xmm14, %xmm3 +; SSE4-NEXT: pshufd {{.*#+}} xmm7 = xmm7[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm7, %xmm7 +; SSE4-NEXT: paddw %xmm15, %xmm7 +; SSE4-NEXT: pcmpeqd %xmm8, %xmm8 +; SSE4-NEXT: psubw %xmm8, %xmm0 +; SSE4-NEXT: psubw %xmm8, %xmm4 +; SSE4-NEXT: psubw %xmm8, %xmm1 +; SSE4-NEXT: psubw %xmm8, %xmm5 +; SSE4-NEXT: psubw %xmm8, %xmm2 +; SSE4-NEXT: psubw %xmm8, %xmm6 +; SSE4-NEXT: psubw %xmm8, %xmm3 +; SSE4-NEXT: psubw %xmm8, %xmm7 +; SSE4-NEXT: psrlw $1, %xmm7 +; SSE4-NEXT: psrlw $1, %xmm3 +; SSE4-NEXT: psrlw $1, %xmm6 +; SSE4-NEXT: psrlw $1, %xmm2 +; SSE4-NEXT: psrlw $1, %xmm5 +; SSE4-NEXT: psrlw $1, %xmm1 +; SSE4-NEXT: psrlw $1, %xmm4 +; SSE4-NEXT: psrlw $1, %xmm0 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm8 = [255,255,255,255,255,255,255,255] +; SSE4-NEXT: pand %xmm8, %xmm0 +; SSE4-NEXT: pand %xmm8, %xmm4 +; SSE4-NEXT: packuswb %xmm4, %xmm0 +; SSE4-NEXT: pand %xmm8, %xmm1 +; SSE4-NEXT: pand %xmm8, %xmm5 +; SSE4-NEXT: packuswb %xmm5, %xmm1 +; SSE4-NEXT: pand %xmm8, %xmm2 +; SSE4-NEXT: pand %xmm8, %xmm6 +; SSE4-NEXT: packuswb %xmm6, %xmm2 +; SSE4-NEXT: pand %xmm8, %xmm3 +; SSE4-NEXT: pand %xmm8, %xmm7 +; SSE4-NEXT: packuswb %xmm7, %xmm3 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v64i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm4 +; AVX1-NEXT: vpmovsxbw %xmm4, %xmm5 +; AVX1-NEXT: vpshufd {{.*#+}} xmm4 = xmm4[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm4, %xmm4 +; AVX1-NEXT: vpmovsxbw %xmm0, %xmm6 +; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm7 +; AVX1-NEXT: vpmovsxbw %xmm7, %xmm8 +; AVX1-NEXT: vpshufd {{.*#+}} xmm7 = xmm7[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm7, %xmm7 +; AVX1-NEXT: vpmovsxbw %xmm1, %xmm9 +; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm1, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm10 +; AVX1-NEXT: vpmovsxbw %xmm10, %xmm11 +; AVX1-NEXT: vpaddw %xmm5, %xmm11, %xmm5 +; AVX1-NEXT: vpshufd {{.*#+}} xmm10 = xmm10[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm10, %xmm10 +; AVX1-NEXT: vpaddw %xmm4, %xmm10, %xmm4 +; AVX1-NEXT: vpmovsxbw %xmm2, %xmm10 +; AVX1-NEXT: vpaddw %xmm6, %xmm10, %xmm6 +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm2, %xmm2 +; AVX1-NEXT: vpaddw %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm2 +; AVX1-NEXT: vpmovsxbw %xmm2, %xmm10 +; AVX1-NEXT: vpaddw %xmm10, %xmm8, %xmm8 +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm2, %xmm2 +; AVX1-NEXT: vpaddw %xmm2, %xmm7, %xmm2 +; AVX1-NEXT: vpmovsxbw %xmm3, %xmm7 +; AVX1-NEXT: vpaddw %xmm7, %xmm9, %xmm7 +; AVX1-NEXT: vpshufd {{.*#+}} xmm3 = xmm3[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm3, %xmm3 +; AVX1-NEXT: vpaddw %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpcmpeqd %xmm3, %xmm3, %xmm3 +; AVX1-NEXT: vpsubw %xmm3, %xmm5, %xmm5 +; AVX1-NEXT: vpsubw %xmm3, %xmm4, %xmm4 +; AVX1-NEXT: vpsubw %xmm3, %xmm6, %xmm6 +; AVX1-NEXT: vpsubw %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpsubw %xmm3, %xmm8, %xmm8 +; AVX1-NEXT: vpsubw %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vpsubw %xmm3, %xmm7, %xmm7 +; AVX1-NEXT: vpsubw %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm7, %xmm3 +; AVX1-NEXT: vpsrlw $1, %xmm2, %xmm2 +; AVX1-NEXT: vpsrlw $1, %xmm8, %xmm7 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm6, %xmm6 +; AVX1-NEXT: vpsrlw $1, %xmm4, %xmm4 +; AVX1-NEXT: vpsrlw $1, %xmm5, %xmm5 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm8 = [255,255,255,255,255,255,255,255] +; AVX1-NEXT: vpand %xmm5, %xmm8, %xmm5 +; AVX1-NEXT: vpand %xmm4, %xmm8, %xmm4 +; AVX1-NEXT: vpackuswb %xmm4, %xmm5, %xmm4 +; AVX1-NEXT: vpand %xmm6, %xmm8, %xmm5 +; AVX1-NEXT: vpand %xmm0, %xmm8, %xmm0 +; AVX1-NEXT: vpackuswb %xmm0, %xmm5, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm4, %ymm0, %ymm0 +; AVX1-NEXT: vpand %xmm7, %xmm8, %xmm4 +; AVX1-NEXT: vpand %xmm2, %xmm8, %xmm2 +; AVX1-NEXT: vpackuswb %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vpand %xmm3, %xmm8, %xmm3 +; AVX1-NEXT: vpand %xmm1, %xmm8, %xmm1 +; AVX1-NEXT: vpackuswb %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v64i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm4 +; AVX2-NEXT: vpmovsxbw %xmm4, %ymm4 +; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm5 +; AVX2-NEXT: vpmovsxbw %xmm5, %ymm5 +; AVX2-NEXT: vpmovsxbw %xmm1, %ymm1 +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm6 +; AVX2-NEXT: vpmovsxbw %xmm6, %ymm6 +; AVX2-NEXT: vpaddw %ymm6, %ymm4, %ymm4 +; AVX2-NEXT: vpmovsxbw %xmm2, %ymm2 +; AVX2-NEXT: vpaddw %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm2 +; AVX2-NEXT: vpmovsxbw %xmm2, %ymm2 +; AVX2-NEXT: vpaddw %ymm2, %ymm5, %ymm2 +; AVX2-NEXT: vpmovsxbw %xmm3, %ymm3 +; AVX2-NEXT: vpaddw %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpcmpeqd %ymm3, %ymm3, %ymm3 +; AVX2-NEXT: vpsubw %ymm3, %ymm4, %ymm4 +; AVX2-NEXT: vpsubw %ymm3, %ymm0, %ymm0 +; AVX2-NEXT: vpsubw %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vpsubw %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm1, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm2, %ymm2 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm4, %ymm3 +; AVX2-NEXT: vpbroadcastw {{.*#+}} ymm4 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0] +; AVX2-NEXT: vpand %ymm4, %ymm3, %ymm3 +; AVX2-NEXT: vpand %ymm4, %ymm0, %ymm0 +; AVX2-NEXT: vpackuswb %ymm3, %ymm0, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: vpand %ymm4, %ymm2, %ymm2 +; AVX2-NEXT: vpand %ymm4, %ymm1, %ymm1 +; AVX2-NEXT: vpackuswb %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vpermq {{.*#+}} ymm1 = ymm1[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v64i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxbw %ymm0, %zmm2 +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm0 +; AVX512-NEXT: vpmovsxbw %ymm0, %zmm0 +; AVX512-NEXT: vpmovsxbw %ymm1, %zmm3 +; AVX512-NEXT: vpaddw %zmm3, %zmm2, %zmm2 +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm1 +; AVX512-NEXT: vpmovsxbw %ymm1, %zmm1 +; AVX512-NEXT: vpaddw %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpternlogd $255, %zmm1, %zmm1, %zmm1 +; AVX512-NEXT: vpsubw %zmm1, %zmm2, %zmm2 +; AVX512-NEXT: vpsubw %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlw $1, %zmm2, %zmm1 +; AVX512-NEXT: vpmovwb %zmm1, %ymm1 +; AVX512-NEXT: vpmovwb %zmm0, %ymm0 +; AVX512-NEXT: vinserti64x4 $1, %ymm0, %zmm1, %zmm0 +; AVX512-NEXT: retq + %x0 = sext <64 x i8> %a0 to <64 x i16> + %x1 = sext <64 x i8> %a1 to <64 x i16> + %sum = add <64 x i16> %x0, %x1 + %inc = add <64 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %shift = ashr <64 x i16> %inc, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <64 x i16> %shift to <64 x i8> + ret <64 x i8> %res +} + +define <32 x i16> @test_fixed_v32i16(<32 x i16> %a0, <32 x i16> %a1) { +; SSE-LABEL: test_fixed_v32i16: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm8 +; SSE-NEXT: por %xmm7, %xmm3 +; SSE-NEXT: movdqa %xmm2, %xmm9 +; SSE-NEXT: por %xmm6, %xmm9 +; SSE-NEXT: movdqa %xmm1, %xmm10 +; SSE-NEXT: por %xmm5, %xmm10 +; SSE-NEXT: movdqa %xmm0, %xmm11 +; SSE-NEXT: por %xmm4, %xmm11 +; SSE-NEXT: pxor %xmm0, %xmm4 +; SSE-NEXT: pxor %xmm1, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm6 +; SSE-NEXT: pxor %xmm8, %xmm7 +; SSE-NEXT: psraw $1, %xmm7 +; SSE-NEXT: psubw %xmm7, %xmm3 +; SSE-NEXT: psraw $1, %xmm6 +; SSE-NEXT: psubw %xmm6, %xmm9 +; SSE-NEXT: psraw $1, %xmm5 +; SSE-NEXT: psubw %xmm5, %xmm10 +; SSE-NEXT: psraw $1, %xmm4 +; SSE-NEXT: psubw %xmm4, %xmm11 +; SSE-NEXT: movdqa %xmm11, %xmm0 +; SSE-NEXT: movdqa %xmm10, %xmm1 +; SSE-NEXT: movdqa %xmm9, %xmm2 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v32i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vorps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsraw $1, %xmm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsraw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsraw $1, %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsraw $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpsubw %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpsubw %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpsubw %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpsubw %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v32i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpor %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsraw $1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubw %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsraw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsubw %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v32i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vporq %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxorq %zmm0, %zmm1, %zmm0 +; AVX512-NEXT: vpsraw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpsubw %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %or = or <32 x i16> %a0, %a1 + %xor = xor <32 x i16> %a1, %a0 + %shift = ashr <32 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = sub <32 x i16> %or, %shift + ret <32 x i16> %res +} + +define <32 x i16> @test_ext_v32i16(<32 x i16> %a0, <32 x i16> %a1) { +; SSE2-LABEL: test_ext_v32i16: +; SSE2: # %bb.0: +; SSE2-NEXT: punpcklwd {{.*#+}} xmm13 = xmm13[0],xmm3[0],xmm13[1],xmm3[1],xmm13[2],xmm3[2],xmm13[3],xmm3[3] +; SSE2-NEXT: psrad $16, %xmm13 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm14 = xmm14[4],xmm3[4],xmm14[5],xmm3[5],xmm14[6],xmm3[6],xmm14[7],xmm3[7] +; SSE2-NEXT: psrad $16, %xmm14 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm15 = xmm15[0],xmm2[0],xmm15[1],xmm2[1],xmm15[2],xmm2[2],xmm15[3],xmm2[3] +; SSE2-NEXT: psrad $16, %xmm15 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm12 = xmm12[4],xmm2[4],xmm12[5],xmm2[5],xmm12[6],xmm2[6],xmm12[7],xmm2[7] +; SSE2-NEXT: psrad $16, %xmm12 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm11 = xmm11[0],xmm1[0],xmm11[1],xmm1[1],xmm11[2],xmm1[2],xmm11[3],xmm1[3] +; SSE2-NEXT: psrad $16, %xmm11 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm10 = xmm10[4],xmm1[4],xmm10[5],xmm1[5],xmm10[6],xmm1[6],xmm10[7],xmm1[7] +; SSE2-NEXT: psrad $16, %xmm10 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm9 = xmm9[0],xmm0[0],xmm9[1],xmm0[1],xmm9[2],xmm0[2],xmm9[3],xmm0[3] +; SSE2-NEXT: psrad $16, %xmm9 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm8 = xmm8[4],xmm0[4],xmm8[5],xmm0[5],xmm8[6],xmm0[6],xmm8[7],xmm0[7] +; SSE2-NEXT: psrad $16, %xmm8 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm7[0],xmm3[1],xmm7[1],xmm3[2],xmm7[2],xmm3[3],xmm7[3] +; SSE2-NEXT: psrad $16, %xmm3 +; SSE2-NEXT: paddd %xmm13, %xmm3 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm7 = xmm7[4,4,5,5,6,6,7,7] +; SSE2-NEXT: psrad $16, %xmm7 +; SSE2-NEXT: paddd %xmm14, %xmm7 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm6[0],xmm2[1],xmm6[1],xmm2[2],xmm6[2],xmm2[3],xmm6[3] +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: paddd %xmm15, %xmm2 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm6 = xmm6[4,4,5,5,6,6,7,7] +; SSE2-NEXT: psrad $16, %xmm6 +; SSE2-NEXT: paddd %xmm12, %xmm6 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm5[0],xmm1[1],xmm5[1],xmm1[2],xmm5[2],xmm1[3],xmm5[3] +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: paddd %xmm11, %xmm1 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm5 = xmm5[4,4,5,5,6,6,7,7] +; SSE2-NEXT: psrad $16, %xmm5 +; SSE2-NEXT: paddd %xmm10, %xmm5 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1],xmm0[2],xmm4[2],xmm0[3],xmm4[3] +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: paddd %xmm9, %xmm0 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm4 = xmm4[4,4,5,5,6,6,7,7] +; SSE2-NEXT: psrad $16, %xmm4 +; SSE2-NEXT: paddd %xmm8, %xmm4 +; SSE2-NEXT: pcmpeqd %xmm8, %xmm8 +; SSE2-NEXT: psubd %xmm8, %xmm3 +; SSE2-NEXT: psubd %xmm8, %xmm7 +; SSE2-NEXT: psubd %xmm8, %xmm2 +; SSE2-NEXT: psubd %xmm8, %xmm6 +; SSE2-NEXT: psubd %xmm8, %xmm1 +; SSE2-NEXT: psubd %xmm8, %xmm5 +; SSE2-NEXT: psubd %xmm8, %xmm0 +; SSE2-NEXT: psubd %xmm8, %xmm4 +; SSE2-NEXT: pslld $15, %xmm4 +; SSE2-NEXT: psrad $16, %xmm4 +; SSE2-NEXT: pslld $15, %xmm0 +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: packssdw %xmm4, %xmm0 +; SSE2-NEXT: pslld $15, %xmm5 +; SSE2-NEXT: psrad $16, %xmm5 +; SSE2-NEXT: pslld $15, %xmm1 +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: packssdw %xmm5, %xmm1 +; SSE2-NEXT: pslld $15, %xmm6 +; SSE2-NEXT: psrad $16, %xmm6 +; SSE2-NEXT: pslld $15, %xmm2 +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: packssdw %xmm6, %xmm2 +; SSE2-NEXT: pslld $15, %xmm7 +; SSE2-NEXT: psrad $16, %xmm7 +; SSE2-NEXT: pslld $15, %xmm3 +; SSE2-NEXT: psrad $16, %xmm3 +; SSE2-NEXT: packssdw %xmm7, %xmm3 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v32i16: +; SSE4: # %bb.0: +; SSE4-NEXT: pmovsxwd %xmm0, %xmm8 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm9 +; SSE4-NEXT: pmovsxwd %xmm1, %xmm10 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm11 +; SSE4-NEXT: pmovsxwd %xmm2, %xmm12 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm13 +; SSE4-NEXT: pmovsxwd %xmm3, %xmm14 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm15 +; SSE4-NEXT: pmovsxwd %xmm4, %xmm0 +; SSE4-NEXT: paddd %xmm8, %xmm0 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm4[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm1, %xmm4 +; SSE4-NEXT: paddd %xmm9, %xmm4 +; SSE4-NEXT: pmovsxwd %xmm5, %xmm1 +; SSE4-NEXT: paddd %xmm10, %xmm1 +; SSE4-NEXT: pshufd {{.*#+}} xmm2 = xmm5[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm2, %xmm5 +; SSE4-NEXT: paddd %xmm11, %xmm5 +; SSE4-NEXT: pmovsxwd %xmm6, %xmm2 +; SSE4-NEXT: paddd %xmm12, %xmm2 +; SSE4-NEXT: pshufd {{.*#+}} xmm3 = xmm6[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm3, %xmm6 +; SSE4-NEXT: paddd %xmm13, %xmm6 +; SSE4-NEXT: pmovsxwd %xmm7, %xmm3 +; SSE4-NEXT: paddd %xmm14, %xmm3 +; SSE4-NEXT: pshufd {{.*#+}} xmm7 = xmm7[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm7, %xmm7 +; SSE4-NEXT: paddd %xmm15, %xmm7 +; SSE4-NEXT: pcmpeqd %xmm8, %xmm8 +; SSE4-NEXT: psubd %xmm8, %xmm0 +; SSE4-NEXT: psubd %xmm8, %xmm4 +; SSE4-NEXT: psubd %xmm8, %xmm1 +; SSE4-NEXT: psubd %xmm8, %xmm5 +; SSE4-NEXT: psubd %xmm8, %xmm2 +; SSE4-NEXT: psubd %xmm8, %xmm6 +; SSE4-NEXT: psubd %xmm8, %xmm3 +; SSE4-NEXT: psubd %xmm8, %xmm7 +; SSE4-NEXT: psrld $1, %xmm7 +; SSE4-NEXT: psrld $1, %xmm3 +; SSE4-NEXT: psrld $1, %xmm6 +; SSE4-NEXT: psrld $1, %xmm2 +; SSE4-NEXT: psrld $1, %xmm5 +; SSE4-NEXT: psrld $1, %xmm1 +; SSE4-NEXT: psrld $1, %xmm4 +; SSE4-NEXT: psrld $1, %xmm0 +; SSE4-NEXT: pxor %xmm8, %xmm8 +; SSE4-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm8[1],xmm0[2],xmm8[3],xmm0[4],xmm8[5],xmm0[6],xmm8[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm4 = xmm4[0],xmm8[1],xmm4[2],xmm8[3],xmm4[4],xmm8[5],xmm4[6],xmm8[7] +; SSE4-NEXT: packusdw %xmm4, %xmm0 +; SSE4-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm8[1],xmm1[2],xmm8[3],xmm1[4],xmm8[5],xmm1[6],xmm8[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm5 = xmm5[0],xmm8[1],xmm5[2],xmm8[3],xmm5[4],xmm8[5],xmm5[6],xmm8[7] +; SSE4-NEXT: packusdw %xmm5, %xmm1 +; SSE4-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0],xmm8[1],xmm2[2],xmm8[3],xmm2[4],xmm8[5],xmm2[6],xmm8[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm6 = xmm6[0],xmm8[1],xmm6[2],xmm8[3],xmm6[4],xmm8[5],xmm6[6],xmm8[7] +; SSE4-NEXT: packusdw %xmm6, %xmm2 +; SSE4-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0],xmm8[1],xmm3[2],xmm8[3],xmm3[4],xmm8[5],xmm3[6],xmm8[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm7 = xmm7[0],xmm8[1],xmm7[2],xmm8[3],xmm7[4],xmm8[5],xmm7[6],xmm8[7] +; SSE4-NEXT: packusdw %xmm7, %xmm3 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v32i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm4 +; AVX1-NEXT: vpmovsxwd %xmm4, %xmm5 +; AVX1-NEXT: vpshufd {{.*#+}} xmm4 = xmm4[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm4, %xmm4 +; AVX1-NEXT: vpmovsxwd %xmm0, %xmm6 +; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm7 +; AVX1-NEXT: vpmovsxwd %xmm7, %xmm8 +; AVX1-NEXT: vpshufd {{.*#+}} xmm7 = xmm7[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm7, %xmm7 +; AVX1-NEXT: vpmovsxwd %xmm1, %xmm9 +; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm1, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm10 +; AVX1-NEXT: vpmovsxwd %xmm10, %xmm11 +; AVX1-NEXT: vpaddd %xmm5, %xmm11, %xmm5 +; AVX1-NEXT: vpshufd {{.*#+}} xmm10 = xmm10[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm10, %xmm10 +; AVX1-NEXT: vpaddd %xmm4, %xmm10, %xmm4 +; AVX1-NEXT: vpmovsxwd %xmm2, %xmm10 +; AVX1-NEXT: vpaddd %xmm6, %xmm10, %xmm6 +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm2, %xmm2 +; AVX1-NEXT: vpaddd %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm2 +; AVX1-NEXT: vpmovsxwd %xmm2, %xmm10 +; AVX1-NEXT: vpaddd %xmm10, %xmm8, %xmm8 +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm2, %xmm2 +; AVX1-NEXT: vpaddd %xmm2, %xmm7, %xmm2 +; AVX1-NEXT: vpmovsxwd %xmm3, %xmm7 +; AVX1-NEXT: vpaddd %xmm7, %xmm9, %xmm7 +; AVX1-NEXT: vpshufd {{.*#+}} xmm3 = xmm3[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm3, %xmm3 +; AVX1-NEXT: vpaddd %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpcmpeqd %xmm3, %xmm3, %xmm3 +; AVX1-NEXT: vpsubd %xmm3, %xmm5, %xmm5 +; AVX1-NEXT: vpsubd %xmm3, %xmm4, %xmm4 +; AVX1-NEXT: vpsubd %xmm3, %xmm6, %xmm6 +; AVX1-NEXT: vpsubd %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpsubd %xmm3, %xmm8, %xmm8 +; AVX1-NEXT: vpsubd %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vpsubd %xmm3, %xmm7, %xmm7 +; AVX1-NEXT: vpsubd %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm7, %xmm3 +; AVX1-NEXT: vpsrld $1, %xmm2, %xmm2 +; AVX1-NEXT: vpsrld $1, %xmm8, %xmm7 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm6, %xmm6 +; AVX1-NEXT: vpsrld $1, %xmm4, %xmm4 +; AVX1-NEXT: vpsrld $1, %xmm5, %xmm5 +; AVX1-NEXT: vpxor %xmm8, %xmm8, %xmm8 +; AVX1-NEXT: vpblendw {{.*#+}} xmm5 = xmm5[0],xmm8[1],xmm5[2],xmm8[3],xmm5[4],xmm8[5],xmm5[6],xmm8[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm4 = xmm4[0],xmm8[1],xmm4[2],xmm8[3],xmm4[4],xmm8[5],xmm4[6],xmm8[7] +; AVX1-NEXT: vpackusdw %xmm4, %xmm5, %xmm4 +; AVX1-NEXT: vpblendw {{.*#+}} xmm5 = xmm6[0],xmm8[1],xmm6[2],xmm8[3],xmm6[4],xmm8[5],xmm6[6],xmm8[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm8[1],xmm0[2],xmm8[3],xmm0[4],xmm8[5],xmm0[6],xmm8[7] +; AVX1-NEXT: vpackusdw %xmm0, %xmm5, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm4, %ymm0, %ymm0 +; AVX1-NEXT: vpblendw {{.*#+}} xmm4 = xmm7[0],xmm8[1],xmm7[2],xmm8[3],xmm7[4],xmm8[5],xmm7[6],xmm8[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm2[0],xmm8[1],xmm2[2],xmm8[3],xmm2[4],xmm8[5],xmm2[6],xmm8[7] +; AVX1-NEXT: vpackusdw %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vpblendw {{.*#+}} xmm3 = xmm3[0],xmm8[1],xmm3[2],xmm8[3],xmm3[4],xmm8[5],xmm3[6],xmm8[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm8[1],xmm1[2],xmm8[3],xmm1[4],xmm8[5],xmm1[6],xmm8[7] +; AVX1-NEXT: vpackusdw %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v32i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm4 +; AVX2-NEXT: vpmovsxwd %xmm4, %ymm4 +; AVX2-NEXT: vpmovsxwd %xmm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm5 +; AVX2-NEXT: vpmovsxwd %xmm5, %ymm5 +; AVX2-NEXT: vpmovsxwd %xmm1, %ymm1 +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm6 +; AVX2-NEXT: vpmovsxwd %xmm6, %ymm6 +; AVX2-NEXT: vpaddd %ymm6, %ymm4, %ymm4 +; AVX2-NEXT: vpmovsxwd %xmm2, %ymm2 +; AVX2-NEXT: vpaddd %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm2 +; AVX2-NEXT: vpmovsxwd %xmm2, %ymm2 +; AVX2-NEXT: vpaddd %ymm2, %ymm5, %ymm2 +; AVX2-NEXT: vpmovsxwd %xmm3, %ymm3 +; AVX2-NEXT: vpaddd %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpcmpeqd %ymm3, %ymm3, %ymm3 +; AVX2-NEXT: vpsubd %ymm3, %ymm4, %ymm4 +; AVX2-NEXT: vpsubd %ymm3, %ymm0, %ymm0 +; AVX2-NEXT: vpsubd %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vpsubd %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpsrld $1, %ymm1, %ymm1 +; AVX2-NEXT: vpsrld $1, %ymm2, %ymm2 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm4, %ymm3 +; AVX2-NEXT: vpxor %xmm4, %xmm4, %xmm4 +; AVX2-NEXT: vpblendw {{.*#+}} ymm3 = ymm3[0],ymm4[1],ymm3[2],ymm4[3],ymm3[4],ymm4[5],ymm3[6],ymm4[7],ymm3[8],ymm4[9],ymm3[10],ymm4[11],ymm3[12],ymm4[13],ymm3[14],ymm4[15] +; AVX2-NEXT: vpblendw {{.*#+}} ymm0 = ymm0[0],ymm4[1],ymm0[2],ymm4[3],ymm0[4],ymm4[5],ymm0[6],ymm4[7],ymm0[8],ymm4[9],ymm0[10],ymm4[11],ymm0[12],ymm4[13],ymm0[14],ymm4[15] +; AVX2-NEXT: vpackusdw %ymm3, %ymm0, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: vpblendw {{.*#+}} ymm2 = ymm2[0],ymm4[1],ymm2[2],ymm4[3],ymm2[4],ymm4[5],ymm2[6],ymm4[7],ymm2[8],ymm4[9],ymm2[10],ymm4[11],ymm2[12],ymm4[13],ymm2[14],ymm4[15] +; AVX2-NEXT: vpblendw {{.*#+}} ymm1 = ymm1[0],ymm4[1],ymm1[2],ymm4[3],ymm1[4],ymm4[5],ymm1[6],ymm4[7],ymm1[8],ymm4[9],ymm1[10],ymm4[11],ymm1[12],ymm4[13],ymm1[14],ymm4[15] +; AVX2-NEXT: vpackusdw %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vpermq {{.*#+}} ymm1 = ymm1[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v32i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxwd %ymm0, %zmm2 +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm0 +; AVX512-NEXT: vpmovsxwd %ymm0, %zmm0 +; AVX512-NEXT: vpmovsxwd %ymm1, %zmm3 +; AVX512-NEXT: vpaddd %zmm3, %zmm2, %zmm2 +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm1 +; AVX512-NEXT: vpmovsxwd %ymm1, %zmm1 +; AVX512-NEXT: vpaddd %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpternlogd $255, %zmm1, %zmm1, %zmm1 +; AVX512-NEXT: vpsubd %zmm1, %zmm2, %zmm2 +; AVX512-NEXT: vpsubd %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrld $1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrld $1, %zmm2, %zmm1 +; AVX512-NEXT: vpmovdw %zmm1, %ymm1 +; AVX512-NEXT: vpmovdw %zmm0, %ymm0 +; AVX512-NEXT: vinserti64x4 $1, %ymm0, %zmm1, %zmm0 +; AVX512-NEXT: retq + %x0 = sext <32 x i16> %a0 to <32 x i32> + %x1 = sext <32 x i16> %a1 to <32 x i32> + %sum = add <32 x i32> %x0, %x1 + %inc = add <32 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %shift = ashr <32 x i32> %inc, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <32 x i32> %shift to <32 x i16> + ret <32 x i16> %res +} + +define <16 x i32> @test_fixed_v16i32(<16 x i32> %a0, <16 x i32> %a1) { +; SSE-LABEL: test_fixed_v16i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm8 +; SSE-NEXT: por %xmm7, %xmm3 +; SSE-NEXT: movdqa %xmm2, %xmm9 +; SSE-NEXT: por %xmm6, %xmm9 +; SSE-NEXT: movdqa %xmm1, %xmm10 +; SSE-NEXT: por %xmm5, %xmm10 +; SSE-NEXT: movdqa %xmm0, %xmm11 +; SSE-NEXT: por %xmm4, %xmm11 +; SSE-NEXT: pxor %xmm0, %xmm4 +; SSE-NEXT: pxor %xmm1, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm6 +; SSE-NEXT: pxor %xmm8, %xmm7 +; SSE-NEXT: psrad $1, %xmm7 +; SSE-NEXT: psubd %xmm7, %xmm3 +; SSE-NEXT: psrad $1, %xmm6 +; SSE-NEXT: psubd %xmm6, %xmm9 +; SSE-NEXT: psrad $1, %xmm5 +; SSE-NEXT: psubd %xmm5, %xmm10 +; SSE-NEXT: psrad $1, %xmm4 +; SSE-NEXT: psubd %xmm4, %xmm11 +; SSE-NEXT: movdqa %xmm11, %xmm0 +; SSE-NEXT: movdqa %xmm10, %xmm1 +; SSE-NEXT: movdqa %xmm9, %xmm2 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v16i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vorps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsrad $1, %xmm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrad $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpsubd %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpsubd %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpsubd %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpsubd %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v16i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpor %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsrad $1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubd %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsrad $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsubd %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v16i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpord %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxord %zmm0, %zmm1, %zmm0 +; AVX512-NEXT: vpsrad $1, %zmm0, %zmm0 +; AVX512-NEXT: vpsubd %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %or = or <16 x i32> %a0, %a1 + %xor = xor <16 x i32> %a1, %a0 + %shift = ashr <16 x i32> %xor, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = sub <16 x i32> %or, %shift + ret <16 x i32> %res +} + +define <16 x i32> @test_ext_v16i32(<16 x i32> %a0, <16 x i32> %a1) { +; SSE2-LABEL: test_ext_v16i32: +; SSE2: # %bb.0: +; SSE2-NEXT: pshufd {{.*#+}} xmm13 = xmm0[2,3,2,3] +; SSE2-NEXT: pxor %xmm9, %xmm9 +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: pcmpgtd %xmm13, %xmm8 +; SSE2-NEXT: punpckldq {{.*#+}} xmm13 = xmm13[0],xmm8[0],xmm13[1],xmm8[1] +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: pcmpgtd %xmm0, %xmm8 +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm8[0],xmm0[1],xmm8[1] +; SSE2-NEXT: pshufd {{.*#+}} xmm12 = xmm1[2,3,2,3] +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: pcmpgtd %xmm12, %xmm8 +; SSE2-NEXT: punpckldq {{.*#+}} xmm12 = xmm12[0],xmm8[0],xmm12[1],xmm8[1] +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: pcmpgtd %xmm1, %xmm8 +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm8[0],xmm1[1],xmm8[1] +; SSE2-NEXT: pshufd {{.*#+}} xmm11 = xmm2[2,3,2,3] +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: pcmpgtd %xmm11, %xmm8 +; SSE2-NEXT: punpckldq {{.*#+}} xmm11 = xmm11[0],xmm8[0],xmm11[1],xmm8[1] +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: pcmpgtd %xmm2, %xmm8 +; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm8[0],xmm2[1],xmm8[1] +; SSE2-NEXT: pshufd {{.*#+}} xmm10 = xmm3[2,3,2,3] +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: pcmpgtd %xmm10, %xmm8 +; SSE2-NEXT: punpckldq {{.*#+}} xmm10 = xmm10[0],xmm8[0],xmm10[1],xmm8[1] +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: pcmpgtd %xmm3, %xmm8 +; SSE2-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm8[0],xmm3[1],xmm8[1] +; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm4[2,3,2,3] +; SSE2-NEXT: pxor %xmm14, %xmm14 +; SSE2-NEXT: pcmpgtd %xmm8, %xmm14 +; SSE2-NEXT: punpckldq {{.*#+}} xmm8 = xmm8[0],xmm14[0],xmm8[1],xmm14[1] +; SSE2-NEXT: paddq %xmm13, %xmm8 +; SSE2-NEXT: pxor %xmm13, %xmm13 +; SSE2-NEXT: pcmpgtd %xmm4, %xmm13 +; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm13[0],xmm4[1],xmm13[1] +; SSE2-NEXT: paddq %xmm4, %xmm0 +; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm5[2,3,2,3] +; SSE2-NEXT: pxor %xmm13, %xmm13 +; SSE2-NEXT: pcmpgtd %xmm4, %xmm13 +; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm13[0],xmm4[1],xmm13[1] +; SSE2-NEXT: paddq %xmm12, %xmm4 +; SSE2-NEXT: pxor %xmm12, %xmm12 +; SSE2-NEXT: pcmpgtd %xmm5, %xmm12 +; SSE2-NEXT: punpckldq {{.*#+}} xmm5 = xmm5[0],xmm12[0],xmm5[1],xmm12[1] +; SSE2-NEXT: paddq %xmm5, %xmm1 +; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm6[2,3,2,3] +; SSE2-NEXT: pxor %xmm12, %xmm12 +; SSE2-NEXT: pcmpgtd %xmm5, %xmm12 +; SSE2-NEXT: punpckldq {{.*#+}} xmm5 = xmm5[0],xmm12[0],xmm5[1],xmm12[1] +; SSE2-NEXT: paddq %xmm11, %xmm5 +; SSE2-NEXT: pxor %xmm11, %xmm11 +; SSE2-NEXT: pcmpgtd %xmm6, %xmm11 +; SSE2-NEXT: punpckldq {{.*#+}} xmm6 = xmm6[0],xmm11[0],xmm6[1],xmm11[1] +; SSE2-NEXT: paddq %xmm6, %xmm2 +; SSE2-NEXT: pshufd {{.*#+}} xmm6 = xmm7[2,3,2,3] +; SSE2-NEXT: pxor %xmm11, %xmm11 +; SSE2-NEXT: pcmpgtd %xmm6, %xmm11 +; SSE2-NEXT: punpckldq {{.*#+}} xmm6 = xmm6[0],xmm11[0],xmm6[1],xmm11[1] +; SSE2-NEXT: paddq %xmm10, %xmm6 +; SSE2-NEXT: pcmpgtd %xmm7, %xmm9 +; SSE2-NEXT: punpckldq {{.*#+}} xmm7 = xmm7[0],xmm9[0],xmm7[1],xmm9[1] +; SSE2-NEXT: paddq %xmm7, %xmm3 +; SSE2-NEXT: pcmpeqd %xmm7, %xmm7 +; SSE2-NEXT: psubq %xmm7, %xmm8 +; SSE2-NEXT: psubq %xmm7, %xmm0 +; SSE2-NEXT: psubq %xmm7, %xmm4 +; SSE2-NEXT: psubq %xmm7, %xmm1 +; SSE2-NEXT: psubq %xmm7, %xmm5 +; SSE2-NEXT: psubq %xmm7, %xmm2 +; SSE2-NEXT: psubq %xmm7, %xmm6 +; SSE2-NEXT: psubq %xmm7, %xmm3 +; SSE2-NEXT: psrlq $1, %xmm3 +; SSE2-NEXT: psrlq $1, %xmm6 +; SSE2-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,2],xmm6[0,2] +; SSE2-NEXT: psrlq $1, %xmm2 +; SSE2-NEXT: psrlq $1, %xmm5 +; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm5[0,2] +; SSE2-NEXT: psrlq $1, %xmm1 +; SSE2-NEXT: psrlq $1, %xmm4 +; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm4[0,2] +; SSE2-NEXT: psrlq $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm8 +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm8[0,2] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v16i32: +; SSE4: # %bb.0: +; SSE4-NEXT: pshufd {{.*#+}} xmm8 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm8, %xmm9 +; SSE4-NEXT: pmovsxdq %xmm0, %xmm10 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm11 +; SSE4-NEXT: pmovsxdq %xmm1, %xmm12 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm13 +; SSE4-NEXT: pmovsxdq %xmm2, %xmm14 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm15 +; SSE4-NEXT: pmovsxdq %xmm3, %xmm0 +; SSE4-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm4[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm8 +; SSE4-NEXT: paddq %xmm9, %xmm8 +; SSE4-NEXT: pmovsxdq %xmm4, %xmm0 +; SSE4-NEXT: paddq %xmm10, %xmm0 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm5[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm1, %xmm4 +; SSE4-NEXT: paddq %xmm11, %xmm4 +; SSE4-NEXT: pmovsxdq %xmm5, %xmm1 +; SSE4-NEXT: paddq %xmm12, %xmm1 +; SSE4-NEXT: pshufd {{.*#+}} xmm2 = xmm6[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm2, %xmm5 +; SSE4-NEXT: paddq %xmm13, %xmm5 +; SSE4-NEXT: pmovsxdq %xmm6, %xmm2 +; SSE4-NEXT: paddq %xmm14, %xmm2 +; SSE4-NEXT: pshufd {{.*#+}} xmm3 = xmm7[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm3, %xmm6 +; SSE4-NEXT: paddq %xmm15, %xmm6 +; SSE4-NEXT: pmovsxdq %xmm7, %xmm3 +; SSE4-NEXT: paddq {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Folded Reload +; SSE4-NEXT: pcmpeqd %xmm7, %xmm7 +; SSE4-NEXT: psubq %xmm7, %xmm8 +; SSE4-NEXT: psubq %xmm7, %xmm0 +; SSE4-NEXT: psubq %xmm7, %xmm4 +; SSE4-NEXT: psubq %xmm7, %xmm1 +; SSE4-NEXT: psubq %xmm7, %xmm5 +; SSE4-NEXT: psubq %xmm7, %xmm2 +; SSE4-NEXT: psubq %xmm7, %xmm6 +; SSE4-NEXT: psubq %xmm7, %xmm3 +; SSE4-NEXT: psrlq $1, %xmm3 +; SSE4-NEXT: psrlq $1, %xmm6 +; SSE4-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,2],xmm6[0,2] +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: psrlq $1, %xmm5 +; SSE4-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm5[0,2] +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: psrlq $1, %xmm4 +; SSE4-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm4[0,2] +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: psrlq $1, %xmm8 +; SSE4-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm8[0,2] +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v16i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vpmovsxdq %xmm0, %xmm4 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm5 +; AVX1-NEXT: vpmovsxdq %xmm5, %xmm6 +; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm5 = xmm5[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm5, %xmm5 +; AVX1-NEXT: vpmovsxdq %xmm1, %xmm7 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm8 +; AVX1-NEXT: vpmovsxdq %xmm8, %xmm9 +; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm1, %xmm1 +; AVX1-NEXT: vpshufd {{.*#+}} xmm8 = xmm8[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm8, %xmm8 +; AVX1-NEXT: vpmovsxdq %xmm2, %xmm10 +; AVX1-NEXT: vpaddq %xmm4, %xmm10, %xmm4 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm10 +; AVX1-NEXT: vpmovsxdq %xmm10, %xmm11 +; AVX1-NEXT: vpaddq %xmm6, %xmm11, %xmm6 +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm2, %xmm2 +; AVX1-NEXT: vpaddq %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm10[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm2, %xmm2 +; AVX1-NEXT: vpaddq %xmm2, %xmm5, %xmm2 +; AVX1-NEXT: vpmovsxdq %xmm3, %xmm5 +; AVX1-NEXT: vpaddq %xmm5, %xmm7, %xmm5 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm7 +; AVX1-NEXT: vpmovsxdq %xmm7, %xmm10 +; AVX1-NEXT: vpaddq %xmm10, %xmm9, %xmm9 +; AVX1-NEXT: vpshufd {{.*#+}} xmm3 = xmm3[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm3, %xmm3 +; AVX1-NEXT: vpaddq %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpshufd {{.*#+}} xmm3 = xmm7[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm3, %xmm3 +; AVX1-NEXT: vpaddq %xmm3, %xmm8, %xmm3 +; AVX1-NEXT: vpcmpeqd %xmm7, %xmm7, %xmm7 +; AVX1-NEXT: vpsubq %xmm7, %xmm4, %xmm4 +; AVX1-NEXT: vpsubq %xmm7, %xmm6, %xmm6 +; AVX1-NEXT: vpsubq %xmm7, %xmm0, %xmm0 +; AVX1-NEXT: vpsubq %xmm7, %xmm2, %xmm2 +; AVX1-NEXT: vpsubq %xmm7, %xmm5, %xmm5 +; AVX1-NEXT: vpsubq %xmm7, %xmm9, %xmm8 +; AVX1-NEXT: vpsubq %xmm7, %xmm1, %xmm1 +; AVX1-NEXT: vpsubq %xmm7, %xmm3, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm3, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm8, %xmm7 +; AVX1-NEXT: vpsrlq $1, %xmm5, %xmm5 +; AVX1-NEXT: vpsrlq $1, %xmm2, %xmm2 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm6, %xmm6 +; AVX1-NEXT: vpsrlq $1, %xmm4, %xmm4 +; AVX1-NEXT: vinsertf128 $1, %xmm6, %ymm4, %ymm4 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 +; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm4[0,2],ymm0[0,2],ymm4[4,6],ymm0[4,6] +; AVX1-NEXT: vinsertf128 $1, %xmm7, %ymm5, %ymm2 +; AVX1-NEXT: vinsertf128 $1, %xmm3, %ymm1, %ymm1 +; AVX1-NEXT: vshufps {{.*#+}} ymm1 = ymm2[0,2],ymm1[0,2],ymm2[4,6],ymm1[4,6] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v16i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxdq %xmm1, %ymm4 +; AVX2-NEXT: vpmovsxdq %xmm0, %ymm5 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vpmovsxdq %xmm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX2-NEXT: vpmovsxdq %xmm1, %ymm1 +; AVX2-NEXT: vpmovsxdq %xmm3, %ymm6 +; AVX2-NEXT: vpaddq %ymm6, %ymm4, %ymm4 +; AVX2-NEXT: vpmovsxdq %xmm2, %ymm6 +; AVX2-NEXT: vpaddq %ymm6, %ymm5, %ymm5 +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm2 +; AVX2-NEXT: vpmovsxdq %xmm2, %ymm2 +; AVX2-NEXT: vpaddq %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm2 +; AVX2-NEXT: vpmovsxdq %xmm2, %ymm2 +; AVX2-NEXT: vpaddq %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vpcmpeqd %ymm2, %ymm2, %ymm2 +; AVX2-NEXT: vpsubq %ymm2, %ymm4, %ymm3 +; AVX2-NEXT: vpsubq %ymm2, %ymm5, %ymm4 +; AVX2-NEXT: vpsubq %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpsubq %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm2 = ymm4[2,3],ymm0[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm2, %ymm2 +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm4, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm2[0,2],ymm0[4,6],ymm2[4,6] +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm2 = ymm3[2,3],ymm1[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm2, %ymm2 +; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vshufps {{.*#+}} ymm1 = ymm1[0,2],ymm2[0,2],ymm1[4,6],ymm2[4,6] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v16i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxdq %ymm0, %zmm2 +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm0 +; AVX512-NEXT: vpmovsxdq %ymm0, %zmm0 +; AVX512-NEXT: vpmovsxdq %ymm1, %zmm3 +; AVX512-NEXT: vpaddq %zmm3, %zmm2, %zmm2 +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm1 +; AVX512-NEXT: vpmovsxdq %ymm1, %zmm1 +; AVX512-NEXT: vpaddq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpternlogd $255, %zmm1, %zmm1, %zmm1 +; AVX512-NEXT: vpsubq %zmm1, %zmm2, %zmm2 +; AVX512-NEXT: vpsubq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm2, %zmm1 +; AVX512-NEXT: vpmovqd %zmm1, %ymm1 +; AVX512-NEXT: vpmovqd %zmm0, %ymm0 +; AVX512-NEXT: vinserti64x4 $1, %ymm0, %zmm1, %zmm0 +; AVX512-NEXT: retq + %x0 = sext <16 x i32> %a0 to <16 x i64> + %x1 = sext <16 x i32> %a1 to <16 x i64> + %sum = add <16 x i64> %x0, %x1 + %inc = add <16 x i64> %sum, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %shift = ashr <16 x i64> %inc, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = trunc <16 x i64> %shift to <16 x i32> + ret <16 x i32> %res +} + +define <8 x i64> @test_fixed_v8i64(<8 x i64> %a0, <8 x i64> %a1) { +; SSE2-LABEL: test_fixed_v8i64: +; SSE2: # %bb.0: +; SSE2-NEXT: movdqa %xmm3, %xmm8 +; SSE2-NEXT: movdqa %xmm2, %xmm9 +; SSE2-NEXT: movdqa %xmm1, %xmm10 +; SSE2-NEXT: movdqa %xmm0, %xmm11 +; SSE2-NEXT: por %xmm7, %xmm3 +; SSE2-NEXT: por %xmm6, %xmm2 +; SSE2-NEXT: por %xmm5, %xmm1 +; SSE2-NEXT: por %xmm4, %xmm0 +; SSE2-NEXT: pxor %xmm11, %xmm4 +; SSE2-NEXT: pxor %xmm10, %xmm5 +; SSE2-NEXT: pxor %xmm9, %xmm6 +; SSE2-NEXT: pxor %xmm8, %xmm7 +; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm7[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm8 +; SSE2-NEXT: psrlq $1, %xmm7 +; SSE2-NEXT: pshufd {{.*#+}} xmm7 = xmm7[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm7 = xmm7[0],xmm8[0],xmm7[1],xmm8[1] +; SSE2-NEXT: psubq %xmm7, %xmm3 +; SSE2-NEXT: pshufd {{.*#+}} xmm7 = xmm6[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm7 +; SSE2-NEXT: psrlq $1, %xmm6 +; SSE2-NEXT: pshufd {{.*#+}} xmm6 = xmm6[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm6 = xmm6[0],xmm7[0],xmm6[1],xmm7[1] +; SSE2-NEXT: psubq %xmm6, %xmm2 +; SSE2-NEXT: pshufd {{.*#+}} xmm6 = xmm5[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm6 +; SSE2-NEXT: psrlq $1, %xmm5 +; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm5[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm5 = xmm5[0],xmm6[0],xmm5[1],xmm6[1] +; SSE2-NEXT: psubq %xmm5, %xmm1 +; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm4[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm5 +; SSE2-NEXT: psrlq $1, %xmm4 +; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm5[0],xmm4[1],xmm5[1] +; SSE2-NEXT: psubq %xmm4, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_fixed_v8i64: +; SSE4: # %bb.0: +; SSE4-NEXT: movdqa %xmm3, %xmm8 +; SSE4-NEXT: movdqa %xmm2, %xmm9 +; SSE4-NEXT: movdqa %xmm1, %xmm10 +; SSE4-NEXT: movdqa %xmm0, %xmm11 +; SSE4-NEXT: por %xmm7, %xmm3 +; SSE4-NEXT: por %xmm6, %xmm2 +; SSE4-NEXT: por %xmm5, %xmm1 +; SSE4-NEXT: por %xmm4, %xmm0 +; SSE4-NEXT: pxor %xmm11, %xmm4 +; SSE4-NEXT: pxor %xmm10, %xmm5 +; SSE4-NEXT: pxor %xmm9, %xmm6 +; SSE4-NEXT: pxor %xmm8, %xmm7 +; SSE4-NEXT: movdqa %xmm7, %xmm8 +; SSE4-NEXT: psrad $1, %xmm8 +; SSE4-NEXT: psrlq $1, %xmm7 +; SSE4-NEXT: pblendw {{.*#+}} xmm7 = xmm7[0,1],xmm8[2,3],xmm7[4,5],xmm8[6,7] +; SSE4-NEXT: psubq %xmm7, %xmm3 +; SSE4-NEXT: movdqa %xmm6, %xmm7 +; SSE4-NEXT: psrad $1, %xmm7 +; SSE4-NEXT: psrlq $1, %xmm6 +; SSE4-NEXT: pblendw {{.*#+}} xmm6 = xmm6[0,1],xmm7[2,3],xmm6[4,5],xmm7[6,7] +; SSE4-NEXT: psubq %xmm6, %xmm2 +; SSE4-NEXT: movdqa %xmm5, %xmm6 +; SSE4-NEXT: psrad $1, %xmm6 +; SSE4-NEXT: psrlq $1, %xmm5 +; SSE4-NEXT: pblendw {{.*#+}} xmm5 = xmm5[0,1],xmm6[2,3],xmm5[4,5],xmm6[6,7] +; SSE4-NEXT: psubq %xmm5, %xmm1 +; SSE4-NEXT: movdqa %xmm4, %xmm5 +; SSE4-NEXT: psrad $1, %xmm5 +; SSE4-NEXT: psrlq $1, %xmm4 +; SSE4-NEXT: pblendw {{.*#+}} xmm4 = xmm4[0,1],xmm5[2,3],xmm4[4,5],xmm5[6,7] +; SSE4-NEXT: psubq %xmm4, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_fixed_v8i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vorps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsrad $1, %xmm1, %xmm2 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm3 +; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm3[0,1],xmm2[2,3],xmm3[4,5],xmm2[6,7] +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrad $1, %xmm1, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm1 +; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7] +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm6 +; AVX1-NEXT: vpblendw {{.*#+}} xmm3 = xmm6[0,1],xmm3[2,3],xmm6[4,5],xmm3[6,7] +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm6 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm6[2,3],xmm0[4,5],xmm6[6,7] +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpsubq %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpsubq %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpsubq %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpsubq %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v8i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpor %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsrad $1, %ymm1, %ymm2 +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vpblendd {{.*#+}} ymm1 = ymm1[0],ymm2[1],ymm1[2],ymm2[3],ymm1[4],ymm2[5],ymm1[6],ymm2[7] +; AVX2-NEXT: vpsubq %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsrad $1, %ymm0, %ymm2 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0],ymm2[1],ymm0[2],ymm2[3],ymm0[4],ymm2[5],ymm0[6],ymm2[7] +; AVX2-NEXT: vpsubq %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v8i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vporq %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxorq %zmm0, %zmm1, %zmm0 +; AVX512-NEXT: vpsraq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpsubq %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %or = or <8 x i64> %a0, %a1 + %xor = xor <8 x i64> %a1, %a0 + %shift = ashr <8 x i64> %xor, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = sub <8 x i64> %or, %shift + ret <8 x i64> %res +} + +define <8 x i64> @test_ext_v8i64(<8 x i64> %a0, <8 x i64> %a1) { +; SSE2-LABEL: test_ext_v8i64: +; SSE2: # %bb.0: +; SSE2-NEXT: pushq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: pushq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: pushq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: pushq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: pushq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: pushq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 56 +; SSE2-NEXT: pushq %rax +; SSE2-NEXT: .cfi_def_cfa_offset 64 +; SSE2-NEXT: .cfi_offset %rbx, -56 +; SSE2-NEXT: .cfi_offset %r12, -48 +; SSE2-NEXT: .cfi_offset %r13, -40 +; SSE2-NEXT: .cfi_offset %r14, -32 +; SSE2-NEXT: .cfi_offset %r15, -24 +; SSE2-NEXT: .cfi_offset %rbp, -16 +; SSE2-NEXT: movq %xmm0, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %rax +; SSE2-NEXT: movq %rax, (%rsp) # 8-byte Spill +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %xmm1, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %xmm2, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %xmm3, %rbx +; SSE2-NEXT: movq %rbx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %rbx +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rdi +; SSE2-NEXT: movq %rdi, %rbp +; SSE2-NEXT: sarq $63, %rbp +; SSE2-NEXT: movq %xmm4, %r8 +; SSE2-NEXT: movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %r8 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm4[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r11 +; SSE2-NEXT: movq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %r11 +; SSE2-NEXT: movq %xmm5, %r10 +; SSE2-NEXT: movq %r10, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %r10 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm5[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r15 +; SSE2-NEXT: movq %r15, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %r15 +; SSE2-NEXT: movq %xmm6, %r9 +; SSE2-NEXT: movq %r9, %r14 +; SSE2-NEXT: sarq $63, %r14 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm6[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rsi +; SSE2-NEXT: movq %rsi, %r13 +; SSE2-NEXT: sarq $63, %r13 +; SSE2-NEXT: movq %xmm7, %rdx +; SSE2-NEXT: movq %rdx, %r12 +; SSE2-NEXT: sarq $63, %r12 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm7[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rax +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: addq %rax, %rdi +; SSE2-NEXT: adcq %rbp, %rcx +; SSE2-NEXT: addq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; SSE2-NEXT: adcq %rbx, %r12 +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbp # 8-byte Reload +; SSE2-NEXT: addq %rsi, %rbp +; SSE2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r13 # 8-byte Folded Reload +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload +; SSE2-NEXT: addq %r9, %rbx +; SSE2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Folded Reload +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Reload +; SSE2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Folded Reload +; SSE2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Folded Reload +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload +; SSE2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Folded Reload +; SSE2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Folded Reload +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload +; SSE2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Folded Reload +; SSE2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; SSE2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Folded Reload +; SSE2-NEXT: adcq (%rsp), %r8 # 8-byte Folded Reload +; SSE2-NEXT: addq $1, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: adcq $0, %r8 +; SSE2-NEXT: addq $1, %rdx +; SSE2-NEXT: adcq $0, %r11 +; SSE2-NEXT: addq $1, %rsi +; SSE2-NEXT: adcq $0, %r10 +; SSE2-NEXT: addq $1, %r9 +; SSE2-NEXT: adcq $0, %r15 +; SSE2-NEXT: addq $1, %rbx +; SSE2-NEXT: adcq $0, %r14 +; SSE2-NEXT: addq $1, %rbp +; SSE2-NEXT: adcq $0, %r13 +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; SSE2-NEXT: addq $1, %rax +; SSE2-NEXT: adcq $0, %r12 +; SSE2-NEXT: addq $1, %rdi +; SSE2-NEXT: adcq $0, %rcx +; SSE2-NEXT: shldq $63, %rdi, %rcx +; SSE2-NEXT: shldq $63, %rax, %r12 +; SSE2-NEXT: shldq $63, %rbp, %r13 +; SSE2-NEXT: shldq $63, %rbx, %r14 +; SSE2-NEXT: shldq $63, %r9, %r15 +; SSE2-NEXT: shldq $63, %rsi, %r10 +; SSE2-NEXT: shldq $63, %rdx, %r11 +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; SSE2-NEXT: shldq $63, %rax, %r8 +; SSE2-NEXT: movq %r8, %xmm0 +; SSE2-NEXT: movq %r11, %xmm4 +; SSE2-NEXT: movq %r10, %xmm1 +; SSE2-NEXT: movq %r15, %xmm5 +; SSE2-NEXT: movq %r14, %xmm2 +; SSE2-NEXT: movq %r13, %xmm6 +; SSE2-NEXT: movq %r12, %xmm3 +; SSE2-NEXT: movq %rcx, %xmm7 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm5[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm6[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm7[0] +; SSE2-NEXT: addq $8, %rsp +; SSE2-NEXT: .cfi_def_cfa_offset 56 +; SSE2-NEXT: popq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: popq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: popq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: popq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: popq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: popq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 8 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v8i64: +; SSE4: # %bb.0: +; SSE4-NEXT: pushq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: pushq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: pushq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: pushq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: pushq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: pushq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 56 +; SSE4-NEXT: subq $16, %rsp +; SSE4-NEXT: .cfi_def_cfa_offset 72 +; SSE4-NEXT: .cfi_offset %rbx, -56 +; SSE4-NEXT: .cfi_offset %r12, -48 +; SSE4-NEXT: .cfi_offset %r13, -40 +; SSE4-NEXT: .cfi_offset %r14, -32 +; SSE4-NEXT: .cfi_offset %r15, -24 +; SSE4-NEXT: .cfi_offset %rbp, -16 +; SSE4-NEXT: pextrq $1, %xmm0, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %xmm0, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: movq %rcx, (%rsp) # 8-byte Spill +; SSE4-NEXT: pextrq $1, %xmm1, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %xmm1, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: pextrq $1, %xmm2, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %xmm2, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: pextrq $1, %xmm3, %r13 +; SSE4-NEXT: movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %r13 +; SSE4-NEXT: movq %xmm3, %rax +; SSE4-NEXT: movq %rax, %rsi +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rsi +; SSE4-NEXT: pextrq $1, %xmm4, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %xmm4, %r11 +; SSE4-NEXT: movq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %r11 +; SSE4-NEXT: pextrq $1, %xmm5, %r10 +; SSE4-NEXT: movq %r10, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %r10 +; SSE4-NEXT: movq %xmm5, %rax +; SSE4-NEXT: movq %rax, %r14 +; SSE4-NEXT: sarq $63, %r14 +; SSE4-NEXT: pextrq $1, %xmm6, %rdi +; SSE4-NEXT: movq %rdi, %rbx +; SSE4-NEXT: sarq $63, %rbx +; SSE4-NEXT: movq %xmm6, %rdx +; SSE4-NEXT: movq %rdx, %r12 +; SSE4-NEXT: sarq $63, %r12 +; SSE4-NEXT: pextrq $1, %xmm7, %r15 +; SSE4-NEXT: movq %r15, %r9 +; SSE4-NEXT: sarq $63, %r9 +; SSE4-NEXT: movq %xmm7, %rbp +; SSE4-NEXT: movq %rbp, %r8 +; SSE4-NEXT: sarq $63, %r8 +; SSE4-NEXT: addq %rbp, %rcx +; SSE4-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: adcq %rsi, %r8 +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; SSE4-NEXT: addq %r15, %rcx +; SSE4-NEXT: adcq %r13, %r9 +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbp # 8-byte Reload +; SSE4-NEXT: addq %rdx, %rbp +; SSE4-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Folded Reload +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 # 8-byte Reload +; SSE4-NEXT: addq %rdi, %r13 +; SSE4-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Folded Reload +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Reload +; SSE4-NEXT: addq %rax, %r15 +; SSE4-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Folded Reload +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi # 8-byte Reload +; SSE4-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rdi # 8-byte Folded Reload +; SSE4-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Folded Reload +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload +; SSE4-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Folded Reload +; SSE4-NEXT: adcq (%rsp), %r11 # 8-byte Folded Reload +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload +; SSE4-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Folded Reload +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; SSE4-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Folded Reload +; SSE4-NEXT: addq $1, %rdx +; SSE4-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: adcq $0, %rax +; SSE4-NEXT: movq %rax, %rdx +; SSE4-NEXT: addq $1, %rsi +; SSE4-NEXT: adcq $0, %r11 +; SSE4-NEXT: addq $1, %rdi +; SSE4-NEXT: adcq $0, %r10 +; SSE4-NEXT: addq $1, %r15 +; SSE4-NEXT: adcq $0, %r14 +; SSE4-NEXT: addq $1, %r13 +; SSE4-NEXT: adcq $0, %rbx +; SSE4-NEXT: addq $1, %rbp +; SSE4-NEXT: adcq $0, %r12 +; SSE4-NEXT: addq $1, %rcx +; SSE4-NEXT: adcq $0, %r9 +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; SSE4-NEXT: addq $1, %rax +; SSE4-NEXT: adcq $0, %r8 +; SSE4-NEXT: shldq $63, %rax, %r8 +; SSE4-NEXT: shldq $63, %rcx, %r9 +; SSE4-NEXT: shldq $63, %rbp, %r12 +; SSE4-NEXT: shldq $63, %r13, %rbx +; SSE4-NEXT: shldq $63, %r15, %r14 +; SSE4-NEXT: shldq $63, %rdi, %r10 +; SSE4-NEXT: shldq $63, %rsi, %r11 +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; SSE4-NEXT: shldq $63, %rcx, %rdx +; SSE4-NEXT: movq %rdx, %xmm4 +; SSE4-NEXT: movq %r11, %xmm0 +; SSE4-NEXT: movq %r10, %xmm5 +; SSE4-NEXT: movq %r14, %xmm1 +; SSE4-NEXT: movq %rbx, %xmm6 +; SSE4-NEXT: movq %r12, %xmm2 +; SSE4-NEXT: movq %r9, %xmm7 +; SSE4-NEXT: movq %r8, %xmm3 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm5[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm6[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm7[0] +; SSE4-NEXT: addq $16, %rsp +; SSE4-NEXT: .cfi_def_cfa_offset 56 +; SSE4-NEXT: popq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: popq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: popq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: popq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: popq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: popq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 8 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v8i64: +; AVX1: # %bb.0: +; AVX1-NEXT: pushq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: pushq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: pushq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: pushq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: pushq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: pushq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 56 +; AVX1-NEXT: pushq %rax +; AVX1-NEXT: .cfi_def_cfa_offset 64 +; AVX1-NEXT: .cfi_offset %rbx, -56 +; AVX1-NEXT: .cfi_offset %r12, -48 +; AVX1-NEXT: .cfi_offset %r13, -40 +; AVX1-NEXT: .cfi_offset %r14, -32 +; AVX1-NEXT: .cfi_offset %r15, -24 +; AVX1-NEXT: .cfi_offset %rbp, -16 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm4 +; AVX1-NEXT: vpextrq $1, %xmm4, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %rax +; AVX1-NEXT: movq %rax, (%rsp) # 8-byte Spill +; AVX1-NEXT: vmovq %xmm4, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movq %rax, %rcx +; AVX1-NEXT: sarq $63, %rcx +; AVX1-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: vpextrq $1, %xmm0, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movq %rax, %rcx +; AVX1-NEXT: sarq $63, %rcx +; AVX1-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: vmovq %xmm0, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movq %rax, %rcx +; AVX1-NEXT: sarq $63, %rcx +; AVX1-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm0 +; AVX1-NEXT: vpextrq $1, %xmm0, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movq %rax, %rcx +; AVX1-NEXT: sarq $63, %rcx +; AVX1-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: vmovq %xmm0, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movq %rax, %rcx +; AVX1-NEXT: sarq $63, %rcx +; AVX1-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: vpextrq $1, %xmm1, %rbx +; AVX1-NEXT: movq %rbx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %rbx +; AVX1-NEXT: vmovq %xmm1, %r8 +; AVX1-NEXT: movq %r8, %rbp +; AVX1-NEXT: sarq $63, %rbp +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm0 +; AVX1-NEXT: vpextrq $1, %xmm0, %r9 +; AVX1-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %r9 +; AVX1-NEXT: vmovq %xmm0, %r10 +; AVX1-NEXT: movq %r10, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %r10 +; AVX1-NEXT: vpextrq $1, %xmm2, %r11 +; AVX1-NEXT: movq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %r11 +; AVX1-NEXT: vmovq %xmm2, %r15 +; AVX1-NEXT: movq %r15, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %r15 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm0 +; AVX1-NEXT: vpextrq $1, %xmm0, %rdi +; AVX1-NEXT: movq %rdi, %r14 +; AVX1-NEXT: sarq $63, %r14 +; AVX1-NEXT: vmovq %xmm0, %rsi +; AVX1-NEXT: movq %rsi, %r12 +; AVX1-NEXT: sarq $63, %r12 +; AVX1-NEXT: vpextrq $1, %xmm3, %r13 +; AVX1-NEXT: movq %r13, %rdx +; AVX1-NEXT: sarq $63, %rdx +; AVX1-NEXT: vmovq %xmm3, %rax +; AVX1-NEXT: movq %rax, %rcx +; AVX1-NEXT: sarq $63, %rcx +; AVX1-NEXT: addq %rax, %r8 +; AVX1-NEXT: adcq %rbp, %rcx +; AVX1-NEXT: addq %r13, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; AVX1-NEXT: adcq %rbx, %rdx +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbp # 8-byte Reload +; AVX1-NEXT: addq %rsi, %rbp +; AVX1-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Folded Reload +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 # 8-byte Reload +; AVX1-NEXT: addq %rdi, %r13 +; AVX1-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Folded Reload +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload +; AVX1-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Folded Reload +; AVX1-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Folded Reload +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi # 8-byte Reload +; AVX1-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rdi # 8-byte Folded Reload +; AVX1-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload +; AVX1-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Folded Reload +; AVX1-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Folded Reload +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX1-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Folded Reload +; AVX1-NEXT: adcq (%rsp), %r9 # 8-byte Folded Reload +; AVX1-NEXT: addq $1, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: adcq $0, %r9 +; AVX1-NEXT: addq $1, %rsi +; AVX1-NEXT: adcq $0, %r10 +; AVX1-NEXT: addq $1, %rdi +; AVX1-NEXT: adcq $0, %r11 +; AVX1-NEXT: addq $1, %rbx +; AVX1-NEXT: adcq $0, %r15 +; AVX1-NEXT: addq $1, %r13 +; AVX1-NEXT: adcq $0, %r14 +; AVX1-NEXT: addq $1, %rbp +; AVX1-NEXT: adcq $0, %r12 +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX1-NEXT: addq $1, %rax +; AVX1-NEXT: adcq $0, %rdx +; AVX1-NEXT: addq $1, %r8 +; AVX1-NEXT: adcq $0, %rcx +; AVX1-NEXT: shldq $63, %r8, %rcx +; AVX1-NEXT: shldq $63, %rax, %rdx +; AVX1-NEXT: shldq $63, %rbp, %r12 +; AVX1-NEXT: shldq $63, %r13, %r14 +; AVX1-NEXT: shldq $63, %rbx, %r15 +; AVX1-NEXT: shldq $63, %rdi, %r11 +; AVX1-NEXT: shldq $63, %rsi, %r10 +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX1-NEXT: shldq $63, %rax, %r9 +; AVX1-NEXT: vmovq %r9, %xmm0 +; AVX1-NEXT: vmovq %r10, %xmm1 +; AVX1-NEXT: vmovq %r11, %xmm2 +; AVX1-NEXT: vmovq %r15, %xmm3 +; AVX1-NEXT: vmovq %r14, %xmm4 +; AVX1-NEXT: vmovq %r12, %xmm5 +; AVX1-NEXT: vmovq %rdx, %xmm6 +; AVX1-NEXT: vmovq %rcx, %xmm7 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: addq $8, %rsp +; AVX1-NEXT: .cfi_def_cfa_offset 56 +; AVX1-NEXT: popq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: popq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: popq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: popq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: popq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: popq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 8 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v8i64: +; AVX2: # %bb.0: +; AVX2-NEXT: pushq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: pushq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: pushq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: pushq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: pushq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: pushq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 56 +; AVX2-NEXT: pushq %rax +; AVX2-NEXT: .cfi_def_cfa_offset 64 +; AVX2-NEXT: .cfi_offset %rbx, -56 +; AVX2-NEXT: .cfi_offset %r12, -48 +; AVX2-NEXT: .cfi_offset %r13, -40 +; AVX2-NEXT: .cfi_offset %r14, -32 +; AVX2-NEXT: .cfi_offset %r15, -24 +; AVX2-NEXT: .cfi_offset %rbp, -16 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm4 +; AVX2-NEXT: vpextrq $1, %xmm4, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %rax +; AVX2-NEXT: movq %rax, (%rsp) # 8-byte Spill +; AVX2-NEXT: vmovq %xmm4, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movq %rax, %rcx +; AVX2-NEXT: sarq $63, %rcx +; AVX2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: vpextrq $1, %xmm0, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movq %rax, %rcx +; AVX2-NEXT: sarq $63, %rcx +; AVX2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: vmovq %xmm0, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movq %rax, %rcx +; AVX2-NEXT: sarq $63, %rcx +; AVX2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm0 +; AVX2-NEXT: vpextrq $1, %xmm0, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movq %rax, %rcx +; AVX2-NEXT: sarq $63, %rcx +; AVX2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: vmovq %xmm0, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movq %rax, %rcx +; AVX2-NEXT: sarq $63, %rcx +; AVX2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: vpextrq $1, %xmm1, %rbx +; AVX2-NEXT: movq %rbx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %rbx +; AVX2-NEXT: vmovq %xmm1, %r8 +; AVX2-NEXT: movq %r8, %rbp +; AVX2-NEXT: sarq $63, %rbp +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm0 +; AVX2-NEXT: vpextrq $1, %xmm0, %r9 +; AVX2-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %r9 +; AVX2-NEXT: vmovq %xmm0, %r10 +; AVX2-NEXT: movq %r10, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %r10 +; AVX2-NEXT: vpextrq $1, %xmm2, %r11 +; AVX2-NEXT: movq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %r11 +; AVX2-NEXT: vmovq %xmm2, %r15 +; AVX2-NEXT: movq %r15, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %r15 +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm0 +; AVX2-NEXT: vpextrq $1, %xmm0, %rdi +; AVX2-NEXT: movq %rdi, %r14 +; AVX2-NEXT: sarq $63, %r14 +; AVX2-NEXT: vmovq %xmm0, %rsi +; AVX2-NEXT: movq %rsi, %r12 +; AVX2-NEXT: sarq $63, %r12 +; AVX2-NEXT: vpextrq $1, %xmm3, %r13 +; AVX2-NEXT: movq %r13, %rdx +; AVX2-NEXT: sarq $63, %rdx +; AVX2-NEXT: vmovq %xmm3, %rax +; AVX2-NEXT: movq %rax, %rcx +; AVX2-NEXT: sarq $63, %rcx +; AVX2-NEXT: addq %rax, %r8 +; AVX2-NEXT: adcq %rbp, %rcx +; AVX2-NEXT: addq %r13, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; AVX2-NEXT: adcq %rbx, %rdx +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbp # 8-byte Reload +; AVX2-NEXT: addq %rsi, %rbp +; AVX2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Folded Reload +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 # 8-byte Reload +; AVX2-NEXT: addq %rdi, %r13 +; AVX2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Folded Reload +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload +; AVX2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Folded Reload +; AVX2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Folded Reload +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi # 8-byte Reload +; AVX2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rdi # 8-byte Folded Reload +; AVX2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload +; AVX2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Folded Reload +; AVX2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Folded Reload +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Folded Reload +; AVX2-NEXT: adcq (%rsp), %r9 # 8-byte Folded Reload +; AVX2-NEXT: addq $1, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: adcq $0, %r9 +; AVX2-NEXT: addq $1, %rsi +; AVX2-NEXT: adcq $0, %r10 +; AVX2-NEXT: addq $1, %rdi +; AVX2-NEXT: adcq $0, %r11 +; AVX2-NEXT: addq $1, %rbx +; AVX2-NEXT: adcq $0, %r15 +; AVX2-NEXT: addq $1, %r13 +; AVX2-NEXT: adcq $0, %r14 +; AVX2-NEXT: addq $1, %rbp +; AVX2-NEXT: adcq $0, %r12 +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX2-NEXT: addq $1, %rax +; AVX2-NEXT: adcq $0, %rdx +; AVX2-NEXT: addq $1, %r8 +; AVX2-NEXT: adcq $0, %rcx +; AVX2-NEXT: shldq $63, %r8, %rcx +; AVX2-NEXT: shldq $63, %rax, %rdx +; AVX2-NEXT: shldq $63, %rbp, %r12 +; AVX2-NEXT: shldq $63, %r13, %r14 +; AVX2-NEXT: shldq $63, %rbx, %r15 +; AVX2-NEXT: shldq $63, %rdi, %r11 +; AVX2-NEXT: shldq $63, %rsi, %r10 +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX2-NEXT: shldq $63, %rax, %r9 +; AVX2-NEXT: vmovq %r9, %xmm0 +; AVX2-NEXT: vmovq %r10, %xmm1 +; AVX2-NEXT: vmovq %r11, %xmm2 +; AVX2-NEXT: vmovq %r15, %xmm3 +; AVX2-NEXT: vmovq %r14, %xmm4 +; AVX2-NEXT: vmovq %r12, %xmm5 +; AVX2-NEXT: vmovq %rdx, %xmm6 +; AVX2-NEXT: vmovq %rcx, %xmm7 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm2, %ymm1 +; AVX2-NEXT: addq $8, %rsp +; AVX2-NEXT: .cfi_def_cfa_offset 56 +; AVX2-NEXT: popq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: popq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: popq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: popq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: popq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: popq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 8 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v8i64: +; AVX512: # %bb.0: +; AVX512-NEXT: pushq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: pushq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: pushq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: pushq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: pushq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: pushq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 56 +; AVX512-NEXT: pushq %rax +; AVX512-NEXT: .cfi_def_cfa_offset 64 +; AVX512-NEXT: .cfi_offset %rbx, -56 +; AVX512-NEXT: .cfi_offset %r12, -48 +; AVX512-NEXT: .cfi_offset %r13, -40 +; AVX512-NEXT: .cfi_offset %r14, -32 +; AVX512-NEXT: .cfi_offset %r15, -24 +; AVX512-NEXT: .cfi_offset %rbp, -16 +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm2 +; AVX512-NEXT: vextracti128 $1, %ymm2, %xmm3 +; AVX512-NEXT: vpextrq $1, %xmm3, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %rax +; AVX512-NEXT: movq %rax, (%rsp) # 8-byte Spill +; AVX512-NEXT: vmovq %xmm3, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: movq %rax, %rcx +; AVX512-NEXT: sarq $63, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: vpextrq $1, %xmm2, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: movq %rax, %rcx +; AVX512-NEXT: sarq $63, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: vmovq %xmm2, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: movq %rax, %rcx +; AVX512-NEXT: sarq $63, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX512-NEXT: vpextrq $1, %xmm2, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: movq %rax, %rcx +; AVX512-NEXT: sarq $63, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: vmovq %xmm2, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: movq %rax, %rcx +; AVX512-NEXT: sarq $63, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: vpextrq $1, %xmm0, %rbx +; AVX512-NEXT: movq %rbx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %rbx +; AVX512-NEXT: vmovq %xmm0, %r8 +; AVX512-NEXT: movq %r8, %r13 +; AVX512-NEXT: sarq $63, %r13 +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm0 +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX512-NEXT: vpextrq $1, %xmm2, %r9 +; AVX512-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r9 +; AVX512-NEXT: vmovq %xmm2, %r10 +; AVX512-NEXT: movq %r10, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r10 +; AVX512-NEXT: vpextrq $1, %xmm0, %r11 +; AVX512-NEXT: movq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r11 +; AVX512-NEXT: vmovq %xmm0, %r14 +; AVX512-NEXT: movq %r14, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r14 +; AVX512-NEXT: vextracti128 $1, %ymm1, %xmm0 +; AVX512-NEXT: vpextrq $1, %xmm0, %rdi +; AVX512-NEXT: movq %rdi, %r15 +; AVX512-NEXT: sarq $63, %r15 +; AVX512-NEXT: vmovq %xmm0, %rsi +; AVX512-NEXT: movq %rsi, %r12 +; AVX512-NEXT: sarq $63, %r12 +; AVX512-NEXT: vpextrq $1, %xmm1, %rbp +; AVX512-NEXT: movq %rbp, %rdx +; AVX512-NEXT: sarq $63, %rdx +; AVX512-NEXT: vmovq %xmm1, %rax +; AVX512-NEXT: movq %rax, %rcx +; AVX512-NEXT: sarq $63, %rcx +; AVX512-NEXT: addq %rax, %r8 +; AVX512-NEXT: adcq %r13, %rcx +; AVX512-NEXT: addq %rbp, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; AVX512-NEXT: adcq %rbx, %rdx +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbp # 8-byte Reload +; AVX512-NEXT: addq %rsi, %rbp +; AVX512-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Folded Reload +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r13 # 8-byte Reload +; AVX512-NEXT: addq %rdi, %r13 +; AVX512-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Folded Reload +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload +; AVX512-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Folded Reload +; AVX512-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Folded Reload +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdi # 8-byte Reload +; AVX512-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rdi # 8-byte Folded Reload +; AVX512-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload +; AVX512-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Folded Reload +; AVX512-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Folded Reload +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX512-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Folded Reload +; AVX512-NEXT: adcq (%rsp), %r9 # 8-byte Folded Reload +; AVX512-NEXT: addq $1, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: adcq $0, %r9 +; AVX512-NEXT: addq $1, %rsi +; AVX512-NEXT: adcq $0, %r10 +; AVX512-NEXT: addq $1, %rdi +; AVX512-NEXT: adcq $0, %r11 +; AVX512-NEXT: addq $1, %rbx +; AVX512-NEXT: adcq $0, %r14 +; AVX512-NEXT: addq $1, %r13 +; AVX512-NEXT: adcq $0, %r15 +; AVX512-NEXT: addq $1, %rbp +; AVX512-NEXT: adcq $0, %r12 +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX512-NEXT: addq $1, %rax +; AVX512-NEXT: adcq $0, %rdx +; AVX512-NEXT: addq $1, %r8 +; AVX512-NEXT: adcq $0, %rcx +; AVX512-NEXT: shldq $63, %r8, %rcx +; AVX512-NEXT: shldq $63, %rax, %rdx +; AVX512-NEXT: shldq $63, %rbp, %r12 +; AVX512-NEXT: shldq $63, %r13, %r15 +; AVX512-NEXT: shldq $63, %rbx, %r14 +; AVX512-NEXT: shldq $63, %rdi, %r11 +; AVX512-NEXT: shldq $63, %rsi, %r10 +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX512-NEXT: shldq $63, %rax, %r9 +; AVX512-NEXT: vmovq %r9, %xmm0 +; AVX512-NEXT: vmovq %r10, %xmm1 +; AVX512-NEXT: vmovq %r11, %xmm2 +; AVX512-NEXT: vmovq %r14, %xmm3 +; AVX512-NEXT: vmovq %r15, %xmm4 +; AVX512-NEXT: vmovq %r12, %xmm5 +; AVX512-NEXT: vmovq %rdx, %xmm6 +; AVX512-NEXT: vmovq %rcx, %xmm7 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX512-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX512-NEXT: vinserti128 $1, %xmm1, %ymm2, %ymm1 +; AVX512-NEXT: vinserti64x4 $1, %ymm0, %zmm1, %zmm0 +; AVX512-NEXT: addq $8, %rsp +; AVX512-NEXT: .cfi_def_cfa_offset 56 +; AVX512-NEXT: popq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: popq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: popq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: popq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: popq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: popq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 8 +; AVX512-NEXT: retq + %x0 = sext <8 x i64> %a0 to <8 x i128> + %x1 = sext <8 x i64> %a1 to <8 x i128> + %sum = add <8 x i128> %x0, %x1 + %inc = add <8 x i128> %sum, <i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1> + %shift = ashr <8 x i128> %inc, <i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1> + %res = trunc <8 x i128> %shift to <8 x i64> + ret <8 x i64> %res +} + diff --git a/llvm/test/CodeGen/X86/avgceilu.ll b/llvm/test/CodeGen/X86/avgceilu.ll new file mode 100644 index 000000000000..3a74fca23773 --- /dev/null +++ b/llvm/test/CodeGen/X86/avgceilu.ll @@ -0,0 +1,2219 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE2 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE4 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2 +; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=AVX,AVX512 + +; +; 128-bit vectors +; + +define <16 x i8> @test_fixed_v16i8(<16 x i8> %a0, <16 x i8> %a1) { +; SSE-LABEL: test_fixed_v16i8: +; SSE: # %bb.0: +; SSE-NEXT: pavgb %xmm1, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_fixed_v16i8: +; AVX: # %bb.0: +; AVX-NEXT: vpavgb %xmm1, %xmm0, %xmm0 +; AVX-NEXT: retq + %or = or <16 x i8> %a0, %a1 + %xor = xor <16 x i8> %a0, %a1 + %shift = lshr <16 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = sub <16 x i8> %or, %shift + ret <16 x i8> %res +} + +define <16 x i8> @test_ext_v16i8(<16 x i8> %a0, <16 x i8> %a1) { +; SSE-LABEL: test_ext_v16i8: +; SSE: # %bb.0: +; SSE-NEXT: pavgb %xmm1, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_ext_v16i8: +; AVX: # %bb.0: +; AVX-NEXT: vpavgb %xmm1, %xmm0, %xmm0 +; AVX-NEXT: retq + %x0 = zext <16 x i8> %a0 to <16 x i16> + %x1 = zext <16 x i8> %a1 to <16 x i16> + %sum = add <16 x i16> %x0, %x1 + %inc = add <16 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %shift = lshr <16 x i16> %inc, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <16 x i16> %shift to <16 x i8> + ret <16 x i8> %res +} + +define <8 x i16> @test_fixed_v8i16(<8 x i16> %a0, <8 x i16> %a1) { +; SSE-LABEL: test_fixed_v8i16: +; SSE: # %bb.0: +; SSE-NEXT: pavgw %xmm1, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_fixed_v8i16: +; AVX: # %bb.0: +; AVX-NEXT: vpavgw %xmm1, %xmm0, %xmm0 +; AVX-NEXT: retq + %or = or <8 x i16> %a0, %a1 + %xor = xor <8 x i16> %a1, %a0 + %shift = lshr <8 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = sub <8 x i16> %or, %shift + ret <8 x i16> %res +} + +define <8 x i16> @test_ext_v8i16(<8 x i16> %a0, <8 x i16> %a1) { +; SSE-LABEL: test_ext_v8i16: +; SSE: # %bb.0: +; SSE-NEXT: pavgw %xmm1, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_ext_v8i16: +; AVX: # %bb.0: +; AVX-NEXT: vpavgw %xmm1, %xmm0, %xmm0 +; AVX-NEXT: retq + %x0 = zext <8 x i16> %a0 to <8 x i32> + %x1 = zext <8 x i16> %a1 to <8 x i32> + %sum = add <8 x i32> %x0, %x1 + %inc = add <8 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %shift = lshr <8 x i32> %inc, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <8 x i32> %shift to <8 x i16> + ret <8 x i16> %res +} + +define <4 x i32> @test_fixed_v4i32(<4 x i32> %a0, <4 x i32> %a1) { +; SSE-LABEL: test_fixed_v4i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: por %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm0, %xmm1 +; SSE-NEXT: psrld $1, %xmm1 +; SSE-NEXT: psubd %xmm1, %xmm2 +; SSE-NEXT: movdqa %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_fixed_v4i32: +; AVX: # %bb.0: +; AVX-NEXT: vpor %xmm1, %xmm0, %xmm2 +; AVX-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX-NEXT: vpsubd %xmm0, %xmm2, %xmm0 +; AVX-NEXT: retq + %or = or <4 x i32> %a0, %a1 + %xor = xor <4 x i32> %a1, %a0 + %shift = lshr <4 x i32> %xor, <i32 1, i32 1, i32 1, i32 1> + %res = sub <4 x i32> %or, %shift + ret <4 x i32> %res +} + +define <4 x i32> @test_ext_v4i32(<4 x i32> %a0, <4 x i32> %a1) { +; SSE2-LABEL: test_ext_v4i32: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm3, %xmm3 +; SSE2-NEXT: movdqa %xmm0, %xmm4 +; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm3[0],xmm4[1],xmm3[1] +; SSE2-NEXT: punpckhdq {{.*#+}} xmm0 = xmm0[2],xmm3[2],xmm0[3],xmm3[3] +; SSE2-NEXT: movdqa %xmm1, %xmm2 +; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1] +; SSE2-NEXT: paddq %xmm4, %xmm2 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm1 = xmm1[2],xmm3[2],xmm1[3],xmm3[3] +; SSE2-NEXT: paddq %xmm0, %xmm1 +; SSE2-NEXT: pcmpeqd %xmm0, %xmm0 +; SSE2-NEXT: psubq %xmm0, %xmm2 +; SSE2-NEXT: psubq %xmm0, %xmm1 +; SSE2-NEXT: psrlq $1, %xmm1 +; SSE2-NEXT: psrlq $1, %xmm2 +; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm1[0,2] +; SSE2-NEXT: movaps %xmm2, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v4i32: +; SSE4: # %bb.0: +; SSE4-NEXT: pxor %xmm3, %xmm3 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm4 = xmm0[0],zero,xmm0[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm0 = xmm0[2],xmm3[2],xmm0[3],xmm3[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm2 = xmm1[0],zero,xmm1[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm1 = xmm1[2],xmm3[2],xmm1[3],xmm3[3] +; SSE4-NEXT: paddq %xmm0, %xmm1 +; SSE4-NEXT: paddq %xmm4, %xmm2 +; SSE4-NEXT: pcmpeqd %xmm0, %xmm0 +; SSE4-NEXT: psubq %xmm0, %xmm1 +; SSE4-NEXT: psubq %xmm0, %xmm2 +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm1[0,2] +; SSE4-NEXT: movaps %xmm2, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v4i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm3 = xmm0[2],xmm2[2],xmm0[3],xmm2[3] +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm2 = xmm1[2],xmm2[2],xmm1[3],xmm2[3] +; AVX1-NEXT: vpaddq %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero +; AVX1-NEXT: vpaddq %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 +; AVX1-NEXT: vpsubq %xmm1, %xmm2, %xmm2 +; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm2, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v4i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 +; AVX2-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] +; AVX2-NEXT: vzeroupper +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v4i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovzxdq {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX512-NEXT: vpmovzxdq {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX512-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX512-NEXT: vpsubq %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX512-NEXT: vpmovqd %ymm0, %xmm0 +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %x0 = zext <4 x i32> %a0 to <4 x i64> + %x1 = zext <4 x i32> %a1 to <4 x i64> + %sum = add <4 x i64> %x0, %x1 + %inc = add <4 x i64> %sum, <i64 1, i64 1, i64 1, i64 1> + %shift = lshr <4 x i64> %inc, <i64 1, i64 1, i64 1, i64 1> + %res = trunc <4 x i64> %shift to <4 x i32> + ret <4 x i32> %res +} + +define <2 x i64> @test_fixed_v2i64(<2 x i64> %a0, <2 x i64> %a1) { +; SSE-LABEL: test_fixed_v2i64: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: por %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm0, %xmm1 +; SSE-NEXT: psrlq $1, %xmm1 +; SSE-NEXT: psubq %xmm1, %xmm2 +; SSE-NEXT: movdqa %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_fixed_v2i64: +; AVX: # %bb.0: +; AVX-NEXT: vpor %xmm1, %xmm0, %xmm2 +; AVX-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX-NEXT: vpsubq %xmm0, %xmm2, %xmm0 +; AVX-NEXT: retq + %or = or <2 x i64> %a0, %a1 + %xor = xor <2 x i64> %a1, %a0 + %shift = lshr <2 x i64> %xor, <i64 1, i64 1> + %res = sub <2 x i64> %or, %shift + ret <2 x i64> %res +} + +define <2 x i64> @test_ext_v2i64(<2 x i64> %a0, <2 x i64> %a1) { +; SSE2-LABEL: test_ext_v2i64: +; SSE2: # %bb.0: +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; SSE2-NEXT: movq %xmm2, %rax +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm2, %rcx +; SSE2-NEXT: movb $1, %dl +; SSE2-NEXT: movb $1, %sil +; SSE2-NEXT: addb $-1, %sil +; SSE2-NEXT: leaq 1(%rax,%rcx), %rsi +; SSE2-NEXT: adcq %rcx, %rax +; SSE2-NEXT: setb %al +; SSE2-NEXT: addb $-1, %dl +; SSE2-NEXT: movq %xmm0, %rcx +; SSE2-NEXT: movq %xmm1, %rdx +; SSE2-NEXT: leaq 1(%rcx,%rdx), %rdi +; SSE2-NEXT: adcq %rdx, %rcx +; SSE2-NEXT: setb %cl +; SSE2-NEXT: movzbl %cl, %ecx +; SSE2-NEXT: movzbl %al, %eax +; SSE2-NEXT: shrdq $1, %rcx, %rdi +; SSE2-NEXT: shrdq $1, %rax, %rsi +; SSE2-NEXT: movq %rdi, %xmm0 +; SSE2-NEXT: movq %rsi, %xmm1 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v2i64: +; SSE4: # %bb.0: +; SSE4-NEXT: movq %xmm0, %rax +; SSE4-NEXT: movq %xmm1, %rcx +; SSE4-NEXT: movb $1, %dl +; SSE4-NEXT: movb $1, %sil +; SSE4-NEXT: addb $-1, %sil +; SSE4-NEXT: leaq 1(%rax,%rcx), %rsi +; SSE4-NEXT: adcq %rcx, %rax +; SSE4-NEXT: setb %al +; SSE4-NEXT: addb $-1, %dl +; SSE4-NEXT: pextrq $1, %xmm0, %rcx +; SSE4-NEXT: pextrq $1, %xmm1, %rdx +; SSE4-NEXT: leaq 1(%rcx,%rdx), %rdi +; SSE4-NEXT: adcq %rdx, %rcx +; SSE4-NEXT: setb %cl +; SSE4-NEXT: movzbl %cl, %ecx +; SSE4-NEXT: movzbl %al, %eax +; SSE4-NEXT: shrdq $1, %rcx, %rdi +; SSE4-NEXT: shrdq $1, %rax, %rsi +; SSE4-NEXT: movq %rdi, %xmm1 +; SSE4-NEXT: movq %rsi, %xmm0 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE4-NEXT: retq +; +; AVX-LABEL: test_ext_v2i64: +; AVX: # %bb.0: +; AVX-NEXT: vmovq %xmm0, %rax +; AVX-NEXT: vmovq %xmm1, %rcx +; AVX-NEXT: movb $1, %dl +; AVX-NEXT: movb $1, %sil +; AVX-NEXT: addb $-1, %sil +; AVX-NEXT: leaq 1(%rax,%rcx), %rsi +; AVX-NEXT: adcq %rcx, %rax +; AVX-NEXT: setb %al +; AVX-NEXT: addb $-1, %dl +; AVX-NEXT: vpextrq $1, %xmm0, %rcx +; AVX-NEXT: vpextrq $1, %xmm1, %rdx +; AVX-NEXT: leaq 1(%rcx,%rdx), %rdi +; AVX-NEXT: adcq %rdx, %rcx +; AVX-NEXT: setb %cl +; AVX-NEXT: movzbl %cl, %ecx +; AVX-NEXT: movzbl %al, %eax +; AVX-NEXT: shrdq $1, %rcx, %rdi +; AVX-NEXT: shrdq $1, %rax, %rsi +; AVX-NEXT: vmovq %rdi, %xmm0 +; AVX-NEXT: vmovq %rsi, %xmm1 +; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX-NEXT: retq + %x0 = zext <2 x i64> %a0 to <2 x i128> + %x1 = zext <2 x i64> %a1 to <2 x i128> + %sum = add <2 x i128> %x0, %x1 + %inc = add <2 x i128> %sum, <i128 1, i128 1> + %shift = lshr <2 x i128> %inc, <i128 1, i128 1> + %res = trunc <2 x i128> %shift to <2 x i64> + ret <2 x i64> %res +} + +; +; 256-bit vectors +; + +define <32 x i8> @test_fixed_v32i8(<32 x i8> %a0, <32 x i8> %a1) { +; SSE-LABEL: test_fixed_v32i8: +; SSE: # %bb.0: +; SSE-NEXT: pavgb %xmm2, %xmm0 +; SSE-NEXT: pavgb %xmm3, %xmm1 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v32i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm1 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; AVX1-NEXT: vpand %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpsubb %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsubb %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v32i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpavgb %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v32i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpavgb %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: retq + %or = or <32 x i8> %a0, %a1 + %xor = xor <32 x i8> %a0, %a1 + %shift = lshr <32 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = sub <32 x i8> %or, %shift + ret <32 x i8> %res +} + +define <32 x i8> @test_ext_v32i8(<32 x i8> %a0, <32 x i8> %a1) { +; SSE-LABEL: test_ext_v32i8: +; SSE: # %bb.0: +; SSE-NEXT: pavgb %xmm2, %xmm0 +; SSE-NEXT: pavgb %xmm3, %xmm1 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_ext_v32i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 +; AVX1-NEXT: vpavgb %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vpavgb %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v32i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpavgb %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v32i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpavgb %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: retq + %x0 = zext <32 x i8> %a0 to <32 x i16> + %x1 = zext <32 x i8> %a1 to <32 x i16> + %sum = add <32 x i16> %x0, %x1 + %inc = add <32 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %shift = lshr <32 x i16> %inc, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <32 x i16> %shift to <32 x i8> + ret <32 x i8> %res +} + +define <16 x i16> @test_fixed_v16i16(<16 x i16> %a0, <16 x i16> %a1) { +; SSE-LABEL: test_fixed_v16i16: +; SSE: # %bb.0: +; SSE-NEXT: pavgw %xmm2, %xmm0 +; SSE-NEXT: pavgw %xmm3, %xmm1 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v16i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpsubw %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsubw %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v16i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpavgw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v16i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpavgw %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: retq + %or = or <16 x i16> %a0, %a1 + %xor = xor <16 x i16> %a1, %a0 + %shift = lshr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = sub <16 x i16> %or, %shift + ret <16 x i16> %res +} + +define <16 x i16> @test_ext_v16i16(<16 x i16> %a0, <16 x i16> %a1) { +; SSE-LABEL: test_ext_v16i16: +; SSE: # %bb.0: +; SSE-NEXT: pavgw %xmm2, %xmm0 +; SSE-NEXT: pavgw %xmm3, %xmm1 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_ext_v16i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 +; AVX1-NEXT: vpavgw %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vpavgw %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v16i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpavgw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v16i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpavgw %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: retq + %x0 = zext <16 x i16> %a0 to <16 x i32> + %x1 = zext <16 x i16> %a1 to <16 x i32> + %sum = add <16 x i32> %x0, %x1 + %inc = add <16 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %shift = lshr <16 x i32> %inc, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <16 x i32> %shift to <16 x i16> + ret <16 x i16> %res +} + +define <8 x i32> @test_fixed_v8i32(<8 x i32> %a0, <8 x i32> %a1) { +; SSE-LABEL: test_fixed_v8i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: por %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: por %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm0, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm3 +; SSE-NEXT: psrld $1, %xmm3 +; SSE-NEXT: psubd %xmm3, %xmm4 +; SSE-NEXT: psrld $1, %xmm2 +; SSE-NEXT: psubd %xmm2, %xmm5 +; SSE-NEXT: movdqa %xmm5, %xmm0 +; SSE-NEXT: movdqa %xmm4, %xmm1 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v8i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpsubd %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsubd %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v8i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsubd %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v8i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX512-NEXT: vpsubd %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %or = or <8 x i32> %a0, %a1 + %xor = xor <8 x i32> %a1, %a0 + %shift = lshr <8 x i32> %xor, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = sub <8 x i32> %or, %shift + ret <8 x i32> %res +} + +define <8 x i32> @test_ext_v8i32(<8 x i32> %a0, <8 x i32> %a1) { +; SSE2-LABEL: test_ext_v8i32: +; SSE2: # %bb.0: +; SSE2-NEXT: movdqa %xmm0, %xmm4 +; SSE2-NEXT: pxor %xmm5, %xmm5 +; SSE2-NEXT: movdqa %xmm0, %xmm6 +; SSE2-NEXT: punpckldq {{.*#+}} xmm6 = xmm6[0],xmm5[0],xmm6[1],xmm5[1] +; SSE2-NEXT: punpckhdq {{.*#+}} xmm4 = xmm4[2],xmm5[2],xmm4[3],xmm5[3] +; SSE2-NEXT: movdqa %xmm1, %xmm7 +; SSE2-NEXT: punpckldq {{.*#+}} xmm7 = xmm7[0],xmm5[0],xmm7[1],xmm5[1] +; SSE2-NEXT: punpckhdq {{.*#+}} xmm1 = xmm1[2],xmm5[2],xmm1[3],xmm5[3] +; SSE2-NEXT: movdqa %xmm2, %xmm0 +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm5[0],xmm0[1],xmm5[1] +; SSE2-NEXT: paddq %xmm6, %xmm0 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm5[2],xmm2[3],xmm5[3] +; SSE2-NEXT: paddq %xmm4, %xmm2 +; SSE2-NEXT: movdqa %xmm3, %xmm4 +; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm5[0],xmm4[1],xmm5[1] +; SSE2-NEXT: paddq %xmm7, %xmm4 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm3 = xmm3[2],xmm5[2],xmm3[3],xmm5[3] +; SSE2-NEXT: paddq %xmm1, %xmm3 +; SSE2-NEXT: pcmpeqd %xmm1, %xmm1 +; SSE2-NEXT: psubq %xmm1, %xmm0 +; SSE2-NEXT: psubq %xmm1, %xmm2 +; SSE2-NEXT: psubq %xmm1, %xmm4 +; SSE2-NEXT: psubq %xmm1, %xmm3 +; SSE2-NEXT: psrlq $1, %xmm3 +; SSE2-NEXT: psrlq $1, %xmm4 +; SSE2-NEXT: shufps {{.*#+}} xmm4 = xmm4[0,2],xmm3[0,2] +; SSE2-NEXT: psrlq $1, %xmm2 +; SSE2-NEXT: psrlq $1, %xmm0 +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2] +; SSE2-NEXT: movaps %xmm4, %xmm1 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v8i32: +; SSE4: # %bb.0: +; SSE4-NEXT: movdqa %xmm0, %xmm4 +; SSE4-NEXT: pxor %xmm5, %xmm5 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm6 = xmm0[0],zero,xmm0[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm4 = xmm4[2],xmm5[2],xmm4[3],xmm5[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm7 = xmm1[0],zero,xmm1[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm1 = xmm1[2],xmm5[2],xmm1[3],xmm5[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm0 = xmm2[0],zero,xmm2[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm5[2],xmm2[3],xmm5[3] +; SSE4-NEXT: paddq %xmm4, %xmm2 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm4 = xmm3[0],zero,xmm3[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm3 = xmm3[2],xmm5[2],xmm3[3],xmm5[3] +; SSE4-NEXT: paddq %xmm1, %xmm3 +; SSE4-NEXT: paddq %xmm6, %xmm0 +; SSE4-NEXT: paddq %xmm7, %xmm4 +; SSE4-NEXT: pcmpeqd %xmm1, %xmm1 +; SSE4-NEXT: psubq %xmm1, %xmm2 +; SSE4-NEXT: psubq %xmm1, %xmm3 +; SSE4-NEXT: psubq %xmm1, %xmm0 +; SSE4-NEXT: psubq %xmm1, %xmm4 +; SSE4-NEXT: psrlq $1, %xmm3 +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: psrlq $1, %xmm4 +; SSE4-NEXT: shufps {{.*#+}} xmm4 = xmm4[0,2],xmm3[0,2] +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2] +; SSE4-NEXT: movaps %xmm4, %xmm1 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v8i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm3 = xmm0[2],xmm2[2],xmm0[3],xmm2[3] +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm4 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm5 = xmm4[2],xmm2[2],xmm4[3],xmm2[3] +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm4 = xmm4[0],zero,xmm4[1],zero +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm6 = xmm1[2],xmm2[2],xmm1[3],xmm2[3] +; AVX1-NEXT: vpaddq %xmm6, %xmm3, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm6 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm2 = xmm6[2],xmm2[2],xmm6[3],xmm2[3] +; AVX1-NEXT: vpaddq %xmm2, %xmm5, %xmm2 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero +; AVX1-NEXT: vpaddq %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm1 = xmm6[0],zero,xmm6[1],zero +; AVX1-NEXT: vpaddq %xmm1, %xmm4, %xmm1 +; AVX1-NEXT: vpcmpeqd %xmm4, %xmm4, %xmm4 +; AVX1-NEXT: vpsubq %xmm4, %xmm3, %xmm3 +; AVX1-NEXT: vpsubq %xmm4, %xmm2, %xmm2 +; AVX1-NEXT: vpsubq %xmm4, %xmm0, %xmm0 +; AVX1-NEXT: vpsubq %xmm4, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm2, %xmm2 +; AVX1-NEXT: vpsrlq $1, %xmm3, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm3, %ymm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 +; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm2[0,2],ymm0[4,6],ymm2[4,6] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v8i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm2 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm3 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX2-NEXT: vpaddq %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubq %ymm1, %ymm2, %ymm2 +; AVX2-NEXT: vpsubq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm1 = ymm2[2,3],ymm0[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm2, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm1[0,2],ymm0[4,6],ymm1[4,6] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v8i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero +; AVX512-NEXT: vpaddq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpternlogd $255, %zmm1, %zmm1, %zmm1 +; AVX512-NEXT: vpsubq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovqd %zmm0, %ymm0 +; AVX512-NEXT: retq + %x0 = zext <8 x i32> %a0 to <8 x i64> + %x1 = zext <8 x i32> %a1 to <8 x i64> + %sum = add <8 x i64> %x0, %x1 + %inc = add <8 x i64> %sum, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %shift = lshr <8 x i64> %inc, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = trunc <8 x i64> %shift to <8 x i32> + ret <8 x i32> %res +} + +define <4 x i64> @test_fixed_v4i64(<4 x i64> %a0, <4 x i64> %a1) { +; SSE-LABEL: test_fixed_v4i64: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: por %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: por %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm0, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm3 +; SSE-NEXT: psrlq $1, %xmm3 +; SSE-NEXT: psubq %xmm3, %xmm4 +; SSE-NEXT: psrlq $1, %xmm2 +; SSE-NEXT: psubq %xmm2, %xmm5 +; SSE-NEXT: movdqa %xmm5, %xmm0 +; SSE-NEXT: movdqa %xmm4, %xmm1 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v4i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpsubq %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsubq %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v4i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsubq %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v4i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vpor %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX512-NEXT: vpsubq %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %or = or <4 x i64> %a0, %a1 + %xor = xor <4 x i64> %a1, %a0 + %shift = lshr <4 x i64> %xor, <i64 1, i64 1, i64 1, i64 1> + %res = sub <4 x i64> %or, %shift + ret <4 x i64> %res +} + +define <4 x i64> @test_ext_v4i64(<4 x i64> %a0, <4 x i64> %a1) { +; SSE2-LABEL: test_ext_v4i64: +; SSE2: # %bb.0: +; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm4, %rcx +; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm3[2,3,2,3] +; SSE2-NEXT: movq %xmm4, %rdx +; SSE2-NEXT: movb $1, %al +; SSE2-NEXT: movb $1, %sil +; SSE2-NEXT: addb $-1, %sil +; SSE2-NEXT: leaq 1(%rcx,%rdx), %rsi +; SSE2-NEXT: adcq %rdx, %rcx +; SSE2-NEXT: setb %dl +; SSE2-NEXT: movb $1, %cl +; SSE2-NEXT: addb $-1, %cl +; SSE2-NEXT: movq %xmm1, %rdi +; SSE2-NEXT: movq %xmm3, %r8 +; SSE2-NEXT: leaq 1(%rdi,%r8), %rcx +; SSE2-NEXT: adcq %r8, %rdi +; SSE2-NEXT: setb %dil +; SSE2-NEXT: movb $1, %r8b +; SSE2-NEXT: addb $-1, %r8b +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3] +; SSE2-NEXT: movq %xmm1, %r8 +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm2[2,3,2,3] +; SSE2-NEXT: movq %xmm1, %r9 +; SSE2-NEXT: leaq 1(%r8,%r9), %r10 +; SSE2-NEXT: adcq %r9, %r8 +; SSE2-NEXT: setb %r8b +; SSE2-NEXT: addb $-1, %al +; SSE2-NEXT: movq %xmm0, %rax +; SSE2-NEXT: movq %xmm2, %r9 +; SSE2-NEXT: leaq 1(%rax,%r9), %r11 +; SSE2-NEXT: adcq %r9, %rax +; SSE2-NEXT: setb %al +; SSE2-NEXT: movzbl %al, %eax +; SSE2-NEXT: movzbl %r8b, %r8d +; SSE2-NEXT: movzbl %dil, %edi +; SSE2-NEXT: movzbl %dl, %edx +; SSE2-NEXT: shrdq $1, %rax, %r11 +; SSE2-NEXT: shrdq $1, %r8, %r10 +; SSE2-NEXT: shrdq $1, %rdi, %rcx +; SSE2-NEXT: shrdq $1, %rdx, %rsi +; SSE2-NEXT: movq %r11, %xmm0 +; SSE2-NEXT: movq %r10, %xmm1 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE2-NEXT: movq %rcx, %xmm1 +; SSE2-NEXT: movq %rsi, %xmm2 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v4i64: +; SSE4: # %bb.0: +; SSE4-NEXT: movq %xmm1, %rcx +; SSE4-NEXT: movq %xmm3, %rdx +; SSE4-NEXT: movb $1, %al +; SSE4-NEXT: movb $1, %sil +; SSE4-NEXT: addb $-1, %sil +; SSE4-NEXT: leaq 1(%rcx,%rdx), %rsi +; SSE4-NEXT: adcq %rdx, %rcx +; SSE4-NEXT: setb %dl +; SSE4-NEXT: movb $1, %cl +; SSE4-NEXT: addb $-1, %cl +; SSE4-NEXT: pextrq $1, %xmm1, %rdi +; SSE4-NEXT: pextrq $1, %xmm3, %r8 +; SSE4-NEXT: leaq 1(%rdi,%r8), %rcx +; SSE4-NEXT: adcq %r8, %rdi +; SSE4-NEXT: setb %dil +; SSE4-NEXT: movb $1, %r8b +; SSE4-NEXT: addb $-1, %r8b +; SSE4-NEXT: movq %xmm0, %r8 +; SSE4-NEXT: movq %xmm2, %r9 +; SSE4-NEXT: leaq 1(%r8,%r9), %r10 +; SSE4-NEXT: adcq %r9, %r8 +; SSE4-NEXT: setb %r8b +; SSE4-NEXT: addb $-1, %al +; SSE4-NEXT: pextrq $1, %xmm0, %rax +; SSE4-NEXT: pextrq $1, %xmm2, %r9 +; SSE4-NEXT: leaq 1(%rax,%r9), %r11 +; SSE4-NEXT: adcq %r9, %rax +; SSE4-NEXT: setb %al +; SSE4-NEXT: movzbl %al, %eax +; SSE4-NEXT: movzbl %r8b, %r8d +; SSE4-NEXT: movzbl %dil, %edi +; SSE4-NEXT: movzbl %dl, %edx +; SSE4-NEXT: shrdq $1, %rax, %r11 +; SSE4-NEXT: shrdq $1, %r8, %r10 +; SSE4-NEXT: shrdq $1, %rdi, %rcx +; SSE4-NEXT: shrdq $1, %rdx, %rsi +; SSE4-NEXT: movq %r11, %xmm1 +; SSE4-NEXT: movq %r10, %xmm0 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE4-NEXT: movq %rcx, %xmm2 +; SSE4-NEXT: movq %rsi, %xmm1 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0] +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v4i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vmovq %xmm0, %rcx +; AVX1-NEXT: vmovq %xmm1, %rdx +; AVX1-NEXT: movb $1, %al +; AVX1-NEXT: movb $1, %sil +; AVX1-NEXT: addb $-1, %sil +; AVX1-NEXT: leaq 1(%rcx,%rdx), %rsi +; AVX1-NEXT: adcq %rdx, %rcx +; AVX1-NEXT: setb %dl +; AVX1-NEXT: movb $1, %cl +; AVX1-NEXT: addb $-1, %cl +; AVX1-NEXT: vpextrq $1, %xmm0, %rdi +; AVX1-NEXT: vpextrq $1, %xmm1, %r8 +; AVX1-NEXT: leaq 1(%rdi,%r8), %rcx +; AVX1-NEXT: adcq %r8, %rdi +; AVX1-NEXT: setb %dil +; AVX1-NEXT: movb $1, %r8b +; AVX1-NEXT: addb $-1, %r8b +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vmovq %xmm0, %r8 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vmovq %xmm1, %r9 +; AVX1-NEXT: leaq 1(%r8,%r9), %r10 +; AVX1-NEXT: adcq %r9, %r8 +; AVX1-NEXT: setb %r8b +; AVX1-NEXT: addb $-1, %al +; AVX1-NEXT: vpextrq $1, %xmm0, %rax +; AVX1-NEXT: vpextrq $1, %xmm1, %r9 +; AVX1-NEXT: leaq 1(%rax,%r9), %r11 +; AVX1-NEXT: adcq %r9, %rax +; AVX1-NEXT: setb %al +; AVX1-NEXT: movzbl %al, %eax +; AVX1-NEXT: movzbl %r8b, %r8d +; AVX1-NEXT: movzbl %dil, %edi +; AVX1-NEXT: movzbl %dl, %edx +; AVX1-NEXT: shrdq $1, %rax, %r11 +; AVX1-NEXT: shrdq $1, %r8, %r10 +; AVX1-NEXT: shrdq $1, %rdi, %rcx +; AVX1-NEXT: shrdq $1, %rdx, %rsi +; AVX1-NEXT: vmovq %r11, %xmm0 +; AVX1-NEXT: vmovq %r10, %xmm1 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX1-NEXT: vmovq %rcx, %xmm1 +; AVX1-NEXT: vmovq %rsi, %xmm2 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0] +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v4i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vmovq %xmm0, %rcx +; AVX2-NEXT: vmovq %xmm1, %rdx +; AVX2-NEXT: movb $1, %al +; AVX2-NEXT: movb $1, %sil +; AVX2-NEXT: addb $-1, %sil +; AVX2-NEXT: leaq 1(%rcx,%rdx), %rsi +; AVX2-NEXT: adcq %rdx, %rcx +; AVX2-NEXT: setb %dl +; AVX2-NEXT: movb $1, %cl +; AVX2-NEXT: addb $-1, %cl +; AVX2-NEXT: vpextrq $1, %xmm0, %rdi +; AVX2-NEXT: vpextrq $1, %xmm1, %r8 +; AVX2-NEXT: leaq 1(%rdi,%r8), %rcx +; AVX2-NEXT: adcq %r8, %rdi +; AVX2-NEXT: setb %dil +; AVX2-NEXT: movb $1, %r8b +; AVX2-NEXT: addb $-1, %r8b +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vmovq %xmm0, %r8 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX2-NEXT: vmovq %xmm1, %r9 +; AVX2-NEXT: leaq 1(%r8,%r9), %r10 +; AVX2-NEXT: adcq %r9, %r8 +; AVX2-NEXT: setb %r8b +; AVX2-NEXT: addb $-1, %al +; AVX2-NEXT: vpextrq $1, %xmm0, %rax +; AVX2-NEXT: vpextrq $1, %xmm1, %r9 +; AVX2-NEXT: leaq 1(%rax,%r9), %r11 +; AVX2-NEXT: adcq %r9, %rax +; AVX2-NEXT: setb %al +; AVX2-NEXT: movzbl %al, %eax +; AVX2-NEXT: movzbl %r8b, %r8d +; AVX2-NEXT: movzbl %dil, %edi +; AVX2-NEXT: movzbl %dl, %edx +; AVX2-NEXT: shrdq $1, %rax, %r11 +; AVX2-NEXT: shrdq $1, %r8, %r10 +; AVX2-NEXT: shrdq $1, %rdi, %rcx +; AVX2-NEXT: shrdq $1, %rdx, %rsi +; AVX2-NEXT: vmovq %r11, %xmm0 +; AVX2-NEXT: vmovq %r10, %xmm1 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX2-NEXT: vmovq %rcx, %xmm1 +; AVX2-NEXT: vmovq %rsi, %xmm2 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0] +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v4i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vmovq %xmm0, %rcx +; AVX512-NEXT: vmovq %xmm1, %rdx +; AVX512-NEXT: movb $1, %al +; AVX512-NEXT: movb $1, %sil +; AVX512-NEXT: addb $-1, %sil +; AVX512-NEXT: leaq 1(%rcx,%rdx), %rsi +; AVX512-NEXT: adcq %rdx, %rcx +; AVX512-NEXT: setb %dl +; AVX512-NEXT: movb $1, %cl +; AVX512-NEXT: vpextrq $1, %xmm0, %rdi +; AVX512-NEXT: vpextrq $1, %xmm1, %r8 +; AVX512-NEXT: addb $-1, %cl +; AVX512-NEXT: leaq 1(%rdi,%r8), %rcx +; AVX512-NEXT: adcq %r8, %rdi +; AVX512-NEXT: setb %dil +; AVX512-NEXT: movb $1, %r8b +; AVX512-NEXT: addb $-1, %r8b +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX512-NEXT: vmovq %xmm0, %r8 +; AVX512-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX512-NEXT: vmovq %xmm1, %r9 +; AVX512-NEXT: leaq 1(%r8,%r9), %r10 +; AVX512-NEXT: adcq %r9, %r8 +; AVX512-NEXT: setb %r8b +; AVX512-NEXT: addb $-1, %al +; AVX512-NEXT: vpextrq $1, %xmm0, %rax +; AVX512-NEXT: vpextrq $1, %xmm1, %r9 +; AVX512-NEXT: leaq 1(%rax,%r9), %r11 +; AVX512-NEXT: adcq %r9, %rax +; AVX512-NEXT: setb %al +; AVX512-NEXT: movzbl %al, %eax +; AVX512-NEXT: movzbl %r8b, %r8d +; AVX512-NEXT: movzbl %dil, %edi +; AVX512-NEXT: movzbl %dl, %edx +; AVX512-NEXT: shrdq $1, %rax, %r11 +; AVX512-NEXT: shrdq $1, %r8, %r10 +; AVX512-NEXT: shrdq $1, %rdi, %rcx +; AVX512-NEXT: shrdq $1, %rdx, %rsi +; AVX512-NEXT: vmovq %r11, %xmm0 +; AVX512-NEXT: vmovq %r10, %xmm1 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX512-NEXT: vmovq %rcx, %xmm1 +; AVX512-NEXT: vmovq %rsi, %xmm2 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0] +; AVX512-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX512-NEXT: retq + %x0 = zext <4 x i64> %a0 to <4 x i128> + %x1 = zext <4 x i64> %a1 to <4 x i128> + %sum = add <4 x i128> %x0, %x1 + %inc = add <4 x i128> %sum, <i128 1, i128 1, i128 1, i128 1> + %shift = lshr <4 x i128> %inc, <i128 1, i128 1, i128 1, i128 1> + %res = trunc <4 x i128> %shift to <4 x i64> + ret <4 x i64> %res +} + +; +; 512-bit vectors +; + +define <64 x i8> @test_fixed_v64i8(<64 x i8> %a0, <64 x i8> %a1) { +; SSE-LABEL: test_fixed_v64i8: +; SSE: # %bb.0: +; SSE-NEXT: pavgb %xmm4, %xmm0 +; SSE-NEXT: pavgb %xmm5, %xmm1 +; SSE-NEXT: pavgb %xmm6, %xmm2 +; SSE-NEXT: pavgb %xmm7, %xmm3 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v64i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vorps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm2, %ymm0, %ymm0 +; AVX1-NEXT: vxorps %ymm3, %ymm1, %ymm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm2 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; AVX1-NEXT: vpand %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpand %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm6 +; AVX1-NEXT: vpand %xmm3, %xmm6, %xmm6 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm3 +; AVX1-NEXT: vpsubb %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpsubb %xmm6, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpsubb %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpsubb %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v64i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpavgb %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpavgb %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v64i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpavgb %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %or = or <64 x i8> %a0, %a1 + %xor = xor <64 x i8> %a0, %a1 + %shift = lshr <64 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = sub <64 x i8> %or, %shift + ret <64 x i8> %res +} + +define <64 x i8> @test_ext_v64i8(<64 x i8> %a0, <64 x i8> %a1) { +; SSE-LABEL: test_ext_v64i8: +; SSE: # %bb.0: +; SSE-NEXT: pavgb %xmm4, %xmm0 +; SSE-NEXT: pavgb %xmm5, %xmm1 +; SSE-NEXT: pavgb %xmm6, %xmm2 +; SSE-NEXT: pavgb %xmm7, %xmm3 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_ext_v64i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm4 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm5 +; AVX1-NEXT: vpavgb %xmm4, %xmm5, %xmm4 +; AVX1-NEXT: vpavgb %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm4, %ymm0, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm4 +; AVX1-NEXT: vpavgb %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vpavgb %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v64i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpavgb %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpavgb %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v64i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpavgb %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %x0 = zext <64 x i8> %a0 to <64 x i16> + %x1 = zext <64 x i8> %a1 to <64 x i16> + %sum = add <64 x i16> %x0, %x1 + %inc = add <64 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %shift = lshr <64 x i16> %inc, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <64 x i16> %shift to <64 x i8> + ret <64 x i8> %res +} + +define <32 x i16> @test_fixed_v32i16(<32 x i16> %a0, <32 x i16> %a1) { +; SSE-LABEL: test_fixed_v32i16: +; SSE: # %bb.0: +; SSE-NEXT: pavgw %xmm4, %xmm0 +; SSE-NEXT: pavgw %xmm5, %xmm1 +; SSE-NEXT: pavgw %xmm6, %xmm2 +; SSE-NEXT: pavgw %xmm7, %xmm3 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v32i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vorps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpsubw %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpsubw %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpsubw %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpsubw %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v32i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpavgw %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpavgw %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v32i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpavgw %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %or = or <32 x i16> %a0, %a1 + %xor = xor <32 x i16> %a1, %a0 + %shift = lshr <32 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = sub <32 x i16> %or, %shift + ret <32 x i16> %res +} + +define <32 x i16> @test_ext_v32i16(<32 x i16> %a0, <32 x i16> %a1) { +; SSE-LABEL: test_ext_v32i16: +; SSE: # %bb.0: +; SSE-NEXT: pavgw %xmm4, %xmm0 +; SSE-NEXT: pavgw %xmm5, %xmm1 +; SSE-NEXT: pavgw %xmm6, %xmm2 +; SSE-NEXT: pavgw %xmm7, %xmm3 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_ext_v32i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm4 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm5 +; AVX1-NEXT: vpavgw %xmm4, %xmm5, %xmm4 +; AVX1-NEXT: vpavgw %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm4, %ymm0, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm4 +; AVX1-NEXT: vpavgw %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vpavgw %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v32i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpavgw %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpavgw %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v32i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpavgw %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %x0 = zext <32 x i16> %a0 to <32 x i32> + %x1 = zext <32 x i16> %a1 to <32 x i32> + %sum = add <32 x i32> %x0, %x1 + %inc = add <32 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %shift = lshr <32 x i32> %inc, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <32 x i32> %shift to <32 x i16> + ret <32 x i16> %res +} + +define <16 x i32> @test_fixed_v16i32(<16 x i32> %a0, <16 x i32> %a1) { +; SSE-LABEL: test_fixed_v16i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm8 +; SSE-NEXT: por %xmm7, %xmm3 +; SSE-NEXT: movdqa %xmm2, %xmm9 +; SSE-NEXT: por %xmm6, %xmm9 +; SSE-NEXT: movdqa %xmm1, %xmm10 +; SSE-NEXT: por %xmm5, %xmm10 +; SSE-NEXT: movdqa %xmm0, %xmm11 +; SSE-NEXT: por %xmm4, %xmm11 +; SSE-NEXT: pxor %xmm0, %xmm4 +; SSE-NEXT: pxor %xmm1, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm6 +; SSE-NEXT: pxor %xmm8, %xmm7 +; SSE-NEXT: psrld $1, %xmm7 +; SSE-NEXT: psubd %xmm7, %xmm3 +; SSE-NEXT: psrld $1, %xmm6 +; SSE-NEXT: psubd %xmm6, %xmm9 +; SSE-NEXT: psrld $1, %xmm5 +; SSE-NEXT: psubd %xmm5, %xmm10 +; SSE-NEXT: psrld $1, %xmm4 +; SSE-NEXT: psubd %xmm4, %xmm11 +; SSE-NEXT: movdqa %xmm11, %xmm0 +; SSE-NEXT: movdqa %xmm10, %xmm1 +; SSE-NEXT: movdqa %xmm9, %xmm2 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v16i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vorps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsrld $1, %xmm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpsubd %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpsubd %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpsubd %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpsubd %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v16i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpor %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsrld $1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubd %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsubd %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v16i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpord %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxord %zmm0, %zmm1, %zmm0 +; AVX512-NEXT: vpsrld $1, %zmm0, %zmm0 +; AVX512-NEXT: vpsubd %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %or = or <16 x i32> %a0, %a1 + %xor = xor <16 x i32> %a1, %a0 + %shift = lshr <16 x i32> %xor, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = sub <16 x i32> %or, %shift + ret <16 x i32> %res +} + +define <16 x i32> @test_ext_v16i32(<16 x i32> %a0, <16 x i32> %a1) { +; SSE2-LABEL: test_ext_v16i32: +; SSE2: # %bb.0: +; SSE2-NEXT: movdqa %xmm2, %xmm8 +; SSE2-NEXT: movdqa %xmm1, %xmm2 +; SSE2-NEXT: movdqa %xmm0, %xmm1 +; SSE2-NEXT: pxor %xmm9, %xmm9 +; SSE2-NEXT: movdqa %xmm0, %xmm10 +; SSE2-NEXT: punpckldq {{.*#+}} xmm10 = xmm10[0],xmm9[0],xmm10[1],xmm9[1] +; SSE2-NEXT: punpckhdq {{.*#+}} xmm1 = xmm1[2],xmm9[2],xmm1[3],xmm9[3] +; SSE2-NEXT: movdqa %xmm2, %xmm11 +; SSE2-NEXT: punpckldq {{.*#+}} xmm11 = xmm11[0],xmm9[0],xmm11[1],xmm9[1] +; SSE2-NEXT: punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm9[2],xmm2[3],xmm9[3] +; SSE2-NEXT: movdqa %xmm8, %xmm12 +; SSE2-NEXT: punpckldq {{.*#+}} xmm12 = xmm12[0],xmm9[0],xmm12[1],xmm9[1] +; SSE2-NEXT: punpckhdq {{.*#+}} xmm8 = xmm8[2],xmm9[2],xmm8[3],xmm9[3] +; SSE2-NEXT: movdqa %xmm3, %xmm13 +; SSE2-NEXT: punpckldq {{.*#+}} xmm13 = xmm13[0],xmm9[0],xmm13[1],xmm9[1] +; SSE2-NEXT: punpckhdq {{.*#+}} xmm3 = xmm3[2],xmm9[2],xmm3[3],xmm9[3] +; SSE2-NEXT: movdqa %xmm4, %xmm0 +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm9[0],xmm0[1],xmm9[1] +; SSE2-NEXT: paddq %xmm10, %xmm0 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm4 = xmm4[2],xmm9[2],xmm4[3],xmm9[3] +; SSE2-NEXT: paddq %xmm1, %xmm4 +; SSE2-NEXT: movdqa %xmm5, %xmm1 +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm9[0],xmm1[1],xmm9[1] +; SSE2-NEXT: paddq %xmm11, %xmm1 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm5 = xmm5[2],xmm9[2],xmm5[3],xmm9[3] +; SSE2-NEXT: paddq %xmm2, %xmm5 +; SSE2-NEXT: movdqa %xmm6, %xmm2 +; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm9[0],xmm2[1],xmm9[1] +; SSE2-NEXT: paddq %xmm12, %xmm2 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm6 = xmm6[2],xmm9[2],xmm6[3],xmm9[3] +; SSE2-NEXT: paddq %xmm8, %xmm6 +; SSE2-NEXT: movdqa %xmm7, %xmm8 +; SSE2-NEXT: punpckldq {{.*#+}} xmm8 = xmm8[0],xmm9[0],xmm8[1],xmm9[1] +; SSE2-NEXT: paddq %xmm13, %xmm8 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm7 = xmm7[2],xmm9[2],xmm7[3],xmm9[3] +; SSE2-NEXT: paddq %xmm3, %xmm7 +; SSE2-NEXT: pcmpeqd %xmm3, %xmm3 +; SSE2-NEXT: psubq %xmm3, %xmm0 +; SSE2-NEXT: psubq %xmm3, %xmm4 +; SSE2-NEXT: psubq %xmm3, %xmm1 +; SSE2-NEXT: psubq %xmm3, %xmm5 +; SSE2-NEXT: psubq %xmm3, %xmm2 +; SSE2-NEXT: psubq %xmm3, %xmm6 +; SSE2-NEXT: psubq %xmm3, %xmm8 +; SSE2-NEXT: psubq %xmm3, %xmm7 +; SSE2-NEXT: psrlq $1, %xmm7 +; SSE2-NEXT: psrlq $1, %xmm8 +; SSE2-NEXT: shufps {{.*#+}} xmm8 = xmm8[0,2],xmm7[0,2] +; SSE2-NEXT: psrlq $1, %xmm6 +; SSE2-NEXT: psrlq $1, %xmm2 +; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm6[0,2] +; SSE2-NEXT: psrlq $1, %xmm5 +; SSE2-NEXT: psrlq $1, %xmm1 +; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm5[0,2] +; SSE2-NEXT: psrlq $1, %xmm4 +; SSE2-NEXT: psrlq $1, %xmm0 +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm4[0,2] +; SSE2-NEXT: movaps %xmm8, %xmm3 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v16i32: +; SSE4: # %bb.0: +; SSE4-NEXT: movdqa %xmm3, %xmm8 +; SSE4-NEXT: movdqa %xmm2, %xmm3 +; SSE4-NEXT: movdqa %xmm1, %xmm2 +; SSE4-NEXT: movdqa %xmm0, %xmm1 +; SSE4-NEXT: pxor %xmm10, %xmm10 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm9 = xmm0[0],zero,xmm0[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm1 = xmm1[2],xmm10[2],xmm1[3],xmm10[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm11 = xmm2[0],zero,xmm2[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm10[2],xmm2[3],xmm10[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm12 = xmm3[0],zero,xmm3[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm3 = xmm3[2],xmm10[2],xmm3[3],xmm10[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm13 = xmm8[0],zero,xmm8[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm8 = xmm8[2],xmm10[2],xmm8[3],xmm10[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm0 = xmm4[0],zero,xmm4[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm4 = xmm4[2],xmm10[2],xmm4[3],xmm10[3] +; SSE4-NEXT: paddq %xmm1, %xmm4 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm1 = xmm5[0],zero,xmm5[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm5 = xmm5[2],xmm10[2],xmm5[3],xmm10[3] +; SSE4-NEXT: paddq %xmm2, %xmm5 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm2 = xmm6[0],zero,xmm6[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm6 = xmm6[2],xmm10[2],xmm6[3],xmm10[3] +; SSE4-NEXT: paddq %xmm3, %xmm6 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm3 = xmm7[0],zero,xmm7[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm7 = xmm7[2],xmm10[2],xmm7[3],xmm10[3] +; SSE4-NEXT: paddq %xmm8, %xmm7 +; SSE4-NEXT: paddq %xmm9, %xmm0 +; SSE4-NEXT: paddq %xmm11, %xmm1 +; SSE4-NEXT: paddq %xmm12, %xmm2 +; SSE4-NEXT: paddq %xmm13, %xmm3 +; SSE4-NEXT: pcmpeqd %xmm8, %xmm8 +; SSE4-NEXT: psubq %xmm8, %xmm4 +; SSE4-NEXT: psubq %xmm8, %xmm5 +; SSE4-NEXT: psubq %xmm8, %xmm6 +; SSE4-NEXT: psubq %xmm8, %xmm7 +; SSE4-NEXT: psubq %xmm8, %xmm0 +; SSE4-NEXT: psubq %xmm8, %xmm1 +; SSE4-NEXT: psubq %xmm8, %xmm2 +; SSE4-NEXT: psubq %xmm8, %xmm3 +; SSE4-NEXT: psrlq $1, %xmm7 +; SSE4-NEXT: psrlq $1, %xmm6 +; SSE4-NEXT: psrlq $1, %xmm5 +; SSE4-NEXT: psrlq $1, %xmm4 +; SSE4-NEXT: psrlq $1, %xmm3 +; SSE4-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,2],xmm7[0,2] +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm6[0,2] +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm5[0,2] +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm4[0,2] +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v16i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vpxor %xmm4, %xmm4, %xmm4 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm5 = xmm0[2],xmm4[2],xmm0[3],xmm4[3] +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm6 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm7 = xmm6[2],xmm4[2],xmm6[3],xmm4[3] +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm8 = xmm1[2],xmm4[2],xmm1[3],xmm4[3] +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm9 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm10 = xmm9[2],xmm4[2],xmm9[3],xmm4[3] +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm6 = xmm6[0],zero,xmm6[1],zero +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm9 = xmm9[0],zero,xmm9[1],zero +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm11 = xmm2[2],xmm4[2],xmm2[3],xmm4[3] +; AVX1-NEXT: vpaddq %xmm5, %xmm11, %xmm5 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm11 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm12 = xmm11[2],xmm4[2],xmm11[3],xmm4[3] +; AVX1-NEXT: vpaddq %xmm7, %xmm12, %xmm7 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm12 = xmm3[2],xmm4[2],xmm3[3],xmm4[3] +; AVX1-NEXT: vpaddq %xmm12, %xmm8, %xmm8 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm12 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm4 = xmm12[2],xmm4[2],xmm12[3],xmm4[3] +; AVX1-NEXT: vpaddq %xmm4, %xmm10, %xmm4 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm2 = xmm2[0],zero,xmm2[1],zero +; AVX1-NEXT: vpaddq %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm2 = xmm11[0],zero,xmm11[1],zero +; AVX1-NEXT: vpaddq %xmm2, %xmm6, %xmm2 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm3 = xmm3[0],zero,xmm3[1],zero +; AVX1-NEXT: vpaddq %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm3 = xmm12[0],zero,xmm12[1],zero +; AVX1-NEXT: vpaddq %xmm3, %xmm9, %xmm3 +; AVX1-NEXT: vpcmpeqd %xmm6, %xmm6, %xmm6 +; AVX1-NEXT: vpsubq %xmm6, %xmm5, %xmm5 +; AVX1-NEXT: vpsubq %xmm6, %xmm7, %xmm7 +; AVX1-NEXT: vpsubq %xmm6, %xmm8, %xmm8 +; AVX1-NEXT: vpsubq %xmm6, %xmm4, %xmm4 +; AVX1-NEXT: vpsubq %xmm6, %xmm0, %xmm0 +; AVX1-NEXT: vpsubq %xmm6, %xmm2, %xmm2 +; AVX1-NEXT: vpsubq %xmm6, %xmm1, %xmm1 +; AVX1-NEXT: vpsubq %xmm6, %xmm3, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm4, %xmm4 +; AVX1-NEXT: vpsrlq $1, %xmm8, %xmm6 +; AVX1-NEXT: vpsrlq $1, %xmm7, %xmm7 +; AVX1-NEXT: vpsrlq $1, %xmm5, %xmm5 +; AVX1-NEXT: vpsrlq $1, %xmm3, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm2, %xmm2 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm7, %ymm5, %ymm5 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 +; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm5[0,2],ymm0[4,6],ymm5[4,6] +; AVX1-NEXT: vinsertf128 $1, %xmm4, %ymm6, %ymm2 +; AVX1-NEXT: vinsertf128 $1, %xmm3, %ymm1, %ymm1 +; AVX1-NEXT: vshufps {{.*#+}} ymm1 = ymm1[0,2],ymm2[0,2],ymm1[4,6],ymm2[4,6] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v16i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm4 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm5 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm6 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero +; AVX2-NEXT: vpaddq %ymm6, %ymm4, %ymm4 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm6 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero +; AVX2-NEXT: vpaddq %ymm6, %ymm5, %ymm5 +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm2 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero +; AVX2-NEXT: vpaddq %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm2 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero +; AVX2-NEXT: vpaddq %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vpcmpeqd %ymm2, %ymm2, %ymm2 +; AVX2-NEXT: vpsubq %ymm2, %ymm4, %ymm3 +; AVX2-NEXT: vpsubq %ymm2, %ymm5, %ymm4 +; AVX2-NEXT: vpsubq %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpsubq %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm2 = ymm4[2,3],ymm0[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm2, %ymm2 +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm4, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm2[0,2],ymm0[4,6],ymm2[4,6] +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm2 = ymm3[2,3],ymm1[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm2, %ymm2 +; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vshufps {{.*#+}} ymm1 = ymm1[0,2],ymm2[0,2],ymm1[4,6],ymm2[4,6] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v16i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm2 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm0 +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm3 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero +; AVX512-NEXT: vpaddq %zmm3, %zmm2, %zmm2 +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm1 +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero +; AVX512-NEXT: vpaddq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpternlogd $255, %zmm1, %zmm1, %zmm1 +; AVX512-NEXT: vpsubq %zmm1, %zmm2, %zmm2 +; AVX512-NEXT: vpsubq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm2, %zmm1 +; AVX512-NEXT: vpmovqd %zmm1, %ymm1 +; AVX512-NEXT: vpmovqd %zmm0, %ymm0 +; AVX512-NEXT: vinserti64x4 $1, %ymm0, %zmm1, %zmm0 +; AVX512-NEXT: retq + %x0 = zext <16 x i32> %a0 to <16 x i64> + %x1 = zext <16 x i32> %a1 to <16 x i64> + %sum = add <16 x i64> %x0, %x1 + %inc = add <16 x i64> %sum, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %shift = lshr <16 x i64> %inc, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = trunc <16 x i64> %shift to <16 x i32> + ret <16 x i32> %res +} + +define <8 x i64> @test_fixed_v8i64(<8 x i64> %a0, <8 x i64> %a1) { +; SSE-LABEL: test_fixed_v8i64: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm8 +; SSE-NEXT: por %xmm7, %xmm3 +; SSE-NEXT: movdqa %xmm2, %xmm9 +; SSE-NEXT: por %xmm6, %xmm9 +; SSE-NEXT: movdqa %xmm1, %xmm10 +; SSE-NEXT: por %xmm5, %xmm10 +; SSE-NEXT: movdqa %xmm0, %xmm11 +; SSE-NEXT: por %xmm4, %xmm11 +; SSE-NEXT: pxor %xmm0, %xmm4 +; SSE-NEXT: pxor %xmm1, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm6 +; SSE-NEXT: pxor %xmm8, %xmm7 +; SSE-NEXT: psrlq $1, %xmm7 +; SSE-NEXT: psubq %xmm7, %xmm3 +; SSE-NEXT: psrlq $1, %xmm6 +; SSE-NEXT: psubq %xmm6, %xmm9 +; SSE-NEXT: psrlq $1, %xmm5 +; SSE-NEXT: psubq %xmm5, %xmm10 +; SSE-NEXT: psrlq $1, %xmm4 +; SSE-NEXT: psubq %xmm4, %xmm11 +; SSE-NEXT: movdqa %xmm11, %xmm0 +; SSE-NEXT: movdqa %xmm10, %xmm1 +; SSE-NEXT: movdqa %xmm9, %xmm2 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v8i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vorps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vorps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpsubq %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpsubq %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpsubq %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpsubq %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v8i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vpor %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpor %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vpsubq %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vpsubq %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v8i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vporq %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxorq %zmm0, %zmm1, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpsubq %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %or = or <8 x i64> %a0, %a1 + %xor = xor <8 x i64> %a1, %a0 + %shift = lshr <8 x i64> %xor, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = sub <8 x i64> %or, %shift + ret <8 x i64> %res +} + +define <8 x i64> @test_ext_v8i64(<8 x i64> %a0, <8 x i64> %a1) { +; SSE2-LABEL: test_ext_v8i64: +; SSE2: # %bb.0: +; SSE2-NEXT: pushq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: pushq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: pushq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: pushq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: pushq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: pushq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 56 +; SSE2-NEXT: .cfi_offset %rbx, -56 +; SSE2-NEXT: .cfi_offset %r12, -48 +; SSE2-NEXT: .cfi_offset %r13, -40 +; SSE2-NEXT: .cfi_offset %r14, -32 +; SSE2-NEXT: .cfi_offset %r15, -24 +; SSE2-NEXT: .cfi_offset %rbp, -16 +; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm3[2,3,2,3] +; SSE2-NEXT: movq %xmm8, %rcx +; SSE2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm7[2,3,2,3] +; SSE2-NEXT: movq %xmm8, %rdx +; SSE2-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movb $1, %al +; SSE2-NEXT: addb $-1, %al +; SSE2-NEXT: movq %rcx, %rax +; SSE2-NEXT: adcq %rdx, %rax +; SSE2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE2-NEXT: movb $1, %al +; SSE2-NEXT: addb $-1, %al +; SSE2-NEXT: movq %xmm3, %r12 +; SSE2-NEXT: movq %xmm7, %rcx +; SSE2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %r12, %rax +; SSE2-NEXT: adcq %rcx, %rax +; SSE2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE2-NEXT: movb $1, %al +; SSE2-NEXT: addb $-1, %al +; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm2[2,3,2,3] +; SSE2-NEXT: movq %xmm3, %r11 +; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm6[2,3,2,3] +; SSE2-NEXT: movq %xmm3, %rbx +; SSE2-NEXT: movq %r11, %rax +; SSE2-NEXT: adcq %rbx, %rax +; SSE2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE2-NEXT: movb $1, %al +; SSE2-NEXT: addb $-1, %al +; SSE2-NEXT: movq %xmm2, %r14 +; SSE2-NEXT: movq %xmm6, %r15 +; SSE2-NEXT: movq %r14, %rax +; SSE2-NEXT: adcq %r15, %rax +; SSE2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE2-NEXT: movb $1, %al +; SSE2-NEXT: addb $-1, %al +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm2, %r13 +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm5[2,3,2,3] +; SSE2-NEXT: movq %xmm2, %r10 +; SSE2-NEXT: movq %r13, %rax +; SSE2-NEXT: adcq %r10, %rax +; SSE2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE2-NEXT: movb $1, %al +; SSE2-NEXT: addb $-1, %al +; SSE2-NEXT: movq %xmm1, %r9 +; SSE2-NEXT: movq %xmm5, %r8 +; SSE2-NEXT: movq %r9, %rax +; SSE2-NEXT: adcq %r8, %rax +; SSE2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE2-NEXT: movb $1, %al +; SSE2-NEXT: addb $-1, %al +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3] +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm4[2,3,2,3] +; SSE2-NEXT: movq %xmm1, %rdi +; SSE2-NEXT: movq %xmm2, %rsi +; SSE2-NEXT: movq %rdi, %rdx +; SSE2-NEXT: adcq %rsi, %rdx +; SSE2-NEXT: movb $1, %dl +; SSE2-NEXT: setb %bpl +; SSE2-NEXT: addb $-1, %dl +; SSE2-NEXT: movq %xmm0, %rcx +; SSE2-NEXT: movq %xmm4, %rax +; SSE2-NEXT: movq %rcx, %rdx +; SSE2-NEXT: adcq %rax, %rdx +; SSE2-NEXT: leaq 1(%rcx,%rax), %rdx +; SSE2-NEXT: leaq 1(%rdi,%rsi), %rax +; SSE2-NEXT: leaq 1(%r9,%r8), %rcx +; SSE2-NEXT: leaq 1(%r13,%r10), %rdi +; SSE2-NEXT: leaq 1(%r14,%r15), %rsi +; SSE2-NEXT: leaq 1(%r11,%rbx), %r11 +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; SSE2-NEXT: leaq 1(%r12,%r8), %r9 +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload +; SSE2-NEXT: leaq 1(%r8,%r10), %r10 +; SSE2-NEXT: setb %r8b +; SSE2-NEXT: movzbl %r8b, %r8d +; SSE2-NEXT: shrdq $1, %r8, %rdx +; SSE2-NEXT: movzbl %bpl, %r8d +; SSE2-NEXT: shrdq $1, %r8, %rax +; SSE2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 1-byte Folded Reload +; SSE2-NEXT: shrdq $1, %r8, %rcx +; SSE2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 1-byte Folded Reload +; SSE2-NEXT: shrdq $1, %r8, %rdi +; SSE2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 1-byte Folded Reload +; SSE2-NEXT: shrdq $1, %r8, %rsi +; SSE2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 1-byte Folded Reload +; SSE2-NEXT: shrdq $1, %r8, %r11 +; SSE2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 1-byte Folded Reload +; SSE2-NEXT: shrdq $1, %r8, %r9 +; SSE2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 1-byte Folded Reload +; SSE2-NEXT: shrdq $1, %r8, %r10 +; SSE2-NEXT: movq %rdx, %xmm0 +; SSE2-NEXT: movq %rax, %xmm4 +; SSE2-NEXT: movq %rcx, %xmm1 +; SSE2-NEXT: movq %rdi, %xmm5 +; SSE2-NEXT: movq %rsi, %xmm2 +; SSE2-NEXT: movq %r11, %xmm6 +; SSE2-NEXT: movq %r9, %xmm3 +; SSE2-NEXT: movq %r10, %xmm7 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm5[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm6[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm7[0] +; SSE2-NEXT: popq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: popq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: popq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: popq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: popq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: popq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 8 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v8i64: +; SSE4: # %bb.0: +; SSE4-NEXT: pushq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: pushq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: pushq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: pushq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: pushq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: pushq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 56 +; SSE4-NEXT: .cfi_offset %rbx, -56 +; SSE4-NEXT: .cfi_offset %r12, -48 +; SSE4-NEXT: .cfi_offset %r13, -40 +; SSE4-NEXT: .cfi_offset %r14, -32 +; SSE4-NEXT: .cfi_offset %r15, -24 +; SSE4-NEXT: .cfi_offset %rbp, -16 +; SSE4-NEXT: movq %xmm3, %rcx +; SSE4-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %xmm7, %rdx +; SSE4-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movb $1, %al +; SSE4-NEXT: addb $-1, %al +; SSE4-NEXT: movq %rcx, %rax +; SSE4-NEXT: adcq %rdx, %rax +; SSE4-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE4-NEXT: movb $1, %al +; SSE4-NEXT: addb $-1, %al +; SSE4-NEXT: pextrq $1, %xmm3, %r12 +; SSE4-NEXT: pextrq $1, %xmm7, %rbp +; SSE4-NEXT: movq %r12, %rax +; SSE4-NEXT: adcq %rbp, %rax +; SSE4-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE4-NEXT: movb $1, %al +; SSE4-NEXT: addb $-1, %al +; SSE4-NEXT: movq %xmm2, %r11 +; SSE4-NEXT: movq %xmm6, %rbx +; SSE4-NEXT: movq %r11, %rax +; SSE4-NEXT: adcq %rbx, %rax +; SSE4-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE4-NEXT: movb $1, %al +; SSE4-NEXT: addb $-1, %al +; SSE4-NEXT: pextrq $1, %xmm2, %r14 +; SSE4-NEXT: pextrq $1, %xmm6, %r15 +; SSE4-NEXT: movq %r14, %rax +; SSE4-NEXT: adcq %r15, %rax +; SSE4-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE4-NEXT: movb $1, %al +; SSE4-NEXT: addb $-1, %al +; SSE4-NEXT: movq %xmm1, %r13 +; SSE4-NEXT: movq %xmm5, %r10 +; SSE4-NEXT: movq %r13, %rax +; SSE4-NEXT: adcq %r10, %rax +; SSE4-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE4-NEXT: movb $1, %al +; SSE4-NEXT: addb $-1, %al +; SSE4-NEXT: pextrq $1, %xmm1, %r9 +; SSE4-NEXT: pextrq $1, %xmm5, %r8 +; SSE4-NEXT: movq %r9, %rax +; SSE4-NEXT: adcq %r8, %rax +; SSE4-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE4-NEXT: movb $1, %al +; SSE4-NEXT: addb $-1, %al +; SSE4-NEXT: movq %xmm0, %rdi +; SSE4-NEXT: movq %xmm4, %rsi +; SSE4-NEXT: movq %rdi, %rdx +; SSE4-NEXT: adcq %rsi, %rdx +; SSE4-NEXT: movb $1, %dl +; SSE4-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; SSE4-NEXT: addb $-1, %dl +; SSE4-NEXT: pextrq $1, %xmm0, %rcx +; SSE4-NEXT: pextrq $1, %xmm4, %rax +; SSE4-NEXT: movq %rcx, %rdx +; SSE4-NEXT: adcq %rax, %rdx +; SSE4-NEXT: leaq 1(%rcx,%rax), %rdx +; SSE4-NEXT: leaq 1(%rdi,%rsi), %rax +; SSE4-NEXT: leaq 1(%r9,%r8), %rcx +; SSE4-NEXT: leaq 1(%r13,%r10), %rdi +; SSE4-NEXT: leaq 1(%r14,%r15), %rsi +; SSE4-NEXT: leaq 1(%r11,%rbx), %r11 +; SSE4-NEXT: leaq 1(%r12,%rbp), %r8 +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Reload +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload +; SSE4-NEXT: leaq 1(%r9,%r10), %r9 +; SSE4-NEXT: setb %r10b +; SSE4-NEXT: movzbl %r10b, %r10d +; SSE4-NEXT: shrdq $1, %r10, %rdx +; SSE4-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; SSE4-NEXT: shrdq $1, %r10, %rax +; SSE4-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; SSE4-NEXT: shrdq $1, %r10, %rcx +; SSE4-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; SSE4-NEXT: shrdq $1, %r10, %rdi +; SSE4-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; SSE4-NEXT: shrdq $1, %r10, %rsi +; SSE4-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; SSE4-NEXT: shrdq $1, %r10, %r11 +; SSE4-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; SSE4-NEXT: shrdq $1, %r10, %r8 +; SSE4-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; SSE4-NEXT: shrdq $1, %r10, %r9 +; SSE4-NEXT: movq %rdx, %xmm4 +; SSE4-NEXT: movq %rax, %xmm0 +; SSE4-NEXT: movq %rcx, %xmm5 +; SSE4-NEXT: movq %rdi, %xmm1 +; SSE4-NEXT: movq %rsi, %xmm6 +; SSE4-NEXT: movq %r11, %xmm2 +; SSE4-NEXT: movq %r8, %xmm7 +; SSE4-NEXT: movq %r9, %xmm3 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm5[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm6[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm7[0] +; SSE4-NEXT: popq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: popq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: popq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: popq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: popq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: popq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 8 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v8i64: +; AVX1: # %bb.0: +; AVX1-NEXT: pushq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: pushq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: pushq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: pushq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: pushq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: pushq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 56 +; AVX1-NEXT: .cfi_offset %rbx, -56 +; AVX1-NEXT: .cfi_offset %r12, -48 +; AVX1-NEXT: .cfi_offset %r13, -40 +; AVX1-NEXT: .cfi_offset %r14, -32 +; AVX1-NEXT: .cfi_offset %r15, -24 +; AVX1-NEXT: .cfi_offset %rbp, -16 +; AVX1-NEXT: vmovq %xmm1, %rcx +; AVX1-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: vmovq %xmm3, %rdx +; AVX1-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movb $1, %al +; AVX1-NEXT: addb $-1, %al +; AVX1-NEXT: movq %rcx, %rax +; AVX1-NEXT: adcq %rdx, %rax +; AVX1-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX1-NEXT: movb $1, %al +; AVX1-NEXT: addb $-1, %al +; AVX1-NEXT: vpextrq $1, %xmm1, %r12 +; AVX1-NEXT: vpextrq $1, %xmm3, %rcx +; AVX1-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movq %r12, %rax +; AVX1-NEXT: adcq %rcx, %rax +; AVX1-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX1-NEXT: movb $1, %al +; AVX1-NEXT: addb $-1, %al +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vmovq %xmm1, %r11 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm3 +; AVX1-NEXT: vmovq %xmm3, %rbx +; AVX1-NEXT: movq %r11, %rax +; AVX1-NEXT: adcq %rbx, %rax +; AVX1-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX1-NEXT: movb $1, %al +; AVX1-NEXT: addb $-1, %al +; AVX1-NEXT: vpextrq $1, %xmm1, %r14 +; AVX1-NEXT: vpextrq $1, %xmm3, %r15 +; AVX1-NEXT: movq %r14, %rax +; AVX1-NEXT: adcq %r15, %rax +; AVX1-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX1-NEXT: movb $1, %al +; AVX1-NEXT: addb $-1, %al +; AVX1-NEXT: vmovq %xmm0, %r13 +; AVX1-NEXT: vmovq %xmm2, %r10 +; AVX1-NEXT: movq %r13, %rax +; AVX1-NEXT: adcq %r10, %rax +; AVX1-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX1-NEXT: movb $1, %al +; AVX1-NEXT: addb $-1, %al +; AVX1-NEXT: vpextrq $1, %xmm0, %r9 +; AVX1-NEXT: vpextrq $1, %xmm2, %r8 +; AVX1-NEXT: movq %r9, %rax +; AVX1-NEXT: adcq %r8, %rax +; AVX1-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX1-NEXT: movb $1, %al +; AVX1-NEXT: addb $-1, %al +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm1 +; AVX1-NEXT: vmovq %xmm0, %rdi +; AVX1-NEXT: vmovq %xmm1, %rsi +; AVX1-NEXT: movq %rdi, %rcx +; AVX1-NEXT: adcq %rsi, %rcx +; AVX1-NEXT: movb $1, %cl +; AVX1-NEXT: setb %bpl +; AVX1-NEXT: addb $-1, %cl +; AVX1-NEXT: vpextrq $1, %xmm0, %rdx +; AVX1-NEXT: vpextrq $1, %xmm1, %rax +; AVX1-NEXT: movq %rdx, %rcx +; AVX1-NEXT: adcq %rax, %rcx +; AVX1-NEXT: leaq 1(%rdx,%rax), %rcx +; AVX1-NEXT: leaq 1(%rdi,%rsi), %rax +; AVX1-NEXT: leaq 1(%r9,%r8), %rdx +; AVX1-NEXT: leaq 1(%r13,%r10), %rdi +; AVX1-NEXT: leaq 1(%r14,%r15), %rsi +; AVX1-NEXT: leaq 1(%r11,%rbx), %r11 +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; AVX1-NEXT: leaq 1(%r12,%r8), %r9 +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload +; AVX1-NEXT: leaq 1(%r8,%r10), %r8 +; AVX1-NEXT: setb %r10b +; AVX1-NEXT: movzbl %r10b, %r10d +; AVX1-NEXT: shrdq $1, %r10, %rcx +; AVX1-NEXT: movzbl %bpl, %r10d +; AVX1-NEXT: shrdq $1, %r10, %rax +; AVX1-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX1-NEXT: shrdq $1, %r10, %rdx +; AVX1-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX1-NEXT: shrdq $1, %r10, %rdi +; AVX1-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX1-NEXT: shrdq $1, %r10, %rsi +; AVX1-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX1-NEXT: shrdq $1, %r10, %r11 +; AVX1-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX1-NEXT: shrdq $1, %r10, %r9 +; AVX1-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX1-NEXT: shrdq $1, %r10, %r8 +; AVX1-NEXT: vmovq %rcx, %xmm0 +; AVX1-NEXT: vmovq %rax, %xmm1 +; AVX1-NEXT: vmovq %rdx, %xmm2 +; AVX1-NEXT: vmovq %rdi, %xmm3 +; AVX1-NEXT: vmovq %rsi, %xmm4 +; AVX1-NEXT: vmovq %r11, %xmm5 +; AVX1-NEXT: vmovq %r9, %xmm6 +; AVX1-NEXT: vmovq %r8, %xmm7 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: popq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: popq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: popq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: popq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: popq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: popq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 8 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v8i64: +; AVX2: # %bb.0: +; AVX2-NEXT: pushq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: pushq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: pushq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: pushq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: pushq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: pushq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 56 +; AVX2-NEXT: .cfi_offset %rbx, -56 +; AVX2-NEXT: .cfi_offset %r12, -48 +; AVX2-NEXT: .cfi_offset %r13, -40 +; AVX2-NEXT: .cfi_offset %r14, -32 +; AVX2-NEXT: .cfi_offset %r15, -24 +; AVX2-NEXT: .cfi_offset %rbp, -16 +; AVX2-NEXT: vmovq %xmm1, %rcx +; AVX2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: vmovq %xmm3, %rdx +; AVX2-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movb $1, %al +; AVX2-NEXT: addb $-1, %al +; AVX2-NEXT: movq %rcx, %rax +; AVX2-NEXT: adcq %rdx, %rax +; AVX2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX2-NEXT: movb $1, %al +; AVX2-NEXT: addb $-1, %al +; AVX2-NEXT: vpextrq $1, %xmm1, %r12 +; AVX2-NEXT: vpextrq $1, %xmm3, %rcx +; AVX2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movq %r12, %rax +; AVX2-NEXT: adcq %rcx, %rax +; AVX2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX2-NEXT: movb $1, %al +; AVX2-NEXT: addb $-1, %al +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX2-NEXT: vmovq %xmm1, %r11 +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm3 +; AVX2-NEXT: vmovq %xmm3, %rbx +; AVX2-NEXT: movq %r11, %rax +; AVX2-NEXT: adcq %rbx, %rax +; AVX2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX2-NEXT: movb $1, %al +; AVX2-NEXT: addb $-1, %al +; AVX2-NEXT: vpextrq $1, %xmm1, %r14 +; AVX2-NEXT: vpextrq $1, %xmm3, %r15 +; AVX2-NEXT: movq %r14, %rax +; AVX2-NEXT: adcq %r15, %rax +; AVX2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX2-NEXT: movb $1, %al +; AVX2-NEXT: addb $-1, %al +; AVX2-NEXT: vmovq %xmm0, %r13 +; AVX2-NEXT: vmovq %xmm2, %r10 +; AVX2-NEXT: movq %r13, %rax +; AVX2-NEXT: adcq %r10, %rax +; AVX2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX2-NEXT: movb $1, %al +; AVX2-NEXT: addb $-1, %al +; AVX2-NEXT: vpextrq $1, %xmm0, %r9 +; AVX2-NEXT: vpextrq $1, %xmm2, %r8 +; AVX2-NEXT: movq %r9, %rax +; AVX2-NEXT: adcq %r8, %rax +; AVX2-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX2-NEXT: movb $1, %al +; AVX2-NEXT: addb $-1, %al +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm1 +; AVX2-NEXT: vmovq %xmm0, %rdi +; AVX2-NEXT: vmovq %xmm1, %rsi +; AVX2-NEXT: movq %rdi, %rcx +; AVX2-NEXT: adcq %rsi, %rcx +; AVX2-NEXT: movb $1, %cl +; AVX2-NEXT: setb %bpl +; AVX2-NEXT: addb $-1, %cl +; AVX2-NEXT: vpextrq $1, %xmm0, %rdx +; AVX2-NEXT: vpextrq $1, %xmm1, %rax +; AVX2-NEXT: movq %rdx, %rcx +; AVX2-NEXT: adcq %rax, %rcx +; AVX2-NEXT: leaq 1(%rdx,%rax), %rcx +; AVX2-NEXT: leaq 1(%rdi,%rsi), %rax +; AVX2-NEXT: leaq 1(%r9,%r8), %rdx +; AVX2-NEXT: leaq 1(%r13,%r10), %rdi +; AVX2-NEXT: leaq 1(%r14,%r15), %rsi +; AVX2-NEXT: leaq 1(%r11,%rbx), %r11 +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; AVX2-NEXT: leaq 1(%r12,%r8), %r9 +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload +; AVX2-NEXT: leaq 1(%r8,%r10), %r8 +; AVX2-NEXT: setb %r10b +; AVX2-NEXT: movzbl %r10b, %r10d +; AVX2-NEXT: shrdq $1, %r10, %rcx +; AVX2-NEXT: movzbl %bpl, %r10d +; AVX2-NEXT: shrdq $1, %r10, %rax +; AVX2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX2-NEXT: shrdq $1, %r10, %rdx +; AVX2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX2-NEXT: shrdq $1, %r10, %rdi +; AVX2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX2-NEXT: shrdq $1, %r10, %rsi +; AVX2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX2-NEXT: shrdq $1, %r10, %r11 +; AVX2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX2-NEXT: shrdq $1, %r10, %r9 +; AVX2-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX2-NEXT: shrdq $1, %r10, %r8 +; AVX2-NEXT: vmovq %rcx, %xmm0 +; AVX2-NEXT: vmovq %rax, %xmm1 +; AVX2-NEXT: vmovq %rdx, %xmm2 +; AVX2-NEXT: vmovq %rdi, %xmm3 +; AVX2-NEXT: vmovq %rsi, %xmm4 +; AVX2-NEXT: vmovq %r11, %xmm5 +; AVX2-NEXT: vmovq %r9, %xmm6 +; AVX2-NEXT: vmovq %r8, %xmm7 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm2, %ymm1 +; AVX2-NEXT: popq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: popq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: popq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: popq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: popq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: popq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 8 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v8i64: +; AVX512: # %bb.0: +; AVX512-NEXT: pushq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: pushq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: pushq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: pushq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: pushq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: pushq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 56 +; AVX512-NEXT: .cfi_offset %rbx, -56 +; AVX512-NEXT: .cfi_offset %r12, -48 +; AVX512-NEXT: .cfi_offset %r13, -40 +; AVX512-NEXT: .cfi_offset %r14, -32 +; AVX512-NEXT: .cfi_offset %r15, -24 +; AVX512-NEXT: .cfi_offset %rbp, -16 +; AVX512-NEXT: vmovq %xmm0, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: vmovq %xmm1, %rdx +; AVX512-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: movb $1, %al +; AVX512-NEXT: addb $-1, %al +; AVX512-NEXT: movq %rcx, %rax +; AVX512-NEXT: adcq %rdx, %rax +; AVX512-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX512-NEXT: movb $1, %al +; AVX512-NEXT: vpextrq $1, %xmm0, %r12 +; AVX512-NEXT: vpextrq $1, %xmm1, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: addb $-1, %al +; AVX512-NEXT: movq %r12, %rax +; AVX512-NEXT: adcq %rcx, %rax +; AVX512-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX512-NEXT: movb $1, %al +; AVX512-NEXT: addb $-1, %al +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX512-NEXT: vmovq %xmm2, %r11 +; AVX512-NEXT: vextracti128 $1, %ymm1, %xmm3 +; AVX512-NEXT: vmovq %xmm3, %rbx +; AVX512-NEXT: movq %r11, %rax +; AVX512-NEXT: adcq %rbx, %rax +; AVX512-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX512-NEXT: movb $1, %al +; AVX512-NEXT: addb $-1, %al +; AVX512-NEXT: vpextrq $1, %xmm2, %r14 +; AVX512-NEXT: vpextrq $1, %xmm3, %r15 +; AVX512-NEXT: movq %r14, %rax +; AVX512-NEXT: adcq %r15, %rax +; AVX512-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX512-NEXT: movb $1, %al +; AVX512-NEXT: addb $-1, %al +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm0 +; AVX512-NEXT: vmovq %xmm0, %r13 +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm1 +; AVX512-NEXT: vmovq %xmm1, %r10 +; AVX512-NEXT: movq %r13, %rax +; AVX512-NEXT: adcq %r10, %rax +; AVX512-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX512-NEXT: movb $1, %al +; AVX512-NEXT: vpextrq $1, %xmm0, %r9 +; AVX512-NEXT: addb $-1, %al +; AVX512-NEXT: vpextrq $1, %xmm1, %r8 +; AVX512-NEXT: movq %r9, %rax +; AVX512-NEXT: adcq %r8, %rax +; AVX512-NEXT: setb {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Folded Spill +; AVX512-NEXT: movb $1, %al +; AVX512-NEXT: addb $-1, %al +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX512-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX512-NEXT: vmovq %xmm0, %rdi +; AVX512-NEXT: vmovq %xmm1, %rsi +; AVX512-NEXT: movq %rdi, %rcx +; AVX512-NEXT: adcq %rsi, %rcx +; AVX512-NEXT: movb $1, %cl +; AVX512-NEXT: setb %bpl +; AVX512-NEXT: vpextrq $1, %xmm0, %rdx +; AVX512-NEXT: vpextrq $1, %xmm1, %rax +; AVX512-NEXT: addb $-1, %cl +; AVX512-NEXT: movq %rdx, %rcx +; AVX512-NEXT: adcq %rax, %rcx +; AVX512-NEXT: leaq 1(%rdx,%rax), %rcx +; AVX512-NEXT: leaq 1(%rdi,%rsi), %rax +; AVX512-NEXT: leaq 1(%r9,%r8), %rdx +; AVX512-NEXT: leaq 1(%r13,%r10), %rdi +; AVX512-NEXT: leaq 1(%r14,%r15), %rsi +; AVX512-NEXT: leaq 1(%r11,%rbx), %r11 +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; AVX512-NEXT: leaq 1(%r12,%r8), %r9 +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload +; AVX512-NEXT: leaq 1(%r8,%r10), %r8 +; AVX512-NEXT: setb %r10b +; AVX512-NEXT: movzbl %r10b, %r10d +; AVX512-NEXT: shrdq $1, %r10, %rcx +; AVX512-NEXT: movzbl %bpl, %r10d +; AVX512-NEXT: shrdq $1, %r10, %rax +; AVX512-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX512-NEXT: shrdq $1, %r10, %rdx +; AVX512-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX512-NEXT: shrdq $1, %r10, %rdi +; AVX512-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX512-NEXT: shrdq $1, %r10, %rsi +; AVX512-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX512-NEXT: shrdq $1, %r10, %r11 +; AVX512-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX512-NEXT: shrdq $1, %r10, %r9 +; AVX512-NEXT: movzbl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 1-byte Folded Reload +; AVX512-NEXT: shrdq $1, %r10, %r8 +; AVX512-NEXT: vmovq %rcx, %xmm0 +; AVX512-NEXT: vmovq %rax, %xmm1 +; AVX512-NEXT: vmovq %rdx, %xmm2 +; AVX512-NEXT: vmovq %rdi, %xmm3 +; AVX512-NEXT: vmovq %rsi, %xmm4 +; AVX512-NEXT: vmovq %r11, %xmm5 +; AVX512-NEXT: vmovq %r9, %xmm6 +; AVX512-NEXT: vmovq %r8, %xmm7 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX512-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX512-NEXT: vinserti128 $1, %xmm1, %ymm2, %ymm1 +; AVX512-NEXT: vinserti64x4 $1, %ymm0, %zmm1, %zmm0 +; AVX512-NEXT: popq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: popq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: popq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: popq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: popq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: popq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 8 +; AVX512-NEXT: retq + %x0 = zext <8 x i64> %a0 to <8 x i128> + %x1 = zext <8 x i64> %a1 to <8 x i128> + %sum = add <8 x i128> %x0, %x1 + %inc = add <8 x i128> %sum, <i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1> + %shift = lshr <8 x i128> %inc, <i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1> + %res = trunc <8 x i128> %shift to <8 x i64> + ret <8 x i64> %res +} + diff --git a/llvm/test/CodeGen/X86/avgfloors.ll b/llvm/test/CodeGen/X86/avgfloors.ll new file mode 100644 index 000000000000..a3864ab4bb44 --- /dev/null +++ b/llvm/test/CodeGen/X86/avgfloors.ll @@ -0,0 +1,3437 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE2 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE4 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2 +; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=AVX,AVX512 + +; +; 128-bit vectors +; + +define <16 x i8> @test_fixed_v16i8(<16 x i8> %a0, <16 x i8> %a1) { +; SSE-LABEL: test_fixed_v16i8: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: pand %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm0 +; SSE-NEXT: psrlw $1, %xmm0 +; SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; SSE-NEXT: movdqa {{.*#+}} xmm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; SSE-NEXT: pxor %xmm1, %xmm0 +; SSE-NEXT: paddb %xmm2, %xmm0 +; SSE-NEXT: psubb %xmm1, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v16i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpaddb %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vpsubb %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v16i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX2-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX2-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 +; AVX2-NEXT: vpbroadcastb {{.*#+}} xmm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX2-NEXT: vpaddb %xmm2, %xmm0, %xmm0 +; AVX2-NEXT: vpsubb %xmm1, %xmm0, %xmm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v16i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX512-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX512-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX512-NEXT: vpbroadcastb {{.*#+}} xmm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX512-NEXT: vpternlogd $108, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm1, %xmm0 +; AVX512-NEXT: vpaddb %xmm2, %xmm0, %xmm0 +; AVX512-NEXT: vpsubb %xmm1, %xmm0, %xmm0 +; AVX512-NEXT: retq + %and = and <16 x i8> %a0, %a1 + %xor = xor <16 x i8> %a0, %a1 + %shift = ashr <16 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = add <16 x i8> %and, %shift + ret <16 x i8> %res +} + +define <16 x i8> @test_ext_v16i8(<16 x i8> %a0, <16 x i8> %a1) { +; SSE2-LABEL: test_ext_v16i8: +; SSE2: # %bb.0: +; SSE2-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7] +; SSE2-NEXT: psraw $8, %xmm2 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm0[8],xmm3[9],xmm0[9],xmm3[10],xmm0[10],xmm3[11],xmm0[11],xmm3[12],xmm0[12],xmm3[13],xmm0[13],xmm3[14],xmm0[14],xmm3[15],xmm0[15] +; SSE2-NEXT: psraw $8, %xmm3 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7] +; SSE2-NEXT: psraw $8, %xmm0 +; SSE2-NEXT: paddw %xmm2, %xmm0 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm1 = xmm1[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15] +; SSE2-NEXT: psraw $8, %xmm1 +; SSE2-NEXT: paddw %xmm3, %xmm1 +; SSE2-NEXT: psrlw $1, %xmm0 +; SSE2-NEXT: psrlw $1, %xmm1 +; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0] +; SSE2-NEXT: pand %xmm2, %xmm1 +; SSE2-NEXT: pand %xmm2, %xmm0 +; SSE2-NEXT: packuswb %xmm1, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v16i8: +; SSE4: # %bb.0: +; SSE4-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm2, %xmm2 +; SSE4-NEXT: pmovsxbw %xmm0, %xmm3 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm4 +; SSE4-NEXT: paddw %xmm2, %xmm4 +; SSE4-NEXT: pmovsxbw %xmm1, %xmm0 +; SSE4-NEXT: paddw %xmm3, %xmm0 +; SSE4-NEXT: psrlw $1, %xmm4 +; SSE4-NEXT: psrlw $1, %xmm0 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm1 = [255,255,255,255,255,255,255,255] +; SSE4-NEXT: pand %xmm1, %xmm0 +; SSE4-NEXT: pand %xmm1, %xmm4 +; SSE4-NEXT: packuswb %xmm4, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v16i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxbw %xmm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm3 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm3, %xmm3 +; AVX1-NEXT: vpaddw %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxbw %xmm1, %xmm1 +; AVX1-NEXT: vpaddw %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm2, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] +; AVX1-NEXT: vpand %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm2, %xmm1, %xmm1 +; AVX1-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v16i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxbw %xmm1, %ymm1 +; AVX2-NEXT: vpaddw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 +; AVX2-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 +; AVX2-NEXT: vzeroupper +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v16i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxbw %xmm0, %ymm0 +; AVX512-NEXT: vpmovsxbw %xmm1, %ymm1 +; AVX512-NEXT: vpaddw %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX512-NEXT: vpmovwb %ymm0, %xmm0 +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %x0 = sext <16 x i8> %a0 to <16 x i16> + %x1 = sext <16 x i8> %a1 to <16 x i16> + %sum = add <16 x i16> %x0, %x1 + %shift = ashr <16 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <16 x i16> %shift to <16 x i8> + ret <16 x i8> %res +} + +define <8 x i16> @test_fixed_v8i16(<8 x i16> %a0, <8 x i16> %a1) { +; SSE-LABEL: test_fixed_v8i16: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: pand %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm0 +; SSE-NEXT: psraw $1, %xmm0 +; SSE-NEXT: paddw %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_fixed_v8i16: +; AVX: # %bb.0: +; AVX-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX-NEXT: vpsraw $1, %xmm0, %xmm0 +; AVX-NEXT: vpaddw %xmm0, %xmm2, %xmm0 +; AVX-NEXT: retq + %and = and <8 x i16> %a0, %a1 + %xor = xor <8 x i16> %a1, %a0 + %shift = ashr <8 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = add <8 x i16> %and, %shift + ret <8 x i16> %res +} + +define <8 x i16> @test_ext_v8i16(<8 x i16> %a0, <8 x i16> %a1) { +; SSE2-LABEL: test_ext_v8i16: +; SSE2: # %bb.0: +; SSE2-NEXT: punpckhwd {{.*#+}} xmm2 = xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7] +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3] +; SSE2-NEXT: psrad $16, %xmm3 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm4 = xmm4[4],xmm1[4],xmm4[5],xmm1[5],xmm4[6],xmm1[6],xmm4[7],xmm1[7] +; SSE2-NEXT: psrad $16, %xmm4 +; SSE2-NEXT: paddd %xmm2, %xmm4 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3] +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: paddd %xmm3, %xmm0 +; SSE2-NEXT: pslld $15, %xmm4 +; SSE2-NEXT: psrad $16, %xmm4 +; SSE2-NEXT: pslld $15, %xmm0 +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: packssdw %xmm4, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v8i16: +; SSE4: # %bb.0: +; SSE4-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm2, %xmm2 +; SSE4-NEXT: pmovsxwd %xmm0, %xmm3 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm4 +; SSE4-NEXT: paddd %xmm2, %xmm4 +; SSE4-NEXT: pmovsxwd %xmm1, %xmm0 +; SSE4-NEXT: paddd %xmm3, %xmm0 +; SSE4-NEXT: psrld $1, %xmm4 +; SSE4-NEXT: psrld $1, %xmm0 +; SSE4-NEXT: pxor %xmm1, %xmm1 +; SSE4-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3],xmm0[4],xmm1[5],xmm0[6],xmm1[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm4 = xmm4[0],xmm1[1],xmm4[2],xmm1[3],xmm4[4],xmm1[5],xmm4[6],xmm1[7] +; SSE4-NEXT: packusdw %xmm4, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v8i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxwd %xmm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm3 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm3, %xmm3 +; AVX1-NEXT: vpaddd %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxwd %xmm1, %xmm1 +; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm2, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3],xmm0[4],xmm2[5],xmm0[6],xmm2[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3],xmm1[4],xmm2[5],xmm1[6],xmm2[7] +; AVX1-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v8i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxwd %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxwd %xmm1, %ymm1 +; AVX2-NEXT: vpaddd %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u] +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3] +; AVX2-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 +; AVX2-NEXT: vzeroupper +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v8i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxwd %xmm0, %ymm0 +; AVX512-NEXT: vpmovsxwd %xmm1, %ymm1 +; AVX512-NEXT: vpaddd %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX512-NEXT: vpmovdw %ymm0, %xmm0 +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %x0 = sext <8 x i16> %a0 to <8 x i32> + %x1 = sext <8 x i16> %a1 to <8 x i32> + %sum = add <8 x i32> %x0, %x1 + %shift = ashr <8 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <8 x i32> %shift to <8 x i16> + ret <8 x i16> %res +} + +define <4 x i32> @test_fixed_v4i32(<4 x i32> %a0, <4 x i32> %a1) { +; SSE-LABEL: test_fixed_v4i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: pand %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm0 +; SSE-NEXT: psrad $1, %xmm0 +; SSE-NEXT: paddd %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_fixed_v4i32: +; AVX: # %bb.0: +; AVX-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX-NEXT: vpsrad $1, %xmm0, %xmm0 +; AVX-NEXT: vpaddd %xmm0, %xmm2, %xmm0 +; AVX-NEXT: retq + %and = and <4 x i32> %a0, %a1 + %xor = xor <4 x i32> %a1, %a0 + %shift = ashr <4 x i32> %xor, <i32 1, i32 1, i32 1, i32 1> + %res = add <4 x i32> %and, %shift + ret <4 x i32> %res +} + +define <4 x i32> @test_ext_v4i32(<4 x i32> %a0, <4 x i32> %a1) { +; SSE2-LABEL: test_ext_v4i32: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm2, %xmm2 +; SSE2-NEXT: pxor %xmm3, %xmm3 +; SSE2-NEXT: pcmpgtd %xmm0, %xmm3 +; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm0[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1] +; SSE2-NEXT: pxor %xmm3, %xmm3 +; SSE2-NEXT: pcmpgtd %xmm4, %xmm3 +; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm3[0],xmm4[1],xmm3[1] +; SSE2-NEXT: pxor %xmm3, %xmm3 +; SSE2-NEXT: pcmpgtd %xmm1, %xmm3 +; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm1[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1] +; SSE2-NEXT: paddq %xmm1, %xmm0 +; SSE2-NEXT: pcmpgtd %xmm5, %xmm2 +; SSE2-NEXT: punpckldq {{.*#+}} xmm5 = xmm5[0],xmm2[0],xmm5[1],xmm2[1] +; SSE2-NEXT: paddq %xmm4, %xmm5 +; SSE2-NEXT: psrlq $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm5 +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm5[0,2] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v4i32: +; SSE4: # %bb.0: +; SSE4-NEXT: pmovsxdq %xmm0, %xmm2 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm3 +; SSE4-NEXT: pmovsxdq %xmm1, %xmm0 +; SSE4-NEXT: paddq %xmm2, %xmm0 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm1, %xmm1 +; SSE4-NEXT: paddq %xmm3, %xmm1 +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v4i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vpmovsxdq %xmm0, %xmm2 +; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm0, %xmm0 +; AVX1-NEXT: vpmovsxdq %xmm1, %xmm3 +; AVX1-NEXT: vpaddq %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm1, %xmm1 +; AVX1-NEXT: vpaddq %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm2, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm1[0,2],xmm0[0,2] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v4i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxdq %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxdq %xmm1, %ymm1 +; AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 +; AVX2-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] +; AVX2-NEXT: vzeroupper +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v4i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxdq %xmm0, %ymm0 +; AVX512-NEXT: vpmovsxdq %xmm1, %ymm1 +; AVX512-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX512-NEXT: vpmovqd %ymm0, %xmm0 +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %x0 = sext <4 x i32> %a0 to <4 x i64> + %x1 = sext <4 x i32> %a1 to <4 x i64> + %sum = add <4 x i64> %x0, %x1 + %shift = ashr <4 x i64> %sum, <i64 1, i64 1, i64 1, i64 1> + %res = trunc <4 x i64> %shift to <4 x i32> + ret <4 x i32> %res +} + +define <2 x i64> @test_fixed_v2i64(<2 x i64> %a0, <2 x i64> %a1) { +; SSE2-LABEL: test_fixed_v2i64: +; SSE2: # %bb.0: +; SSE2-NEXT: movdqa %xmm0, %xmm2 +; SSE2-NEXT: pand %xmm1, %xmm2 +; SSE2-NEXT: pxor %xmm0, %xmm1 +; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm1[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm3 +; SSE2-NEXT: psrlq $1, %xmm1 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1] +; SSE2-NEXT: paddq %xmm2, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_fixed_v2i64: +; SSE4: # %bb.0: +; SSE4-NEXT: movdqa %xmm0, %xmm2 +; SSE4-NEXT: pand %xmm1, %xmm2 +; SSE4-NEXT: pxor %xmm1, %xmm0 +; SSE4-NEXT: movdqa %xmm0, %xmm1 +; SSE4-NEXT: psrad $1, %xmm1 +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] +; SSE4-NEXT: paddq %xmm2, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_fixed_v2i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX1-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7] +; AVX1-NEXT: vpaddq %xmm0, %xmm2, %xmm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v2i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX2-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX2-NEXT: vpsrad $1, %xmm0, %xmm1 +; AVX2-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3] +; AVX2-NEXT: vpaddq %xmm0, %xmm2, %xmm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v2i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX512-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX512-NEXT: vpsraq $1, %xmm0, %xmm0 +; AVX512-NEXT: vpaddq %xmm0, %xmm2, %xmm0 +; AVX512-NEXT: retq + %and = and <2 x i64> %a0, %a1 + %xor = xor <2 x i64> %a1, %a0 + %shift = ashr <2 x i64> %xor, <i64 1, i64 1> + %res = add <2 x i64> %and, %shift + ret <2 x i64> %res +} + +define <2 x i64> @test_ext_v2i64(<2 x i64> %a0, <2 x i64> %a1) { +; SSE2-LABEL: test_ext_v2i64: +; SSE2: # %bb.0: +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; SSE2-NEXT: movq %xmm2, %rax +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: movq %xmm0, %rdx +; SSE2-NEXT: movq %rdx, %rsi +; SSE2-NEXT: sarq $63, %rsi +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rdi +; SSE2-NEXT: movq %rdi, %r8 +; SSE2-NEXT: sarq $63, %r8 +; SSE2-NEXT: movq %xmm1, %r9 +; SSE2-NEXT: movq %r9, %r10 +; SSE2-NEXT: sarq $63, %r10 +; SSE2-NEXT: addq %r9, %rdx +; SSE2-NEXT: adcq %rsi, %r10 +; SSE2-NEXT: addq %rdi, %rax +; SSE2-NEXT: adcq %rcx, %r8 +; SSE2-NEXT: shldq $63, %rax, %r8 +; SSE2-NEXT: shldq $63, %rdx, %r10 +; SSE2-NEXT: movq %r10, %xmm0 +; SSE2-NEXT: movq %r8, %xmm1 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v2i64: +; SSE4: # %bb.0: +; SSE4-NEXT: movq %xmm0, %rax +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: pextrq $1, %xmm0, %rdx +; SSE4-NEXT: movq %rdx, %rsi +; SSE4-NEXT: sarq $63, %rsi +; SSE4-NEXT: movq %xmm1, %rdi +; SSE4-NEXT: movq %rdi, %r8 +; SSE4-NEXT: sarq $63, %r8 +; SSE4-NEXT: pextrq $1, %xmm1, %r9 +; SSE4-NEXT: movq %r9, %r10 +; SSE4-NEXT: sarq $63, %r10 +; SSE4-NEXT: addq %r9, %rdx +; SSE4-NEXT: adcq %rsi, %r10 +; SSE4-NEXT: addq %rdi, %rax +; SSE4-NEXT: adcq %rcx, %r8 +; SSE4-NEXT: shldq $63, %rax, %r8 +; SSE4-NEXT: shldq $63, %rdx, %r10 +; SSE4-NEXT: movq %r10, %xmm1 +; SSE4-NEXT: movq %r8, %xmm0 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE4-NEXT: retq +; +; AVX-LABEL: test_ext_v2i64: +; AVX: # %bb.0: +; AVX-NEXT: vmovq %xmm0, %rax +; AVX-NEXT: movq %rax, %rcx +; AVX-NEXT: sarq $63, %rcx +; AVX-NEXT: vpextrq $1, %xmm0, %rdx +; AVX-NEXT: movq %rdx, %rsi +; AVX-NEXT: sarq $63, %rsi +; AVX-NEXT: vmovq %xmm1, %rdi +; AVX-NEXT: movq %rdi, %r8 +; AVX-NEXT: sarq $63, %r8 +; AVX-NEXT: vpextrq $1, %xmm1, %r9 +; AVX-NEXT: movq %r9, %r10 +; AVX-NEXT: sarq $63, %r10 +; AVX-NEXT: addq %r9, %rdx +; AVX-NEXT: adcq %rsi, %r10 +; AVX-NEXT: addq %rdi, %rax +; AVX-NEXT: adcq %rcx, %r8 +; AVX-NEXT: shldq $63, %rax, %r8 +; AVX-NEXT: shldq $63, %rdx, %r10 +; AVX-NEXT: vmovq %r10, %xmm0 +; AVX-NEXT: vmovq %r8, %xmm1 +; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX-NEXT: retq + %x0 = sext <2 x i64> %a0 to <2 x i128> + %x1 = sext <2 x i64> %a1 to <2 x i128> + %sum = add <2 x i128> %x0, %x1 + %shift = ashr <2 x i128> %sum, <i128 1, i128 1> + %res = trunc <2 x i128> %shift to <2 x i64> + ret <2 x i64> %res +} + +; +; 256-bit vectors +; + +define <32 x i8> @test_fixed_v32i8(<32 x i8> %a0, <32 x i8> %a1) { +; SSE-LABEL: test_fixed_v32i8: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: pand %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: pand %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm0 +; SSE-NEXT: pxor %xmm3, %xmm1 +; SSE-NEXT: psrlw $1, %xmm1 +; SSE-NEXT: movdqa {{.*#+}} xmm2 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; SSE-NEXT: pand %xmm2, %xmm1 +; SSE-NEXT: movdqa {{.*#+}} xmm3 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; SSE-NEXT: pxor %xmm3, %xmm1 +; SSE-NEXT: paddb %xmm4, %xmm1 +; SSE-NEXT: psrlw $1, %xmm0 +; SSE-NEXT: pand %xmm2, %xmm0 +; SSE-NEXT: pxor %xmm3, %xmm0 +; SSE-NEXT: paddb %xmm5, %xmm0 +; SSE-NEXT: psubb %xmm3, %xmm0 +; SSE-NEXT: psubb %xmm3, %xmm1 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v32i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm1 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; AVX1-NEXT: vpand %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX1-NEXT: vpxor %xmm4, %xmm1, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpxor %xmm4, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpaddb %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpsubb %xmm4, %xmm0, %xmm0 +; AVX1-NEXT: vpaddb %xmm2, %xmm1, %xmm1 +; AVX1-NEXT: vpsubb %xmm4, %xmm1, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v32i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 +; AVX2-NEXT: vpbroadcastb {{.*#+}} ymm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX2-NEXT: vpxor %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpaddb %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpsubb %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v32i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX512-NEXT: vpbroadcastb {{.*#+}} ymm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX512-NEXT: vpternlogd $108, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm1, %ymm0 +; AVX512-NEXT: vpaddb %ymm2, %ymm0, %ymm0 +; AVX512-NEXT: vpsubb %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: retq + %and = and <32 x i8> %a0, %a1 + %xor = xor <32 x i8> %a0, %a1 + %shift = ashr <32 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = add <32 x i8> %and, %shift + ret <32 x i8> %res +} + +define <32 x i8> @test_ext_v32i8(<32 x i8> %a0, <32 x i8> %a1) { +; SSE2-LABEL: test_ext_v32i8: +; SSE2: # %bb.0: +; SSE2-NEXT: punpcklbw {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1],xmm4[2],xmm1[2],xmm4[3],xmm1[3],xmm4[4],xmm1[4],xmm4[5],xmm1[5],xmm4[6],xmm1[6],xmm4[7],xmm1[7] +; SSE2-NEXT: psraw $8, %xmm4 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm5 = xmm5[8],xmm1[8],xmm5[9],xmm1[9],xmm5[10],xmm1[10],xmm5[11],xmm1[11],xmm5[12],xmm1[12],xmm5[13],xmm1[13],xmm5[14],xmm1[14],xmm5[15],xmm1[15] +; SSE2-NEXT: psraw $8, %xmm5 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm6 = xmm6[0],xmm0[0],xmm6[1],xmm0[1],xmm6[2],xmm0[2],xmm6[3],xmm0[3],xmm6[4],xmm0[4],xmm6[5],xmm0[5],xmm6[6],xmm0[6],xmm6[7],xmm0[7] +; SSE2-NEXT: psraw $8, %xmm6 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm7 = xmm7[8],xmm0[8],xmm7[9],xmm0[9],xmm7[10],xmm0[10],xmm7[11],xmm0[11],xmm7[12],xmm0[12],xmm7[13],xmm0[13],xmm7[14],xmm0[14],xmm7[15],xmm0[15] +; SSE2-NEXT: psraw $8, %xmm7 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1],xmm1[2],xmm3[2],xmm1[3],xmm3[3],xmm1[4],xmm3[4],xmm1[5],xmm3[5],xmm1[6],xmm3[6],xmm1[7],xmm3[7] +; SSE2-NEXT: psraw $8, %xmm1 +; SSE2-NEXT: paddw %xmm4, %xmm1 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm3 = xmm3[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15] +; SSE2-NEXT: psraw $8, %xmm3 +; SSE2-NEXT: paddw %xmm5, %xmm3 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3],xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7] +; SSE2-NEXT: psraw $8, %xmm0 +; SSE2-NEXT: paddw %xmm6, %xmm0 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm2 = xmm2[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15] +; SSE2-NEXT: psraw $8, %xmm2 +; SSE2-NEXT: paddw %xmm7, %xmm2 +; SSE2-NEXT: psrlw $1, %xmm1 +; SSE2-NEXT: psrlw $1, %xmm3 +; SSE2-NEXT: psrlw $1, %xmm0 +; SSE2-NEXT: psrlw $1, %xmm2 +; SSE2-NEXT: movdqa {{.*#+}} xmm4 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0] +; SSE2-NEXT: pand %xmm4, %xmm2 +; SSE2-NEXT: pand %xmm4, %xmm0 +; SSE2-NEXT: packuswb %xmm2, %xmm0 +; SSE2-NEXT: pand %xmm4, %xmm3 +; SSE2-NEXT: pand %xmm4, %xmm1 +; SSE2-NEXT: packuswb %xmm3, %xmm1 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v32i8: +; SSE4: # %bb.0: +; SSE4-NEXT: pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm4, %xmm5 +; SSE4-NEXT: pmovsxbw %xmm1, %xmm6 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm1, %xmm7 +; SSE4-NEXT: pmovsxbw %xmm0, %xmm8 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm4 +; SSE4-NEXT: paddw %xmm5, %xmm4 +; SSE4-NEXT: pmovsxbw %xmm3, %xmm1 +; SSE4-NEXT: paddw %xmm6, %xmm1 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm3 +; SSE4-NEXT: paddw %xmm7, %xmm3 +; SSE4-NEXT: pmovsxbw %xmm2, %xmm0 +; SSE4-NEXT: paddw %xmm8, %xmm0 +; SSE4-NEXT: psrlw $1, %xmm4 +; SSE4-NEXT: psrlw $1, %xmm1 +; SSE4-NEXT: psrlw $1, %xmm3 +; SSE4-NEXT: psrlw $1, %xmm0 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] +; SSE4-NEXT: pand %xmm2, %xmm0 +; SSE4-NEXT: pand %xmm2, %xmm3 +; SSE4-NEXT: packuswb %xmm3, %xmm0 +; SSE4-NEXT: pand %xmm2, %xmm1 +; SSE4-NEXT: pand %xmm2, %xmm4 +; SSE4-NEXT: packuswb %xmm4, %xmm1 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v32i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxbw %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm4 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm4, %xmm4 +; AVX1-NEXT: vpmovsxbw %xmm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm5 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm5, %xmm5 +; AVX1-NEXT: vpaddw %xmm5, %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxbw %xmm1, %xmm5 +; AVX1-NEXT: vpaddw %xmm5, %xmm3, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpshufd {{.*#+}} xmm5 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm5, %xmm5 +; AVX1-NEXT: vpaddw %xmm5, %xmm4, %xmm4 +; AVX1-NEXT: vpmovsxbw %xmm1, %xmm1 +; AVX1-NEXT: vpaddw %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm2, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm3, %xmm2 +; AVX1-NEXT: vpsrlw $1, %xmm4, %xmm3 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm4 = [255,255,255,255,255,255,255,255] +; AVX1-NEXT: vpand %xmm4, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm4, %xmm3, %xmm3 +; AVX1-NEXT: vpackuswb %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm4, %xmm2, %xmm2 +; AVX1-NEXT: vpand %xmm4, %xmm1, %xmm1 +; AVX1-NEXT: vpackuswb %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v32i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxbw %xmm0, %ymm2 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxbw %xmm1, %ymm3 +; AVX2-NEXT: vpaddw %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX2-NEXT: vpmovsxbw %xmm1, %ymm1 +; AVX2-NEXT: vpaddw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm2, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpbroadcastw {{.*#+}} ymm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0] +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpand %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vpackuswb %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v32i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxbw %ymm0, %zmm0 +; AVX512-NEXT: vpmovsxbw %ymm1, %zmm1 +; AVX512-NEXT: vpaddw %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovwb %zmm0, %ymm0 +; AVX512-NEXT: retq + %x0 = sext <32 x i8> %a0 to <32 x i16> + %x1 = sext <32 x i8> %a1 to <32 x i16> + %sum = add <32 x i16> %x0, %x1 + %shift = ashr <32 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <32 x i16> %shift to <32 x i8> + ret <32 x i8> %res +} + +define <16 x i16> @test_fixed_v16i16(<16 x i16> %a0, <16 x i16> %a1) { +; SSE-LABEL: test_fixed_v16i16: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: pand %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: pand %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm0 +; SSE-NEXT: pxor %xmm3, %xmm1 +; SSE-NEXT: psraw $1, %xmm1 +; SSE-NEXT: paddw %xmm4, %xmm1 +; SSE-NEXT: psraw $1, %xmm0 +; SSE-NEXT: paddw %xmm5, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v16i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsraw $1, %xmm0, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsraw $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpaddw %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpaddw %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v16i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsraw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpaddw %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v16i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: vpsraw $1, %ymm0, %ymm0 +; AVX512-NEXT: vpaddw %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %and = and <16 x i16> %a0, %a1 + %xor = xor <16 x i16> %a1, %a0 + %shift = ashr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = add <16 x i16> %and, %shift + ret <16 x i16> %res +} + +define <16 x i16> @test_ext_v16i16(<16 x i16> %a0, <16 x i16> %a1) { +; SSE2-LABEL: test_ext_v16i16: +; SSE2: # %bb.0: +; SSE2-NEXT: punpckhwd {{.*#+}} xmm4 = xmm4[4],xmm0[4],xmm4[5],xmm0[5],xmm4[6],xmm0[6],xmm4[7],xmm0[7] +; SSE2-NEXT: psrad $16, %xmm4 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm0[0],xmm5[1],xmm0[1],xmm5[2],xmm0[2],xmm5[3],xmm0[3] +; SSE2-NEXT: psrad $16, %xmm5 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm6 = xmm6[4],xmm1[4],xmm6[5],xmm1[5],xmm6[6],xmm1[6],xmm6[7],xmm1[7] +; SSE2-NEXT: psrad $16, %xmm6 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm7 = xmm7[0],xmm1[0],xmm7[1],xmm1[1],xmm7[2],xmm1[2],xmm7[3],xmm1[3] +; SSE2-NEXT: psrad $16, %xmm7 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm8 = xmm8[4],xmm2[4],xmm8[5],xmm2[5],xmm8[6],xmm2[6],xmm8[7],xmm2[7] +; SSE2-NEXT: psrad $16, %xmm8 +; SSE2-NEXT: paddd %xmm4, %xmm8 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: paddd %xmm5, %xmm0 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm2 = xmm2[4],xmm3[4],xmm2[5],xmm3[5],xmm2[6],xmm3[6],xmm2[7],xmm3[7] +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: paddd %xmm6, %xmm2 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1],xmm1[2],xmm3[2],xmm1[3],xmm3[3] +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: paddd %xmm7, %xmm1 +; SSE2-NEXT: pslld $15, %xmm8 +; SSE2-NEXT: psrad $16, %xmm8 +; SSE2-NEXT: pslld $15, %xmm0 +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: packssdw %xmm8, %xmm0 +; SSE2-NEXT: pslld $15, %xmm2 +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: pslld $15, %xmm1 +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: packssdw %xmm2, %xmm1 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v16i16: +; SSE4: # %bb.0: +; SSE4-NEXT: pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm4, %xmm5 +; SSE4-NEXT: pmovsxwd %xmm1, %xmm6 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm1, %xmm7 +; SSE4-NEXT: pmovsxwd %xmm0, %xmm8 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm4 +; SSE4-NEXT: paddd %xmm5, %xmm4 +; SSE4-NEXT: pmovsxwd %xmm3, %xmm1 +; SSE4-NEXT: paddd %xmm6, %xmm1 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm3 +; SSE4-NEXT: paddd %xmm7, %xmm3 +; SSE4-NEXT: pmovsxwd %xmm2, %xmm0 +; SSE4-NEXT: paddd %xmm8, %xmm0 +; SSE4-NEXT: psrld $1, %xmm4 +; SSE4-NEXT: psrld $1, %xmm1 +; SSE4-NEXT: psrld $1, %xmm3 +; SSE4-NEXT: psrld $1, %xmm0 +; SSE4-NEXT: pxor %xmm2, %xmm2 +; SSE4-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3],xmm0[4],xmm2[5],xmm0[6],xmm2[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0],xmm2[1],xmm3[2],xmm2[3],xmm3[4],xmm2[5],xmm3[6],xmm2[7] +; SSE4-NEXT: packusdw %xmm3, %xmm0 +; SSE4-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3],xmm1[4],xmm2[5],xmm1[6],xmm2[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm4 = xmm4[0],xmm2[1],xmm4[2],xmm2[3],xmm4[4],xmm2[5],xmm4[6],xmm2[7] +; SSE4-NEXT: packusdw %xmm4, %xmm1 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v16i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vpshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxwd %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm4 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm4, %xmm4 +; AVX1-NEXT: vpmovsxwd %xmm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm5 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm5, %xmm5 +; AVX1-NEXT: vpaddd %xmm5, %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxwd %xmm1, %xmm5 +; AVX1-NEXT: vpaddd %xmm5, %xmm3, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpshufd {{.*#+}} xmm5 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm5, %xmm5 +; AVX1-NEXT: vpaddd %xmm5, %xmm4, %xmm4 +; AVX1-NEXT: vpmovsxwd %xmm1, %xmm1 +; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm2, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm3, %xmm2 +; AVX1-NEXT: vpsrld $1, %xmm4, %xmm3 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vpxor %xmm4, %xmm4, %xmm4 +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm4[1],xmm0[2],xmm4[3],xmm0[4],xmm4[5],xmm0[6],xmm4[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm3 = xmm3[0],xmm4[1],xmm3[2],xmm4[3],xmm3[4],xmm4[5],xmm3[6],xmm4[7] +; AVX1-NEXT: vpackusdw %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm2[0],xmm4[1],xmm2[2],xmm4[3],xmm2[4],xmm4[5],xmm2[6],xmm4[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm4[1],xmm1[2],xmm4[3],xmm1[4],xmm4[5],xmm1[6],xmm4[7] +; AVX1-NEXT: vpackusdw %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v16i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxwd %xmm0, %ymm2 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vpmovsxwd %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxwd %xmm1, %ymm3 +; AVX2-NEXT: vpaddd %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX2-NEXT: vpmovsxwd %xmm1, %ymm1 +; AVX2-NEXT: vpaddd %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm2, %ymm1 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpxor %xmm2, %xmm2, %xmm2 +; AVX2-NEXT: vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1],ymm0[2],ymm2[3],ymm0[4],ymm2[5],ymm0[6],ymm2[7],ymm0[8],ymm2[9],ymm0[10],ymm2[11],ymm0[12],ymm2[13],ymm0[14],ymm2[15] +; AVX2-NEXT: vpblendw {{.*#+}} ymm1 = ymm1[0],ymm2[1],ymm1[2],ymm2[3],ymm1[4],ymm2[5],ymm1[6],ymm2[7],ymm1[8],ymm2[9],ymm1[10],ymm2[11],ymm1[12],ymm2[13],ymm1[14],ymm2[15] +; AVX2-NEXT: vpackusdw %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v16i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxwd %ymm0, %zmm0 +; AVX512-NEXT: vpmovsxwd %ymm1, %zmm1 +; AVX512-NEXT: vpaddd %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrld $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovdw %zmm0, %ymm0 +; AVX512-NEXT: retq + %x0 = sext <16 x i16> %a0 to <16 x i32> + %x1 = sext <16 x i16> %a1 to <16 x i32> + %sum = add <16 x i32> %x0, %x1 + %shift = ashr <16 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <16 x i32> %shift to <16 x i16> + ret <16 x i16> %res +} + +define <8 x i32> @test_fixed_v8i32(<8 x i32> %a0, <8 x i32> %a1) { +; SSE-LABEL: test_fixed_v8i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: pand %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: pand %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm0 +; SSE-NEXT: pxor %xmm3, %xmm1 +; SSE-NEXT: psrad $1, %xmm1 +; SSE-NEXT: paddd %xmm4, %xmm1 +; SSE-NEXT: psrad $1, %xmm0 +; SSE-NEXT: paddd %xmm5, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v8i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpaddd %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpaddd %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v8i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsrad $1, %ymm0, %ymm0 +; AVX2-NEXT: vpaddd %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v8i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: vpsrad $1, %ymm0, %ymm0 +; AVX512-NEXT: vpaddd %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %and = and <8 x i32> %a0, %a1 + %xor = xor <8 x i32> %a1, %a0 + %shift = ashr <8 x i32> %xor, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = add <8 x i32> %and, %shift + ret <8 x i32> %res +} + +define <8 x i32> @test_ext_v8i32(<8 x i32> %a0, <8 x i32> %a1) { +; SSE2-LABEL: test_ext_v8i32: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm4, %xmm4 +; SSE2-NEXT: pxor %xmm5, %xmm5 +; SSE2-NEXT: pcmpgtd %xmm1, %xmm5 +; SSE2-NEXT: pshufd {{.*#+}} xmm6 = xmm1[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm5[0],xmm1[1],xmm5[1] +; SSE2-NEXT: pxor %xmm5, %xmm5 +; SSE2-NEXT: pcmpgtd %xmm6, %xmm5 +; SSE2-NEXT: punpckldq {{.*#+}} xmm6 = xmm6[0],xmm5[0],xmm6[1],xmm5[1] +; SSE2-NEXT: pxor %xmm5, %xmm5 +; SSE2-NEXT: pcmpgtd %xmm0, %xmm5 +; SSE2-NEXT: pshufd {{.*#+}} xmm7 = xmm0[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm5[0],xmm0[1],xmm5[1] +; SSE2-NEXT: pxor %xmm5, %xmm5 +; SSE2-NEXT: pcmpgtd %xmm7, %xmm5 +; SSE2-NEXT: punpckldq {{.*#+}} xmm7 = xmm7[0],xmm5[0],xmm7[1],xmm5[1] +; SSE2-NEXT: pxor %xmm5, %xmm5 +; SSE2-NEXT: pcmpgtd %xmm3, %xmm5 +; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm3[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm5[0],xmm3[1],xmm5[1] +; SSE2-NEXT: paddq %xmm3, %xmm1 +; SSE2-NEXT: pxor %xmm3, %xmm3 +; SSE2-NEXT: pcmpgtd %xmm8, %xmm3 +; SSE2-NEXT: punpckldq {{.*#+}} xmm8 = xmm8[0],xmm3[0],xmm8[1],xmm3[1] +; SSE2-NEXT: paddq %xmm6, %xmm8 +; SSE2-NEXT: pxor %xmm3, %xmm3 +; SSE2-NEXT: pcmpgtd %xmm2, %xmm3 +; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm2[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1] +; SSE2-NEXT: paddq %xmm2, %xmm0 +; SSE2-NEXT: pcmpgtd %xmm5, %xmm4 +; SSE2-NEXT: punpckldq {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1] +; SSE2-NEXT: paddq %xmm7, %xmm5 +; SSE2-NEXT: psrlq $1, %xmm1 +; SSE2-NEXT: psrlq $1, %xmm8 +; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm8[0,2] +; SSE2-NEXT: psrlq $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm5 +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm5[0,2] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v8i32: +; SSE4: # %bb.0: +; SSE4-NEXT: pmovsxdq %xmm1, %xmm4 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm1, %xmm5 +; SSE4-NEXT: pmovsxdq %xmm0, %xmm6 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm7 +; SSE4-NEXT: pmovsxdq %xmm3, %xmm1 +; SSE4-NEXT: paddq %xmm4, %xmm1 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm3 +; SSE4-NEXT: paddq %xmm5, %xmm3 +; SSE4-NEXT: pmovsxdq %xmm2, %xmm0 +; SSE4-NEXT: paddq %xmm6, %xmm0 +; SSE4-NEXT: pshufd {{.*#+}} xmm2 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm2, %xmm2 +; SSE4-NEXT: paddq %xmm7, %xmm2 +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: psrlq $1, %xmm3 +; SSE4-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm3[0,2] +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2] +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v8i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 +; AVX1-NEXT: vpshufd {{.*#+}} xmm3 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm3, %xmm3 +; AVX1-NEXT: vpshufd {{.*#+}} xmm4 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm4, %xmm4 +; AVX1-NEXT: vpmovsxdq %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxdq %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm5 +; AVX1-NEXT: vpshufd {{.*#+}} xmm6 = xmm5[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm6, %xmm6 +; AVX1-NEXT: vpaddq %xmm6, %xmm3, %xmm3 +; AVX1-NEXT: vpshufd {{.*#+}} xmm6 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm6, %xmm6 +; AVX1-NEXT: vpaddq %xmm6, %xmm4, %xmm4 +; AVX1-NEXT: vpmovsxdq %xmm5, %xmm5 +; AVX1-NEXT: vpaddq %xmm5, %xmm2, %xmm2 +; AVX1-NEXT: vpmovsxdq %xmm1, %xmm1 +; AVX1-NEXT: vpaddq %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm3, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm4, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm2, %xmm2 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm3, %ymm1 +; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm1[0,2],ymm0[4,6],ymm1[4,6] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v8i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX2-NEXT: vpmovsxdq %xmm2, %ymm2 +; AVX2-NEXT: vpmovsxdq %xmm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm3 +; AVX2-NEXT: vpmovsxdq %xmm3, %ymm3 +; AVX2-NEXT: vpaddq %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vpmovsxdq %xmm1, %ymm1 +; AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm1 = ymm0[2,3],ymm2[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vinserti128 $1, %xmm2, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm1[0,2],ymm0[4,6],ymm1[4,6] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v8i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovsxdq %ymm0, %zmm0 +; AVX512-NEXT: vpmovsxdq %ymm1, %zmm1 +; AVX512-NEXT: vpaddq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovqd %zmm0, %ymm0 +; AVX512-NEXT: retq + %x0 = sext <8 x i32> %a0 to <8 x i64> + %x1 = sext <8 x i32> %a1 to <8 x i64> + %sum = add <8 x i64> %x0, %x1 + %shift = ashr <8 x i64> %sum, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = trunc <8 x i64> %shift to <8 x i32> + ret <8 x i32> %res +} + +define <4 x i64> @test_fixed_v4i64(<4 x i64> %a0, <4 x i64> %a1) { +; SSE2-LABEL: test_fixed_v4i64: +; SSE2: # %bb.0: +; SSE2-NEXT: movdqa %xmm1, %xmm4 +; SSE2-NEXT: pand %xmm3, %xmm4 +; SSE2-NEXT: movdqa %xmm0, %xmm5 +; SSE2-NEXT: pand %xmm2, %xmm5 +; SSE2-NEXT: pxor %xmm0, %xmm2 +; SSE2-NEXT: pxor %xmm1, %xmm3 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm3[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm3 +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm3[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] +; SSE2-NEXT: paddq %xmm4, %xmm1 +; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm2[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm3 +; SSE2-NEXT: psrlq $1, %xmm2 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1] +; SSE2-NEXT: paddq %xmm5, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_fixed_v4i64: +; SSE4: # %bb.0: +; SSE4-NEXT: movdqa %xmm1, %xmm4 +; SSE4-NEXT: pand %xmm3, %xmm4 +; SSE4-NEXT: movdqa %xmm0, %xmm5 +; SSE4-NEXT: pand %xmm2, %xmm5 +; SSE4-NEXT: pxor %xmm2, %xmm0 +; SSE4-NEXT: pxor %xmm3, %xmm1 +; SSE4-NEXT: movdqa %xmm1, %xmm2 +; SSE4-NEXT: psrad $1, %xmm2 +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7] +; SSE4-NEXT: paddq %xmm4, %xmm1 +; SSE4-NEXT: movdqa %xmm0, %xmm2 +; SSE4-NEXT: psrad $1, %xmm2 +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7] +; SSE4-NEXT: paddq %xmm5, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_fixed_v4i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm3 +; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm3[0,1],xmm1[2,3],xmm3[4,5],xmm1[6,7] +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm3[2,3],xmm0[4,5],xmm3[6,7] +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpaddq %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpaddq %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v4i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsrad $1, %ymm0, %ymm1 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[3],ymm0[4],ymm1[5],ymm0[6],ymm1[7] +; AVX2-NEXT: vpaddq %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v4i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: vpsraq $1, %ymm0, %ymm0 +; AVX512-NEXT: vpaddq %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %and = and <4 x i64> %a0, %a1 + %xor = xor <4 x i64> %a1, %a0 + %shift = ashr <4 x i64> %xor, <i64 1, i64 1, i64 1, i64 1> + %res = add <4 x i64> %and, %shift + ret <4 x i64> %res +} + +define <4 x i64> @test_ext_v4i64(<4 x i64> %a0, <4 x i64> %a1) { +; SSE2-LABEL: test_ext_v4i64: +; SSE2: # %bb.0: +; SSE2-NEXT: pushq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: pushq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: pushq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: pushq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: pushq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: pushq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 56 +; SSE2-NEXT: .cfi_offset %rbx, -56 +; SSE2-NEXT: .cfi_offset %r12, -48 +; SSE2-NEXT: .cfi_offset %r13, -40 +; SSE2-NEXT: .cfi_offset %r14, -32 +; SSE2-NEXT: .cfi_offset %r15, -24 +; SSE2-NEXT: .cfi_offset %rbp, -16 +; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm4, %rdx +; SSE2-NEXT: movq %rdx, %r14 +; SSE2-NEXT: sarq $63, %r14 +; SSE2-NEXT: movq %xmm1, %rcx +; SSE2-NEXT: movq %rcx, %r10 +; SSE2-NEXT: sarq $63, %r10 +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3] +; SSE2-NEXT: movq %xmm1, %rsi +; SSE2-NEXT: movq %rsi, %r11 +; SSE2-NEXT: sarq $63, %r11 +; SSE2-NEXT: movq %xmm0, %r8 +; SSE2-NEXT: movq %r8, %rbx +; SSE2-NEXT: sarq $63, %rbx +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rdi +; SSE2-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %rdi +; SSE2-NEXT: movq %xmm3, %r15 +; SSE2-NEXT: movq %r15, %r9 +; SSE2-NEXT: sarq $63, %r9 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r12 +; SSE2-NEXT: movq %r12, %r13 +; SSE2-NEXT: sarq $63, %r13 +; SSE2-NEXT: movq %xmm2, %rax +; SSE2-NEXT: movq %rax, %rbp +; SSE2-NEXT: sarq $63, %rbp +; SSE2-NEXT: addq %rax, %r8 +; SSE2-NEXT: adcq %rbx, %rbp +; SSE2-NEXT: addq %r12, %rsi +; SSE2-NEXT: adcq %r11, %r13 +; SSE2-NEXT: addq %r15, %rcx +; SSE2-NEXT: adcq %r10, %r9 +; SSE2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Folded Reload +; SSE2-NEXT: adcq %r14, %rdi +; SSE2-NEXT: shldq $63, %rdx, %rdi +; SSE2-NEXT: shldq $63, %rcx, %r9 +; SSE2-NEXT: shldq $63, %rsi, %r13 +; SSE2-NEXT: shldq $63, %r8, %rbp +; SSE2-NEXT: movq %rbp, %xmm0 +; SSE2-NEXT: movq %r13, %xmm2 +; SSE2-NEXT: movq %r9, %xmm1 +; SSE2-NEXT: movq %rdi, %xmm3 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0] +; SSE2-NEXT: popq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: popq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: popq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: popq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: popq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: popq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 8 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v4i64: +; SSE4: # %bb.0: +; SSE4-NEXT: pushq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: pushq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: pushq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: pushq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: pushq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: pushq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 56 +; SSE4-NEXT: .cfi_offset %rbx, -56 +; SSE4-NEXT: .cfi_offset %r12, -48 +; SSE4-NEXT: .cfi_offset %r13, -40 +; SSE4-NEXT: .cfi_offset %r14, -32 +; SSE4-NEXT: .cfi_offset %r15, -24 +; SSE4-NEXT: .cfi_offset %rbp, -16 +; SSE4-NEXT: movq %xmm1, %rdi +; SSE4-NEXT: movq %rdi, %r14 +; SSE4-NEXT: sarq $63, %r14 +; SSE4-NEXT: pextrq $1, %xmm1, %rcx +; SSE4-NEXT: movq %rcx, %r10 +; SSE4-NEXT: sarq $63, %r10 +; SSE4-NEXT: movq %xmm0, %rsi +; SSE4-NEXT: movq %rsi, %r11 +; SSE4-NEXT: sarq $63, %r11 +; SSE4-NEXT: pextrq $1, %xmm0, %r8 +; SSE4-NEXT: movq %r8, %rbx +; SSE4-NEXT: sarq $63, %rbx +; SSE4-NEXT: movq %xmm3, %rdx +; SSE4-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %rdx +; SSE4-NEXT: pextrq $1, %xmm3, %r15 +; SSE4-NEXT: movq %r15, %r9 +; SSE4-NEXT: sarq $63, %r9 +; SSE4-NEXT: movq %xmm2, %r12 +; SSE4-NEXT: movq %r12, %r13 +; SSE4-NEXT: sarq $63, %r13 +; SSE4-NEXT: pextrq $1, %xmm2, %rax +; SSE4-NEXT: movq %rax, %rbp +; SSE4-NEXT: sarq $63, %rbp +; SSE4-NEXT: addq %rax, %r8 +; SSE4-NEXT: adcq %rbx, %rbp +; SSE4-NEXT: addq %r12, %rsi +; SSE4-NEXT: adcq %r11, %r13 +; SSE4-NEXT: addq %r15, %rcx +; SSE4-NEXT: adcq %r10, %r9 +; SSE4-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rdi # 8-byte Folded Reload +; SSE4-NEXT: adcq %r14, %rdx +; SSE4-NEXT: shldq $63, %rdi, %rdx +; SSE4-NEXT: shldq $63, %rcx, %r9 +; SSE4-NEXT: shldq $63, %rsi, %r13 +; SSE4-NEXT: shldq $63, %r8, %rbp +; SSE4-NEXT: movq %rbp, %xmm2 +; SSE4-NEXT: movq %r13, %xmm0 +; SSE4-NEXT: movq %r9, %xmm3 +; SSE4-NEXT: movq %rdx, %xmm1 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0] +; SSE4-NEXT: popq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: popq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: popq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: popq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: popq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: popq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 8 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v4i64: +; AVX1: # %bb.0: +; AVX1-NEXT: pushq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: pushq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: pushq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: pushq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: pushq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: pushq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 56 +; AVX1-NEXT: .cfi_offset %rbx, -56 +; AVX1-NEXT: .cfi_offset %r12, -48 +; AVX1-NEXT: .cfi_offset %r13, -40 +; AVX1-NEXT: .cfi_offset %r14, -32 +; AVX1-NEXT: .cfi_offset %r15, -24 +; AVX1-NEXT: .cfi_offset %rbp, -16 +; AVX1-NEXT: vmovq %xmm0, %rdx +; AVX1-NEXT: movq %rdx, %r14 +; AVX1-NEXT: sarq $63, %r14 +; AVX1-NEXT: vpextrq $1, %xmm0, %rcx +; AVX1-NEXT: movq %rcx, %r10 +; AVX1-NEXT: sarq $63, %r10 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vmovq %xmm0, %rsi +; AVX1-NEXT: movq %rsi, %r11 +; AVX1-NEXT: sarq $63, %r11 +; AVX1-NEXT: vpextrq $1, %xmm0, %rdi +; AVX1-NEXT: movq %rdi, %rbx +; AVX1-NEXT: sarq $63, %rbx +; AVX1-NEXT: vmovq %xmm1, %r8 +; AVX1-NEXT: movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %r8 +; AVX1-NEXT: vpextrq $1, %xmm1, %r15 +; AVX1-NEXT: movq %r15, %r9 +; AVX1-NEXT: sarq $63, %r9 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm0 +; AVX1-NEXT: vmovq %xmm0, %r12 +; AVX1-NEXT: movq %r12, %r13 +; AVX1-NEXT: sarq $63, %r13 +; AVX1-NEXT: vpextrq $1, %xmm0, %rax +; AVX1-NEXT: movq %rax, %rbp +; AVX1-NEXT: sarq $63, %rbp +; AVX1-NEXT: addq %rax, %rdi +; AVX1-NEXT: adcq %rbx, %rbp +; AVX1-NEXT: addq %r12, %rsi +; AVX1-NEXT: adcq %r11, %r13 +; AVX1-NEXT: addq %r15, %rcx +; AVX1-NEXT: adcq %r10, %r9 +; AVX1-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Folded Reload +; AVX1-NEXT: adcq %r14, %r8 +; AVX1-NEXT: shldq $63, %rdx, %r8 +; AVX1-NEXT: shldq $63, %rcx, %r9 +; AVX1-NEXT: shldq $63, %rsi, %r13 +; AVX1-NEXT: shldq $63, %rdi, %rbp +; AVX1-NEXT: vmovq %rbp, %xmm0 +; AVX1-NEXT: vmovq %r13, %xmm1 +; AVX1-NEXT: vmovq %r9, %xmm2 +; AVX1-NEXT: vmovq %r8, %xmm3 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: popq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: popq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: popq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: popq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: popq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: popq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 8 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v4i64: +; AVX2: # %bb.0: +; AVX2-NEXT: pushq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: pushq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: pushq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: pushq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: pushq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: pushq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 56 +; AVX2-NEXT: .cfi_offset %rbx, -56 +; AVX2-NEXT: .cfi_offset %r12, -48 +; AVX2-NEXT: .cfi_offset %r13, -40 +; AVX2-NEXT: .cfi_offset %r14, -32 +; AVX2-NEXT: .cfi_offset %r15, -24 +; AVX2-NEXT: .cfi_offset %rbp, -16 +; AVX2-NEXT: vmovq %xmm0, %rdx +; AVX2-NEXT: movq %rdx, %r14 +; AVX2-NEXT: sarq $63, %r14 +; AVX2-NEXT: vpextrq $1, %xmm0, %rcx +; AVX2-NEXT: movq %rcx, %r10 +; AVX2-NEXT: sarq $63, %r10 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vmovq %xmm0, %rsi +; AVX2-NEXT: movq %rsi, %r11 +; AVX2-NEXT: sarq $63, %r11 +; AVX2-NEXT: vpextrq $1, %xmm0, %rdi +; AVX2-NEXT: movq %rdi, %rbx +; AVX2-NEXT: sarq $63, %rbx +; AVX2-NEXT: vmovq %xmm1, %r8 +; AVX2-NEXT: movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %r8 +; AVX2-NEXT: vpextrq $1, %xmm1, %r15 +; AVX2-NEXT: movq %r15, %r9 +; AVX2-NEXT: sarq $63, %r9 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm0 +; AVX2-NEXT: vmovq %xmm0, %r12 +; AVX2-NEXT: movq %r12, %r13 +; AVX2-NEXT: sarq $63, %r13 +; AVX2-NEXT: vpextrq $1, %xmm0, %rax +; AVX2-NEXT: movq %rax, %rbp +; AVX2-NEXT: sarq $63, %rbp +; AVX2-NEXT: addq %rax, %rdi +; AVX2-NEXT: adcq %rbx, %rbp +; AVX2-NEXT: addq %r12, %rsi +; AVX2-NEXT: adcq %r11, %r13 +; AVX2-NEXT: addq %r15, %rcx +; AVX2-NEXT: adcq %r10, %r9 +; AVX2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Folded Reload +; AVX2-NEXT: adcq %r14, %r8 +; AVX2-NEXT: shldq $63, %rdx, %r8 +; AVX2-NEXT: shldq $63, %rcx, %r9 +; AVX2-NEXT: shldq $63, %rsi, %r13 +; AVX2-NEXT: shldq $63, %rdi, %rbp +; AVX2-NEXT: vmovq %rbp, %xmm0 +; AVX2-NEXT: vmovq %r13, %xmm1 +; AVX2-NEXT: vmovq %r9, %xmm2 +; AVX2-NEXT: vmovq %r8, %xmm3 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX2-NEXT: popq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: popq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: popq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: popq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: popq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: popq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 8 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v4i64: +; AVX512: # %bb.0: +; AVX512-NEXT: pushq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: pushq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: pushq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: pushq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: pushq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: pushq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 56 +; AVX512-NEXT: .cfi_offset %rbx, -56 +; AVX512-NEXT: .cfi_offset %r12, -48 +; AVX512-NEXT: .cfi_offset %r13, -40 +; AVX512-NEXT: .cfi_offset %r14, -32 +; AVX512-NEXT: .cfi_offset %r15, -24 +; AVX512-NEXT: .cfi_offset %rbp, -16 +; AVX512-NEXT: vmovq %xmm0, %rdx +; AVX512-NEXT: movq %rdx, %r14 +; AVX512-NEXT: sarq $63, %r14 +; AVX512-NEXT: vpextrq $1, %xmm0, %rcx +; AVX512-NEXT: movq %rcx, %r10 +; AVX512-NEXT: sarq $63, %r10 +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX512-NEXT: vmovq %xmm0, %rsi +; AVX512-NEXT: movq %rsi, %r11 +; AVX512-NEXT: sarq $63, %r11 +; AVX512-NEXT: vpextrq $1, %xmm0, %rdi +; AVX512-NEXT: movq %rdi, %rbx +; AVX512-NEXT: sarq $63, %rbx +; AVX512-NEXT: vmovq %xmm1, %r8 +; AVX512-NEXT: movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r8 +; AVX512-NEXT: vpextrq $1, %xmm1, %r15 +; AVX512-NEXT: movq %r15, %r9 +; AVX512-NEXT: sarq $63, %r9 +; AVX512-NEXT: vextracti128 $1, %ymm1, %xmm0 +; AVX512-NEXT: vmovq %xmm0, %r12 +; AVX512-NEXT: movq %r12, %r13 +; AVX512-NEXT: sarq $63, %r13 +; AVX512-NEXT: vpextrq $1, %xmm0, %rax +; AVX512-NEXT: movq %rax, %rbp +; AVX512-NEXT: sarq $63, %rbp +; AVX512-NEXT: addq %rax, %rdi +; AVX512-NEXT: adcq %rbx, %rbp +; AVX512-NEXT: addq %r12, %rsi +; AVX512-NEXT: adcq %r11, %r13 +; AVX512-NEXT: addq %r15, %rcx +; AVX512-NEXT: adcq %r10, %r9 +; AVX512-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Folded Reload +; AVX512-NEXT: adcq %r14, %r8 +; AVX512-NEXT: shldq $63, %rdx, %r8 +; AVX512-NEXT: shldq $63, %rcx, %r9 +; AVX512-NEXT: shldq $63, %rsi, %r13 +; AVX512-NEXT: shldq $63, %rdi, %rbp +; AVX512-NEXT: vmovq %rbp, %xmm0 +; AVX512-NEXT: vmovq %r13, %xmm1 +; AVX512-NEXT: vmovq %r9, %xmm2 +; AVX512-NEXT: vmovq %r8, %xmm3 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX512-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX512-NEXT: popq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: popq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: popq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: popq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: popq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: popq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 8 +; AVX512-NEXT: retq + %x0 = sext <4 x i64> %a0 to <4 x i128> + %x1 = sext <4 x i64> %a1 to <4 x i128> + %sum = add <4 x i128> %x0, %x1 + %shift = ashr <4 x i128> %sum, <i128 1, i128 1, i128 1, i128 1> + %res = trunc <4 x i128> %shift to <4 x i64> + ret <4 x i64> %res +} + +; +; 512-bit vectors +; + +define <64 x i8> @test_fixed_v64i8(<64 x i8> %a0, <64 x i8> %a1) { +; SSE-LABEL: test_fixed_v64i8: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm10 +; SSE-NEXT: pand %xmm7, %xmm10 +; SSE-NEXT: movdqa %xmm2, %xmm11 +; SSE-NEXT: pand %xmm6, %xmm11 +; SSE-NEXT: movdqa %xmm1, %xmm9 +; SSE-NEXT: pand %xmm5, %xmm9 +; SSE-NEXT: movdqa %xmm0, %xmm8 +; SSE-NEXT: pand %xmm4, %xmm8 +; SSE-NEXT: pxor %xmm4, %xmm0 +; SSE-NEXT: pxor %xmm5, %xmm1 +; SSE-NEXT: pxor %xmm6, %xmm2 +; SSE-NEXT: pxor %xmm7, %xmm3 +; SSE-NEXT: psrlw $1, %xmm3 +; SSE-NEXT: movdqa {{.*#+}} xmm5 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; SSE-NEXT: pand %xmm5, %xmm3 +; SSE-NEXT: movdqa {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; SSE-NEXT: pxor %xmm4, %xmm3 +; SSE-NEXT: paddb %xmm10, %xmm3 +; SSE-NEXT: psrlw $1, %xmm2 +; SSE-NEXT: pand %xmm5, %xmm2 +; SSE-NEXT: pxor %xmm4, %xmm2 +; SSE-NEXT: paddb %xmm11, %xmm2 +; SSE-NEXT: psrlw $1, %xmm1 +; SSE-NEXT: pand %xmm5, %xmm1 +; SSE-NEXT: pxor %xmm4, %xmm1 +; SSE-NEXT: paddb %xmm9, %xmm1 +; SSE-NEXT: psrlw $1, %xmm0 +; SSE-NEXT: pand %xmm5, %xmm0 +; SSE-NEXT: pxor %xmm4, %xmm0 +; SSE-NEXT: paddb %xmm8, %xmm0 +; SSE-NEXT: psubb %xmm4, %xmm0 +; SSE-NEXT: psubb %xmm4, %xmm1 +; SSE-NEXT: psubb %xmm4, %xmm2 +; SSE-NEXT: psubb %xmm4, %xmm3 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v64i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm2, %ymm0, %ymm0 +; AVX1-NEXT: vxorps %ymm3, %ymm1, %ymm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm2 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; AVX1-NEXT: vpand %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm6 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX1-NEXT: vpxor %xmm6, %xmm2, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpand %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpxor %xmm6, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm7 +; AVX1-NEXT: vpand %xmm3, %xmm7, %xmm7 +; AVX1-NEXT: vpxor %xmm6, %xmm7, %xmm7 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpxor %xmm6, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm3 +; AVX1-NEXT: vpaddb %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpsubb %xmm6, %xmm0, %xmm0 +; AVX1-NEXT: vpaddb %xmm5, %xmm7, %xmm3 +; AVX1-NEXT: vpsubb %xmm6, %xmm3, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpaddb %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpsubb %xmm6, %xmm1, %xmm1 +; AVX1-NEXT: vpaddb %xmm4, %xmm2, %xmm2 +; AVX1-NEXT: vpsubb %xmm6, %xmm2, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v64i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpxor %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm1, %ymm1 +; AVX2-NEXT: vpbroadcastb {{.*#+}} ymm2 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; AVX2-NEXT: vpand %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vpbroadcastb {{.*#+}} ymm3 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX2-NEXT: vpxor %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpaddb %ymm4, %ymm1, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpxor %ymm3, %ymm0, %ymm0 +; AVX2-NEXT: vpaddb %ymm5, %ymm0, %ymm0 +; AVX2-NEXT: vpsubb %ymm3, %ymm0, %ymm0 +; AVX2-NEXT: vpsubb %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v64i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpandq %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxorq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpbroadcastb {{.*#+}} zmm1 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] +; AVX512-NEXT: vpternlogd $108, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to16}, %zmm1, %zmm0 +; AVX512-NEXT: vpaddb %zmm2, %zmm0, %zmm0 +; AVX512-NEXT: vpsubb %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %and = and <64 x i8> %a0, %a1 + %xor = xor <64 x i8> %a0, %a1 + %shift = ashr <64 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = add <64 x i8> %and, %shift + ret <64 x i8> %res +} + +define <64 x i8> @test_ext_v64i8(<64 x i8> %a0, <64 x i8> %a1) { +; SSE2-LABEL: test_ext_v64i8: +; SSE2: # %bb.0: +; SSE2-NEXT: punpcklbw {{.*#+}} xmm13 = xmm13[0],xmm3[0],xmm13[1],xmm3[1],xmm13[2],xmm3[2],xmm13[3],xmm3[3],xmm13[4],xmm3[4],xmm13[5],xmm3[5],xmm13[6],xmm3[6],xmm13[7],xmm3[7] +; SSE2-NEXT: psraw $8, %xmm13 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm14 = xmm14[8],xmm3[8],xmm14[9],xmm3[9],xmm14[10],xmm3[10],xmm14[11],xmm3[11],xmm14[12],xmm3[12],xmm14[13],xmm3[13],xmm14[14],xmm3[14],xmm14[15],xmm3[15] +; SSE2-NEXT: psraw $8, %xmm14 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm15 = xmm15[0],xmm2[0],xmm15[1],xmm2[1],xmm15[2],xmm2[2],xmm15[3],xmm2[3],xmm15[4],xmm2[4],xmm15[5],xmm2[5],xmm15[6],xmm2[6],xmm15[7],xmm2[7] +; SSE2-NEXT: psraw $8, %xmm15 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm12 = xmm12[8],xmm2[8],xmm12[9],xmm2[9],xmm12[10],xmm2[10],xmm12[11],xmm2[11],xmm12[12],xmm2[12],xmm12[13],xmm2[13],xmm12[14],xmm2[14],xmm12[15],xmm2[15] +; SSE2-NEXT: psraw $8, %xmm12 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm11 = xmm11[0],xmm1[0],xmm11[1],xmm1[1],xmm11[2],xmm1[2],xmm11[3],xmm1[3],xmm11[4],xmm1[4],xmm11[5],xmm1[5],xmm11[6],xmm1[6],xmm11[7],xmm1[7] +; SSE2-NEXT: psraw $8, %xmm11 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm10 = xmm10[8],xmm1[8],xmm10[9],xmm1[9],xmm10[10],xmm1[10],xmm10[11],xmm1[11],xmm10[12],xmm1[12],xmm10[13],xmm1[13],xmm10[14],xmm1[14],xmm10[15],xmm1[15] +; SSE2-NEXT: psraw $8, %xmm10 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm9 = xmm9[0],xmm0[0],xmm9[1],xmm0[1],xmm9[2],xmm0[2],xmm9[3],xmm0[3],xmm9[4],xmm0[4],xmm9[5],xmm0[5],xmm9[6],xmm0[6],xmm9[7],xmm0[7] +; SSE2-NEXT: psraw $8, %xmm9 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm8 = xmm8[8],xmm0[8],xmm8[9],xmm0[9],xmm8[10],xmm0[10],xmm8[11],xmm0[11],xmm8[12],xmm0[12],xmm8[13],xmm0[13],xmm8[14],xmm0[14],xmm8[15],xmm0[15] +; SSE2-NEXT: psraw $8, %xmm8 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm7[0],xmm3[1],xmm7[1],xmm3[2],xmm7[2],xmm3[3],xmm7[3],xmm3[4],xmm7[4],xmm3[5],xmm7[5],xmm3[6],xmm7[6],xmm3[7],xmm7[7] +; SSE2-NEXT: psraw $8, %xmm3 +; SSE2-NEXT: paddw %xmm13, %xmm3 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm7 = xmm7[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15] +; SSE2-NEXT: psraw $8, %xmm7 +; SSE2-NEXT: paddw %xmm14, %xmm7 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm6[0],xmm2[1],xmm6[1],xmm2[2],xmm6[2],xmm2[3],xmm6[3],xmm2[4],xmm6[4],xmm2[5],xmm6[5],xmm2[6],xmm6[6],xmm2[7],xmm6[7] +; SSE2-NEXT: psraw $8, %xmm2 +; SSE2-NEXT: paddw %xmm15, %xmm2 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm6 = xmm6[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15] +; SSE2-NEXT: psraw $8, %xmm6 +; SSE2-NEXT: paddw %xmm12, %xmm6 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm5[0],xmm1[1],xmm5[1],xmm1[2],xmm5[2],xmm1[3],xmm5[3],xmm1[4],xmm5[4],xmm1[5],xmm5[5],xmm1[6],xmm5[6],xmm1[7],xmm5[7] +; SSE2-NEXT: psraw $8, %xmm1 +; SSE2-NEXT: paddw %xmm11, %xmm1 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm5 = xmm5[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15] +; SSE2-NEXT: psraw $8, %xmm5 +; SSE2-NEXT: paddw %xmm10, %xmm5 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1],xmm0[2],xmm4[2],xmm0[3],xmm4[3],xmm0[4],xmm4[4],xmm0[5],xmm4[5],xmm0[6],xmm4[6],xmm0[7],xmm4[7] +; SSE2-NEXT: psraw $8, %xmm0 +; SSE2-NEXT: paddw %xmm9, %xmm0 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15] +; SSE2-NEXT: psraw $8, %xmm4 +; SSE2-NEXT: paddw %xmm8, %xmm4 +; SSE2-NEXT: psrlw $1, %xmm3 +; SSE2-NEXT: psrlw $1, %xmm7 +; SSE2-NEXT: psrlw $1, %xmm2 +; SSE2-NEXT: psrlw $1, %xmm6 +; SSE2-NEXT: psrlw $1, %xmm1 +; SSE2-NEXT: psrlw $1, %xmm5 +; SSE2-NEXT: psrlw $1, %xmm0 +; SSE2-NEXT: psrlw $1, %xmm4 +; SSE2-NEXT: movdqa {{.*#+}} xmm8 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0] +; SSE2-NEXT: pand %xmm8, %xmm4 +; SSE2-NEXT: pand %xmm8, %xmm0 +; SSE2-NEXT: packuswb %xmm4, %xmm0 +; SSE2-NEXT: pand %xmm8, %xmm5 +; SSE2-NEXT: pand %xmm8, %xmm1 +; SSE2-NEXT: packuswb %xmm5, %xmm1 +; SSE2-NEXT: pand %xmm8, %xmm6 +; SSE2-NEXT: pand %xmm8, %xmm2 +; SSE2-NEXT: packuswb %xmm6, %xmm2 +; SSE2-NEXT: pand %xmm8, %xmm7 +; SSE2-NEXT: pand %xmm8, %xmm3 +; SSE2-NEXT: packuswb %xmm7, %xmm3 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v64i8: +; SSE4: # %bb.0: +; SSE4-NEXT: pshufd {{.*#+}} xmm8 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm8, %xmm9 +; SSE4-NEXT: pmovsxbw %xmm3, %xmm10 +; SSE4-NEXT: pshufd {{.*#+}} xmm3 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm3, %xmm11 +; SSE4-NEXT: pmovsxbw %xmm2, %xmm12 +; SSE4-NEXT: pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm2, %xmm13 +; SSE4-NEXT: pmovsxbw %xmm1, %xmm14 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm1, %xmm15 +; SSE4-NEXT: pmovsxbw %xmm0, %xmm0 +; SSE4-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm7[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm8 +; SSE4-NEXT: paddw %xmm9, %xmm8 +; SSE4-NEXT: pmovsxbw %xmm7, %xmm3 +; SSE4-NEXT: paddw %xmm10, %xmm3 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm6[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm7 +; SSE4-NEXT: paddw %xmm11, %xmm7 +; SSE4-NEXT: pmovsxbw %xmm6, %xmm2 +; SSE4-NEXT: paddw %xmm12, %xmm2 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm5[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm6 +; SSE4-NEXT: paddw %xmm13, %xmm6 +; SSE4-NEXT: pmovsxbw %xmm5, %xmm1 +; SSE4-NEXT: paddw %xmm14, %xmm1 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm4[2,3,2,3] +; SSE4-NEXT: pmovsxbw %xmm0, %xmm5 +; SSE4-NEXT: paddw %xmm15, %xmm5 +; SSE4-NEXT: pmovsxbw %xmm4, %xmm0 +; SSE4-NEXT: paddw {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload +; SSE4-NEXT: psrlw $1, %xmm8 +; SSE4-NEXT: psrlw $1, %xmm3 +; SSE4-NEXT: psrlw $1, %xmm7 +; SSE4-NEXT: psrlw $1, %xmm2 +; SSE4-NEXT: psrlw $1, %xmm6 +; SSE4-NEXT: psrlw $1, %xmm1 +; SSE4-NEXT: psrlw $1, %xmm5 +; SSE4-NEXT: psrlw $1, %xmm0 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm4 = [255,255,255,255,255,255,255,255] +; SSE4-NEXT: pand %xmm4, %xmm0 +; SSE4-NEXT: pand %xmm4, %xmm5 +; SSE4-NEXT: packuswb %xmm5, %xmm0 +; SSE4-NEXT: pand %xmm4, %xmm1 +; SSE4-NEXT: pand %xmm4, %xmm6 +; SSE4-NEXT: packuswb %xmm6, %xmm1 +; SSE4-NEXT: pand %xmm4, %xmm2 +; SSE4-NEXT: pand %xmm4, %xmm7 +; SSE4-NEXT: packuswb %xmm7, %xmm2 +; SSE4-NEXT: pand %xmm4, %xmm3 +; SSE4-NEXT: pand %xmm4, %xmm8 +; SSE4-NEXT: packuswb %xmm8, %xmm3 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v64i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vpshufd {{.*#+}} xmm4 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm4, %xmm4 +; AVX1-NEXT: vpmovsxbw %xmm1, %xmm5 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpshufd {{.*#+}} xmm6 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm6, %xmm6 +; AVX1-NEXT: vpmovsxbw %xmm1, %xmm1 +; AVX1-NEXT: vpshufd {{.*#+}} xmm7 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm7, %xmm7 +; AVX1-NEXT: vpmovsxbw %xmm0, %xmm8 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm9 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm9, %xmm9 +; AVX1-NEXT: vpmovsxbw %xmm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm10 = xmm3[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm10, %xmm10 +; AVX1-NEXT: vpaddw %xmm4, %xmm10, %xmm4 +; AVX1-NEXT: vpmovsxbw %xmm3, %xmm10 +; AVX1-NEXT: vpaddw %xmm5, %xmm10, %xmm5 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm3 +; AVX1-NEXT: vpshufd {{.*#+}} xmm10 = xmm3[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm10, %xmm10 +; AVX1-NEXT: vpaddw %xmm6, %xmm10, %xmm6 +; AVX1-NEXT: vpmovsxbw %xmm3, %xmm3 +; AVX1-NEXT: vpaddw %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpshufd {{.*#+}} xmm3 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm3, %xmm3 +; AVX1-NEXT: vpaddw %xmm3, %xmm7, %xmm3 +; AVX1-NEXT: vpmovsxbw %xmm2, %xmm7 +; AVX1-NEXT: vpaddw %xmm7, %xmm8, %xmm7 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm2 +; AVX1-NEXT: vpshufd {{.*#+}} xmm8 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxbw %xmm8, %xmm8 +; AVX1-NEXT: vpaddw %xmm8, %xmm9, %xmm8 +; AVX1-NEXT: vpmovsxbw %xmm2, %xmm2 +; AVX1-NEXT: vpaddw %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm4, %xmm2 +; AVX1-NEXT: vpsrlw $1, %xmm5, %xmm4 +; AVX1-NEXT: vpsrlw $1, %xmm6, %xmm5 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm3, %xmm3 +; AVX1-NEXT: vpsrlw $1, %xmm7, %xmm6 +; AVX1-NEXT: vpsrlw $1, %xmm8, %xmm7 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm8 = [255,255,255,255,255,255,255,255] +; AVX1-NEXT: vpand %xmm0, %xmm8, %xmm0 +; AVX1-NEXT: vpand %xmm7, %xmm8, %xmm7 +; AVX1-NEXT: vpackuswb %xmm7, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm6, %xmm8, %xmm6 +; AVX1-NEXT: vpand %xmm3, %xmm8, %xmm3 +; AVX1-NEXT: vpackuswb %xmm3, %xmm6, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vpand %xmm1, %xmm8, %xmm1 +; AVX1-NEXT: vpand %xmm5, %xmm8, %xmm3 +; AVX1-NEXT: vpackuswb %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpand %xmm4, %xmm8, %xmm3 +; AVX1-NEXT: vpand %xmm2, %xmm8, %xmm2 +; AVX1-NEXT: vpackuswb %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v64i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxbw %xmm1, %ymm4 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX2-NEXT: vpmovsxbw %xmm1, %ymm1 +; AVX2-NEXT: vpmovsxbw %xmm0, %ymm5 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxbw %xmm3, %ymm6 +; AVX2-NEXT: vpaddw %ymm6, %ymm4, %ymm4 +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm3 +; AVX2-NEXT: vpmovsxbw %xmm3, %ymm3 +; AVX2-NEXT: vpaddw %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpmovsxbw %xmm2, %ymm3 +; AVX2-NEXT: vpaddw %ymm3, %ymm5, %ymm3 +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm2 +; AVX2-NEXT: vpmovsxbw %xmm2, %ymm2 +; AVX2-NEXT: vpaddw %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm4, %ymm2 +; AVX2-NEXT: vpsrlw $1, %ymm1, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm3, %ymm3 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpbroadcastw {{.*#+}} ymm4 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0] +; AVX2-NEXT: vpand %ymm4, %ymm0, %ymm0 +; AVX2-NEXT: vpand %ymm4, %ymm3, %ymm3 +; AVX2-NEXT: vpackuswb %ymm0, %ymm3, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: vpand %ymm4, %ymm1, %ymm1 +; AVX2-NEXT: vpand %ymm4, %ymm2, %ymm2 +; AVX2-NEXT: vpackuswb %ymm1, %ymm2, %ymm1 +; AVX2-NEXT: vpermq {{.*#+}} ymm1 = ymm1[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v64i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm2 +; AVX512-NEXT: vpmovsxbw %ymm2, %zmm2 +; AVX512-NEXT: vpmovsxbw %ymm0, %zmm0 +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm3 +; AVX512-NEXT: vpmovsxbw %ymm3, %zmm3 +; AVX512-NEXT: vpaddw %zmm3, %zmm2, %zmm2 +; AVX512-NEXT: vpmovsxbw %ymm1, %zmm1 +; AVX512-NEXT: vpaddw %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlw $1, %zmm2, %zmm1 +; AVX512-NEXT: vpsrlw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovwb %zmm0, %ymm0 +; AVX512-NEXT: vpmovwb %zmm1, %ymm1 +; AVX512-NEXT: vinserti64x4 $1, %ymm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %x0 = sext <64 x i8> %a0 to <64 x i16> + %x1 = sext <64 x i8> %a1 to <64 x i16> + %sum = add <64 x i16> %x0, %x1 + %shift = ashr <64 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <64 x i16> %shift to <64 x i8> + ret <64 x i8> %res +} + +define <32 x i16> @test_fixed_v32i16(<32 x i16> %a0, <32 x i16> %a1) { +; SSE-LABEL: test_fixed_v32i16: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm8 +; SSE-NEXT: pand %xmm7, %xmm8 +; SSE-NEXT: movdqa %xmm2, %xmm9 +; SSE-NEXT: pand %xmm6, %xmm9 +; SSE-NEXT: movdqa %xmm1, %xmm10 +; SSE-NEXT: pand %xmm5, %xmm10 +; SSE-NEXT: movdqa %xmm0, %xmm11 +; SSE-NEXT: pand %xmm4, %xmm11 +; SSE-NEXT: pxor %xmm4, %xmm0 +; SSE-NEXT: pxor %xmm5, %xmm1 +; SSE-NEXT: pxor %xmm6, %xmm2 +; SSE-NEXT: pxor %xmm7, %xmm3 +; SSE-NEXT: psraw $1, %xmm3 +; SSE-NEXT: paddw %xmm8, %xmm3 +; SSE-NEXT: psraw $1, %xmm2 +; SSE-NEXT: paddw %xmm9, %xmm2 +; SSE-NEXT: psraw $1, %xmm1 +; SSE-NEXT: paddw %xmm10, %xmm1 +; SSE-NEXT: psraw $1, %xmm0 +; SSE-NEXT: paddw %xmm11, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v32i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsraw $1, %xmm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsraw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsraw $1, %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsraw $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpaddw %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpaddw %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpaddw %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpaddw %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v32i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsraw $1, %ymm1, %ymm1 +; AVX2-NEXT: vpaddw %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsraw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpaddw %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v32i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpandq %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxorq %zmm0, %zmm1, %zmm0 +; AVX512-NEXT: vpsraw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpaddw %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %and = and <32 x i16> %a0, %a1 + %xor = xor <32 x i16> %a1, %a0 + %shift = ashr <32 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = add <32 x i16> %and, %shift + ret <32 x i16> %res +} + +define <32 x i16> @test_ext_v32i16(<32 x i16> %a0, <32 x i16> %a1) { +; SSE2-LABEL: test_ext_v32i16: +; SSE2: # %bb.0: +; SSE2-NEXT: movdqa %xmm3, %xmm9 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm8 = xmm8[4],xmm0[4],xmm8[5],xmm0[5],xmm8[6],xmm0[6],xmm8[7],xmm0[7] +; SSE2-NEXT: psrad $16, %xmm8 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm15 = xmm15[0],xmm0[0],xmm15[1],xmm0[1],xmm15[2],xmm0[2],xmm15[3],xmm0[3] +; SSE2-NEXT: psrad $16, %xmm15 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4],xmm1[4],xmm3[5],xmm1[5],xmm3[6],xmm1[6],xmm3[7],xmm1[7] +; SSE2-NEXT: psrad $16, %xmm3 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm14 = xmm14[0],xmm1[0],xmm14[1],xmm1[1],xmm14[2],xmm1[2],xmm14[3],xmm1[3] +; SSE2-NEXT: psrad $16, %xmm14 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm13 = xmm13[4],xmm2[4],xmm13[5],xmm2[5],xmm13[6],xmm2[6],xmm13[7],xmm2[7] +; SSE2-NEXT: psrad $16, %xmm13 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm12 = xmm12[0],xmm2[0],xmm12[1],xmm2[1],xmm12[2],xmm2[2],xmm12[3],xmm2[3] +; SSE2-NEXT: psrad $16, %xmm12 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm11 = xmm11[4],xmm9[4],xmm11[5],xmm9[5],xmm11[6],xmm9[6],xmm11[7],xmm9[7] +; SSE2-NEXT: psrad $16, %xmm11 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm10 = xmm10[0],xmm9[0],xmm10[1],xmm9[1],xmm10[2],xmm9[2],xmm10[3],xmm9[3] +; SSE2-NEXT: psrad $16, %xmm10 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm9 = xmm9[4],xmm4[4],xmm9[5],xmm4[5],xmm9[6],xmm4[6],xmm9[7],xmm4[7] +; SSE2-NEXT: psrad $16, %xmm9 +; SSE2-NEXT: paddd %xmm8, %xmm9 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1],xmm0[2],xmm4[2],xmm0[3],xmm4[3] +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: paddd %xmm15, %xmm0 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm8 = xmm8[4],xmm5[4],xmm8[5],xmm5[5],xmm8[6],xmm5[6],xmm8[7],xmm5[7] +; SSE2-NEXT: psrad $16, %xmm8 +; SSE2-NEXT: paddd %xmm3, %xmm8 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm5[0],xmm1[1],xmm5[1],xmm1[2],xmm5[2],xmm1[3],xmm5[3] +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: paddd %xmm14, %xmm1 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm5 = xmm5[4],xmm6[4],xmm5[5],xmm6[5],xmm5[6],xmm6[6],xmm5[7],xmm6[7] +; SSE2-NEXT: psrad $16, %xmm5 +; SSE2-NEXT: paddd %xmm13, %xmm5 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm6[0],xmm2[1],xmm6[1],xmm2[2],xmm6[2],xmm2[3],xmm6[3] +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: paddd %xmm12, %xmm2 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm4 = xmm4[4],xmm7[4],xmm4[5],xmm7[5],xmm4[6],xmm7[6],xmm4[7],xmm7[7] +; SSE2-NEXT: psrad $16, %xmm4 +; SSE2-NEXT: paddd %xmm11, %xmm4 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm7[0],xmm3[1],xmm7[1],xmm3[2],xmm7[2],xmm3[3],xmm7[3] +; SSE2-NEXT: psrad $16, %xmm3 +; SSE2-NEXT: paddd %xmm10, %xmm3 +; SSE2-NEXT: pslld $15, %xmm9 +; SSE2-NEXT: psrad $16, %xmm9 +; SSE2-NEXT: pslld $15, %xmm0 +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: packssdw %xmm9, %xmm0 +; SSE2-NEXT: pslld $15, %xmm8 +; SSE2-NEXT: psrad $16, %xmm8 +; SSE2-NEXT: pslld $15, %xmm1 +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: packssdw %xmm8, %xmm1 +; SSE2-NEXT: pslld $15, %xmm5 +; SSE2-NEXT: psrad $16, %xmm5 +; SSE2-NEXT: pslld $15, %xmm2 +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: packssdw %xmm5, %xmm2 +; SSE2-NEXT: pslld $15, %xmm4 +; SSE2-NEXT: psrad $16, %xmm4 +; SSE2-NEXT: pslld $15, %xmm3 +; SSE2-NEXT: psrad $16, %xmm3 +; SSE2-NEXT: packssdw %xmm4, %xmm3 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v32i16: +; SSE4: # %bb.0: +; SSE4-NEXT: pshufd {{.*#+}} xmm8 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm8, %xmm9 +; SSE4-NEXT: pmovsxwd %xmm3, %xmm10 +; SSE4-NEXT: pshufd {{.*#+}} xmm3 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm3, %xmm11 +; SSE4-NEXT: pmovsxwd %xmm2, %xmm12 +; SSE4-NEXT: pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm2, %xmm13 +; SSE4-NEXT: pmovsxwd %xmm1, %xmm14 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm1, %xmm15 +; SSE4-NEXT: pmovsxwd %xmm0, %xmm0 +; SSE4-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm7[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm8 +; SSE4-NEXT: paddd %xmm9, %xmm8 +; SSE4-NEXT: pmovsxwd %xmm7, %xmm3 +; SSE4-NEXT: paddd %xmm10, %xmm3 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm6[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm7 +; SSE4-NEXT: paddd %xmm11, %xmm7 +; SSE4-NEXT: pmovsxwd %xmm6, %xmm2 +; SSE4-NEXT: paddd %xmm12, %xmm2 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm5[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm6 +; SSE4-NEXT: paddd %xmm13, %xmm6 +; SSE4-NEXT: pmovsxwd %xmm5, %xmm1 +; SSE4-NEXT: paddd %xmm14, %xmm1 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm4[2,3,2,3] +; SSE4-NEXT: pmovsxwd %xmm0, %xmm5 +; SSE4-NEXT: paddd %xmm15, %xmm5 +; SSE4-NEXT: pmovsxwd %xmm4, %xmm0 +; SSE4-NEXT: paddd {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload +; SSE4-NEXT: psrld $1, %xmm8 +; SSE4-NEXT: psrld $1, %xmm3 +; SSE4-NEXT: psrld $1, %xmm7 +; SSE4-NEXT: psrld $1, %xmm2 +; SSE4-NEXT: psrld $1, %xmm6 +; SSE4-NEXT: psrld $1, %xmm1 +; SSE4-NEXT: psrld $1, %xmm5 +; SSE4-NEXT: psrld $1, %xmm0 +; SSE4-NEXT: pxor %xmm4, %xmm4 +; SSE4-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm4[1],xmm0[2],xmm4[3],xmm0[4],xmm4[5],xmm0[6],xmm4[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm5 = xmm5[0],xmm4[1],xmm5[2],xmm4[3],xmm5[4],xmm4[5],xmm5[6],xmm4[7] +; SSE4-NEXT: packusdw %xmm5, %xmm0 +; SSE4-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm4[1],xmm1[2],xmm4[3],xmm1[4],xmm4[5],xmm1[6],xmm4[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm6 = xmm6[0],xmm4[1],xmm6[2],xmm4[3],xmm6[4],xmm4[5],xmm6[6],xmm4[7] +; SSE4-NEXT: packusdw %xmm6, %xmm1 +; SSE4-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0],xmm4[1],xmm2[2],xmm4[3],xmm2[4],xmm4[5],xmm2[6],xmm4[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm7 = xmm7[0],xmm4[1],xmm7[2],xmm4[3],xmm7[4],xmm4[5],xmm7[6],xmm4[7] +; SSE4-NEXT: packusdw %xmm7, %xmm2 +; SSE4-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0],xmm4[1],xmm3[2],xmm4[3],xmm3[4],xmm4[5],xmm3[6],xmm4[7] +; SSE4-NEXT: pblendw {{.*#+}} xmm8 = xmm8[0],xmm4[1],xmm8[2],xmm4[3],xmm8[4],xmm4[5],xmm8[6],xmm4[7] +; SSE4-NEXT: packusdw %xmm8, %xmm3 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v32i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vpshufd {{.*#+}} xmm4 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm4, %xmm4 +; AVX1-NEXT: vpmovsxwd %xmm1, %xmm5 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpshufd {{.*#+}} xmm6 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm6, %xmm6 +; AVX1-NEXT: vpmovsxwd %xmm1, %xmm1 +; AVX1-NEXT: vpshufd {{.*#+}} xmm7 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm7, %xmm7 +; AVX1-NEXT: vpmovsxwd %xmm0, %xmm8 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm9 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm9, %xmm9 +; AVX1-NEXT: vpmovsxwd %xmm0, %xmm0 +; AVX1-NEXT: vpshufd {{.*#+}} xmm10 = xmm3[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm10, %xmm10 +; AVX1-NEXT: vpaddd %xmm4, %xmm10, %xmm4 +; AVX1-NEXT: vpmovsxwd %xmm3, %xmm10 +; AVX1-NEXT: vpaddd %xmm5, %xmm10, %xmm5 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm3 +; AVX1-NEXT: vpshufd {{.*#+}} xmm10 = xmm3[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm10, %xmm10 +; AVX1-NEXT: vpaddd %xmm6, %xmm10, %xmm6 +; AVX1-NEXT: vpmovsxwd %xmm3, %xmm3 +; AVX1-NEXT: vpaddd %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpshufd {{.*#+}} xmm3 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm3, %xmm3 +; AVX1-NEXT: vpaddd %xmm3, %xmm7, %xmm3 +; AVX1-NEXT: vpmovsxwd %xmm2, %xmm7 +; AVX1-NEXT: vpaddd %xmm7, %xmm8, %xmm7 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm2 +; AVX1-NEXT: vpshufd {{.*#+}} xmm8 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxwd %xmm8, %xmm8 +; AVX1-NEXT: vpaddd %xmm8, %xmm9, %xmm8 +; AVX1-NEXT: vpmovsxwd %xmm2, %xmm2 +; AVX1-NEXT: vpaddd %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm4, %xmm2 +; AVX1-NEXT: vpsrld $1, %xmm5, %xmm4 +; AVX1-NEXT: vpsrld $1, %xmm6, %xmm5 +; AVX1-NEXT: vpsrld $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm3, %xmm3 +; AVX1-NEXT: vpsrld $1, %xmm7, %xmm6 +; AVX1-NEXT: vpsrld $1, %xmm8, %xmm7 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vpxor %xmm8, %xmm8, %xmm8 +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm8[1],xmm0[2],xmm8[3],xmm0[4],xmm8[5],xmm0[6],xmm8[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm7 = xmm7[0],xmm8[1],xmm7[2],xmm8[3],xmm7[4],xmm8[5],xmm7[6],xmm8[7] +; AVX1-NEXT: vpackusdw %xmm7, %xmm0, %xmm0 +; AVX1-NEXT: vpblendw {{.*#+}} xmm6 = xmm6[0],xmm8[1],xmm6[2],xmm8[3],xmm6[4],xmm8[5],xmm6[6],xmm8[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm3 = xmm3[0],xmm8[1],xmm3[2],xmm8[3],xmm3[4],xmm8[5],xmm3[6],xmm8[7] +; AVX1-NEXT: vpackusdw %xmm3, %xmm6, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm8[1],xmm1[2],xmm8[3],xmm1[4],xmm8[5],xmm1[6],xmm8[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm3 = xmm5[0],xmm8[1],xmm5[2],xmm8[3],xmm5[4],xmm8[5],xmm5[6],xmm8[7] +; AVX1-NEXT: vpackusdw %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpblendw {{.*#+}} xmm3 = xmm4[0],xmm8[1],xmm4[2],xmm8[3],xmm4[4],xmm8[5],xmm4[6],xmm8[7] +; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm2[0],xmm8[1],xmm2[2],xmm8[3],xmm2[4],xmm8[5],xmm2[6],xmm8[7] +; AVX1-NEXT: vpackusdw %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v32i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovsxwd %xmm1, %ymm4 +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX2-NEXT: vpmovsxwd %xmm1, %ymm1 +; AVX2-NEXT: vpmovsxwd %xmm0, %ymm5 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vpmovsxwd %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxwd %xmm3, %ymm6 +; AVX2-NEXT: vpaddd %ymm6, %ymm4, %ymm4 +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm3 +; AVX2-NEXT: vpmovsxwd %xmm3, %ymm3 +; AVX2-NEXT: vpaddd %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpmovsxwd %xmm2, %ymm3 +; AVX2-NEXT: vpaddd %ymm3, %ymm5, %ymm3 +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm2 +; AVX2-NEXT: vpmovsxwd %xmm2, %ymm2 +; AVX2-NEXT: vpaddd %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm4, %ymm2 +; AVX2-NEXT: vpsrld $1, %ymm1, %ymm1 +; AVX2-NEXT: vpsrld $1, %ymm3, %ymm3 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpxor %xmm4, %xmm4, %xmm4 +; AVX2-NEXT: vpblendw {{.*#+}} ymm0 = ymm0[0],ymm4[1],ymm0[2],ymm4[3],ymm0[4],ymm4[5],ymm0[6],ymm4[7],ymm0[8],ymm4[9],ymm0[10],ymm4[11],ymm0[12],ymm4[13],ymm0[14],ymm4[15] +; AVX2-NEXT: vpblendw {{.*#+}} ymm3 = ymm3[0],ymm4[1],ymm3[2],ymm4[3],ymm3[4],ymm4[5],ymm3[6],ymm4[7],ymm3[8],ymm4[9],ymm3[10],ymm4[11],ymm3[12],ymm4[13],ymm3[14],ymm4[15] +; AVX2-NEXT: vpackusdw %ymm0, %ymm3, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: vpblendw {{.*#+}} ymm1 = ymm1[0],ymm4[1],ymm1[2],ymm4[3],ymm1[4],ymm4[5],ymm1[6],ymm4[7],ymm1[8],ymm4[9],ymm1[10],ymm4[11],ymm1[12],ymm4[13],ymm1[14],ymm4[15] +; AVX2-NEXT: vpblendw {{.*#+}} ymm2 = ymm2[0],ymm4[1],ymm2[2],ymm4[3],ymm2[4],ymm4[5],ymm2[6],ymm4[7],ymm2[8],ymm4[9],ymm2[10],ymm4[11],ymm2[12],ymm4[13],ymm2[14],ymm4[15] +; AVX2-NEXT: vpackusdw %ymm1, %ymm2, %ymm1 +; AVX2-NEXT: vpermq {{.*#+}} ymm1 = ymm1[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v32i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm2 +; AVX512-NEXT: vpmovsxwd %ymm2, %zmm2 +; AVX512-NEXT: vpmovsxwd %ymm0, %zmm0 +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm3 +; AVX512-NEXT: vpmovsxwd %ymm3, %zmm3 +; AVX512-NEXT: vpaddd %zmm3, %zmm2, %zmm2 +; AVX512-NEXT: vpmovsxwd %ymm1, %zmm1 +; AVX512-NEXT: vpaddd %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrld $1, %zmm2, %zmm1 +; AVX512-NEXT: vpsrld $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovdw %zmm0, %ymm0 +; AVX512-NEXT: vpmovdw %zmm1, %ymm1 +; AVX512-NEXT: vinserti64x4 $1, %ymm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %x0 = sext <32 x i16> %a0 to <32 x i32> + %x1 = sext <32 x i16> %a1 to <32 x i32> + %sum = add <32 x i32> %x0, %x1 + %shift = ashr <32 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <32 x i32> %shift to <32 x i16> + ret <32 x i16> %res +} + +define <16 x i32> @test_fixed_v16i32(<16 x i32> %a0, <16 x i32> %a1) { +; SSE-LABEL: test_fixed_v16i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm8 +; SSE-NEXT: pand %xmm7, %xmm8 +; SSE-NEXT: movdqa %xmm2, %xmm9 +; SSE-NEXT: pand %xmm6, %xmm9 +; SSE-NEXT: movdqa %xmm1, %xmm10 +; SSE-NEXT: pand %xmm5, %xmm10 +; SSE-NEXT: movdqa %xmm0, %xmm11 +; SSE-NEXT: pand %xmm4, %xmm11 +; SSE-NEXT: pxor %xmm4, %xmm0 +; SSE-NEXT: pxor %xmm5, %xmm1 +; SSE-NEXT: pxor %xmm6, %xmm2 +; SSE-NEXT: pxor %xmm7, %xmm3 +; SSE-NEXT: psrad $1, %xmm3 +; SSE-NEXT: paddd %xmm8, %xmm3 +; SSE-NEXT: psrad $1, %xmm2 +; SSE-NEXT: paddd %xmm9, %xmm2 +; SSE-NEXT: psrad $1, %xmm1 +; SSE-NEXT: paddd %xmm10, %xmm1 +; SSE-NEXT: psrad $1, %xmm0 +; SSE-NEXT: paddd %xmm11, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v16i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsrad $1, %xmm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrad $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpaddd %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpaddd %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpaddd %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpaddd %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v16i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsrad $1, %ymm1, %ymm1 +; AVX2-NEXT: vpaddd %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsrad $1, %ymm0, %ymm0 +; AVX2-NEXT: vpaddd %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v16i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpandd %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxord %zmm0, %zmm1, %zmm0 +; AVX512-NEXT: vpsrad $1, %zmm0, %zmm0 +; AVX512-NEXT: vpaddd %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %and = and <16 x i32> %a0, %a1 + %xor = xor <16 x i32> %a1, %a0 + %shift = ashr <16 x i32> %xor, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = add <16 x i32> %and, %shift + ret <16 x i32> %res +} + +define <16 x i32> @test_ext_v16i32(<16 x i32> %a0, <16 x i32> %a1) { +; SSE2-LABEL: test_ext_v16i32: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: pxor %xmm9, %xmm9 +; SSE2-NEXT: pcmpgtd %xmm3, %xmm9 +; SSE2-NEXT: pshufd {{.*#+}} xmm13 = xmm3[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm9[0],xmm3[1],xmm9[1] +; SSE2-NEXT: pxor %xmm9, %xmm9 +; SSE2-NEXT: pcmpgtd %xmm13, %xmm9 +; SSE2-NEXT: punpckldq {{.*#+}} xmm13 = xmm13[0],xmm9[0],xmm13[1],xmm9[1] +; SSE2-NEXT: pxor %xmm9, %xmm9 +; SSE2-NEXT: pcmpgtd %xmm2, %xmm9 +; SSE2-NEXT: pshufd {{.*#+}} xmm12 = xmm2[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm9[0],xmm2[1],xmm9[1] +; SSE2-NEXT: pxor %xmm9, %xmm9 +; SSE2-NEXT: pcmpgtd %xmm12, %xmm9 +; SSE2-NEXT: punpckldq {{.*#+}} xmm12 = xmm12[0],xmm9[0],xmm12[1],xmm9[1] +; SSE2-NEXT: pxor %xmm9, %xmm9 +; SSE2-NEXT: pcmpgtd %xmm1, %xmm9 +; SSE2-NEXT: pshufd {{.*#+}} xmm11 = xmm1[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm9[0],xmm1[1],xmm9[1] +; SSE2-NEXT: pxor %xmm9, %xmm9 +; SSE2-NEXT: pcmpgtd %xmm11, %xmm9 +; SSE2-NEXT: punpckldq {{.*#+}} xmm11 = xmm11[0],xmm9[0],xmm11[1],xmm9[1] +; SSE2-NEXT: pxor %xmm10, %xmm10 +; SSE2-NEXT: pcmpgtd %xmm0, %xmm10 +; SSE2-NEXT: pshufd {{.*#+}} xmm9 = xmm0[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm10[0],xmm0[1],xmm10[1] +; SSE2-NEXT: pxor %xmm10, %xmm10 +; SSE2-NEXT: pcmpgtd %xmm9, %xmm10 +; SSE2-NEXT: punpckldq {{.*#+}} xmm9 = xmm9[0],xmm10[0],xmm9[1],xmm10[1] +; SSE2-NEXT: pxor %xmm14, %xmm14 +; SSE2-NEXT: pcmpgtd %xmm7, %xmm14 +; SSE2-NEXT: pshufd {{.*#+}} xmm10 = xmm7[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm7 = xmm7[0],xmm14[0],xmm7[1],xmm14[1] +; SSE2-NEXT: paddq %xmm7, %xmm3 +; SSE2-NEXT: pxor %xmm7, %xmm7 +; SSE2-NEXT: pcmpgtd %xmm10, %xmm7 +; SSE2-NEXT: punpckldq {{.*#+}} xmm10 = xmm10[0],xmm7[0],xmm10[1],xmm7[1] +; SSE2-NEXT: paddq %xmm13, %xmm10 +; SSE2-NEXT: pxor %xmm13, %xmm13 +; SSE2-NEXT: pcmpgtd %xmm6, %xmm13 +; SSE2-NEXT: pshufd {{.*#+}} xmm7 = xmm6[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm6 = xmm6[0],xmm13[0],xmm6[1],xmm13[1] +; SSE2-NEXT: paddq %xmm6, %xmm2 +; SSE2-NEXT: pxor %xmm6, %xmm6 +; SSE2-NEXT: pcmpgtd %xmm7, %xmm6 +; SSE2-NEXT: punpckldq {{.*#+}} xmm7 = xmm7[0],xmm6[0],xmm7[1],xmm6[1] +; SSE2-NEXT: paddq %xmm12, %xmm7 +; SSE2-NEXT: pxor %xmm12, %xmm12 +; SSE2-NEXT: pcmpgtd %xmm5, %xmm12 +; SSE2-NEXT: pshufd {{.*#+}} xmm6 = xmm5[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm5 = xmm5[0],xmm12[0],xmm5[1],xmm12[1] +; SSE2-NEXT: paddq %xmm5, %xmm1 +; SSE2-NEXT: pxor %xmm5, %xmm5 +; SSE2-NEXT: pcmpgtd %xmm6, %xmm5 +; SSE2-NEXT: punpckldq {{.*#+}} xmm6 = xmm6[0],xmm5[0],xmm6[1],xmm5[1] +; SSE2-NEXT: paddq %xmm11, %xmm6 +; SSE2-NEXT: pxor %xmm11, %xmm11 +; SSE2-NEXT: pcmpgtd %xmm4, %xmm11 +; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm4[2,3,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm11[0],xmm4[1],xmm11[1] +; SSE2-NEXT: paddq %xmm4, %xmm0 +; SSE2-NEXT: pcmpgtd %xmm5, %xmm8 +; SSE2-NEXT: punpckldq {{.*#+}} xmm5 = xmm5[0],xmm8[0],xmm5[1],xmm8[1] +; SSE2-NEXT: paddq %xmm9, %xmm5 +; SSE2-NEXT: psrlq $1, %xmm3 +; SSE2-NEXT: psrlq $1, %xmm10 +; SSE2-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,2],xmm10[0,2] +; SSE2-NEXT: psrlq $1, %xmm2 +; SSE2-NEXT: psrlq $1, %xmm7 +; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm7[0,2] +; SSE2-NEXT: psrlq $1, %xmm1 +; SSE2-NEXT: psrlq $1, %xmm6 +; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm6[0,2] +; SSE2-NEXT: psrlq $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm5 +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm5[0,2] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v16i32: +; SSE4: # %bb.0: +; SSE4-NEXT: pmovsxdq %xmm3, %xmm8 +; SSE4-NEXT: pshufd {{.*#+}} xmm3 = xmm3[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm3, %xmm9 +; SSE4-NEXT: pmovsxdq %xmm2, %xmm10 +; SSE4-NEXT: pshufd {{.*#+}} xmm2 = xmm2[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm2, %xmm11 +; SSE4-NEXT: pmovsxdq %xmm1, %xmm12 +; SSE4-NEXT: pshufd {{.*#+}} xmm1 = xmm1[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm1, %xmm13 +; SSE4-NEXT: pmovsxdq %xmm0, %xmm14 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm15 +; SSE4-NEXT: pmovsxdq %xmm7, %xmm3 +; SSE4-NEXT: paddq %xmm8, %xmm3 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm7[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm7 +; SSE4-NEXT: paddq %xmm9, %xmm7 +; SSE4-NEXT: pmovsxdq %xmm6, %xmm2 +; SSE4-NEXT: paddq %xmm10, %xmm2 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm6[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm6 +; SSE4-NEXT: paddq %xmm11, %xmm6 +; SSE4-NEXT: pmovsxdq %xmm5, %xmm1 +; SSE4-NEXT: paddq %xmm12, %xmm1 +; SSE4-NEXT: pshufd {{.*#+}} xmm0 = xmm5[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm0, %xmm5 +; SSE4-NEXT: paddq %xmm13, %xmm5 +; SSE4-NEXT: pmovsxdq %xmm4, %xmm0 +; SSE4-NEXT: paddq %xmm14, %xmm0 +; SSE4-NEXT: pshufd {{.*#+}} xmm4 = xmm4[2,3,2,3] +; SSE4-NEXT: pmovsxdq %xmm4, %xmm4 +; SSE4-NEXT: paddq %xmm15, %xmm4 +; SSE4-NEXT: psrlq $1, %xmm3 +; SSE4-NEXT: psrlq $1, %xmm7 +; SSE4-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,2],xmm7[0,2] +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: psrlq $1, %xmm6 +; SSE4-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm6[0,2] +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: psrlq $1, %xmm5 +; SSE4-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm5[0,2] +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: psrlq $1, %xmm4 +; SSE4-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm4[0,2] +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v16i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm4 +; AVX1-NEXT: vpshufd {{.*#+}} xmm5 = xmm4[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm5, %xmm5 +; AVX1-NEXT: vpshufd {{.*#+}} xmm6 = xmm1[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm6, %xmm6 +; AVX1-NEXT: vpmovsxdq %xmm4, %xmm4 +; AVX1-NEXT: vpmovsxdq %xmm1, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm7 +; AVX1-NEXT: vpshufd {{.*#+}} xmm8 = xmm7[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm8, %xmm8 +; AVX1-NEXT: vpshufd {{.*#+}} xmm9 = xmm0[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm9, %xmm9 +; AVX1-NEXT: vpmovsxdq %xmm7, %xmm7 +; AVX1-NEXT: vpmovsxdq %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm10 +; AVX1-NEXT: vpshufd {{.*#+}} xmm11 = xmm10[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm11, %xmm11 +; AVX1-NEXT: vpaddq %xmm5, %xmm11, %xmm5 +; AVX1-NEXT: vpshufd {{.*#+}} xmm11 = xmm3[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm11, %xmm11 +; AVX1-NEXT: vpaddq %xmm6, %xmm11, %xmm6 +; AVX1-NEXT: vpmovsxdq %xmm10, %xmm10 +; AVX1-NEXT: vpaddq %xmm4, %xmm10, %xmm4 +; AVX1-NEXT: vpmovsxdq %xmm3, %xmm3 +; AVX1-NEXT: vpaddq %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpshufd {{.*#+}} xmm10 = xmm3[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm10, %xmm10 +; AVX1-NEXT: vpaddq %xmm10, %xmm8, %xmm8 +; AVX1-NEXT: vpshufd {{.*#+}} xmm10 = xmm2[2,3,2,3] +; AVX1-NEXT: vpmovsxdq %xmm10, %xmm10 +; AVX1-NEXT: vpaddq %xmm10, %xmm9, %xmm9 +; AVX1-NEXT: vpmovsxdq %xmm3, %xmm3 +; AVX1-NEXT: vpaddq %xmm3, %xmm7, %xmm3 +; AVX1-NEXT: vpmovsxdq %xmm2, %xmm2 +; AVX1-NEXT: vpaddq %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm5, %xmm2 +; AVX1-NEXT: vpsrlq $1, %xmm6, %xmm5 +; AVX1-NEXT: vpsrlq $1, %xmm4, %xmm4 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm8, %xmm6 +; AVX1-NEXT: vpsrlq $1, %xmm9, %xmm7 +; AVX1-NEXT: vpsrlq $1, %xmm3, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm3, %ymm0, %ymm0 +; AVX1-NEXT: vinsertf128 $1, %xmm6, %ymm7, %ymm3 +; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm3[0,2],ymm0[4,6],ymm3[4,6] +; AVX1-NEXT: vinsertf128 $1, %xmm4, %ymm1, %ymm1 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm5, %ymm2 +; AVX1-NEXT: vshufps {{.*#+}} ymm1 = ymm1[0,2],ymm2[0,2],ymm1[4,6],ymm2[4,6] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v16i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm4 +; AVX2-NEXT: vpmovsxdq %xmm4, %ymm4 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm5 +; AVX2-NEXT: vpmovsxdq %xmm5, %ymm5 +; AVX2-NEXT: vpmovsxdq %xmm0, %ymm0 +; AVX2-NEXT: vpmovsxdq %xmm1, %ymm1 +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm6 +; AVX2-NEXT: vpmovsxdq %xmm6, %ymm6 +; AVX2-NEXT: vpaddq %ymm6, %ymm4, %ymm4 +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm6 +; AVX2-NEXT: vpmovsxdq %xmm6, %ymm6 +; AVX2-NEXT: vpaddq %ymm6, %ymm5, %ymm5 +; AVX2-NEXT: vpmovsxdq %xmm2, %ymm2 +; AVX2-NEXT: vpaddq %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpmovsxdq %xmm3, %ymm2 +; AVX2-NEXT: vpaddq %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm2 = ymm0[2,3],ymm5[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm2, %ymm2 +; AVX2-NEXT: vinserti128 $1, %xmm5, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm2[0,2],ymm0[4,6],ymm2[4,6] +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm2 = ymm1[2,3],ymm4[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm2, %ymm2 +; AVX2-NEXT: vinserti128 $1, %xmm4, %ymm1, %ymm1 +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vshufps {{.*#+}} ymm1 = ymm1[0,2],ymm2[0,2],ymm1[4,6],ymm2[4,6] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v16i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm2 +; AVX512-NEXT: vpmovsxdq %ymm2, %zmm2 +; AVX512-NEXT: vpmovsxdq %ymm0, %zmm0 +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm3 +; AVX512-NEXT: vpmovsxdq %ymm3, %zmm3 +; AVX512-NEXT: vpaddq %zmm3, %zmm2, %zmm2 +; AVX512-NEXT: vpmovsxdq %ymm1, %zmm1 +; AVX512-NEXT: vpaddq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm2, %zmm1 +; AVX512-NEXT: vpsrlq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovqd %zmm0, %ymm0 +; AVX512-NEXT: vpmovqd %zmm1, %ymm1 +; AVX512-NEXT: vinserti64x4 $1, %ymm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %x0 = sext <16 x i32> %a0 to <16 x i64> + %x1 = sext <16 x i32> %a1 to <16 x i64> + %sum = add <16 x i64> %x0, %x1 + %shift = ashr <16 x i64> %sum, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = trunc <16 x i64> %shift to <16 x i32> + ret <16 x i32> %res +} + +define <8 x i64> @test_fixed_v8i64(<8 x i64> %a0, <8 x i64> %a1) { +; SSE2-LABEL: test_fixed_v8i64: +; SSE2: # %bb.0: +; SSE2-NEXT: movdqa %xmm3, %xmm11 +; SSE2-NEXT: pand %xmm7, %xmm11 +; SSE2-NEXT: movdqa %xmm2, %xmm10 +; SSE2-NEXT: pand %xmm6, %xmm10 +; SSE2-NEXT: movdqa %xmm1, %xmm9 +; SSE2-NEXT: pand %xmm5, %xmm9 +; SSE2-NEXT: movdqa %xmm0, %xmm8 +; SSE2-NEXT: pand %xmm4, %xmm8 +; SSE2-NEXT: pxor %xmm0, %xmm4 +; SSE2-NEXT: pxor %xmm1, %xmm5 +; SSE2-NEXT: pxor %xmm2, %xmm6 +; SSE2-NEXT: pxor %xmm3, %xmm7 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm7[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm7 +; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm7[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1] +; SSE2-NEXT: paddq %xmm11, %xmm3 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm6[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm6 +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm6[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1] +; SSE2-NEXT: paddq %xmm10, %xmm2 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm5[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm5 +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm5[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] +; SSE2-NEXT: paddq %xmm9, %xmm1 +; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm4[1,3,2,3] +; SSE2-NEXT: psrad $1, %xmm5 +; SSE2-NEXT: psrlq $1, %xmm4 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm4[0,2,2,3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm5[0],xmm0[1],xmm5[1] +; SSE2-NEXT: paddq %xmm8, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_fixed_v8i64: +; SSE4: # %bb.0: +; SSE4-NEXT: movdqa %xmm3, %xmm10 +; SSE4-NEXT: pand %xmm7, %xmm10 +; SSE4-NEXT: movdqa %xmm2, %xmm11 +; SSE4-NEXT: pand %xmm6, %xmm11 +; SSE4-NEXT: movdqa %xmm1, %xmm9 +; SSE4-NEXT: pand %xmm5, %xmm9 +; SSE4-NEXT: movdqa %xmm0, %xmm8 +; SSE4-NEXT: pand %xmm4, %xmm8 +; SSE4-NEXT: pxor %xmm4, %xmm0 +; SSE4-NEXT: pxor %xmm5, %xmm1 +; SSE4-NEXT: pxor %xmm6, %xmm2 +; SSE4-NEXT: pxor %xmm7, %xmm3 +; SSE4-NEXT: movdqa %xmm3, %xmm4 +; SSE4-NEXT: psrad $1, %xmm4 +; SSE4-NEXT: psrlq $1, %xmm3 +; SSE4-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0,1],xmm4[2,3],xmm3[4,5],xmm4[6,7] +; SSE4-NEXT: paddq %xmm10, %xmm3 +; SSE4-NEXT: movdqa %xmm2, %xmm4 +; SSE4-NEXT: psrad $1, %xmm4 +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0,1],xmm4[2,3],xmm2[4,5],xmm4[6,7] +; SSE4-NEXT: paddq %xmm11, %xmm2 +; SSE4-NEXT: movdqa %xmm1, %xmm4 +; SSE4-NEXT: psrad $1, %xmm4 +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm4[2,3],xmm1[4,5],xmm4[6,7] +; SSE4-NEXT: paddq %xmm9, %xmm1 +; SSE4-NEXT: movdqa %xmm0, %xmm4 +; SSE4-NEXT: psrad $1, %xmm4 +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm4[2,3],xmm0[4,5],xmm4[6,7] +; SSE4-NEXT: paddq %xmm8, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_fixed_v8i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsrad $1, %xmm1, %xmm2 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm3 +; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm3[0,1],xmm2[2,3],xmm3[4,5],xmm2[6,7] +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrad $1, %xmm1, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm1 +; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7] +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm6 +; AVX1-NEXT: vpblendw {{.*#+}} xmm3 = xmm6[0,1],xmm3[2,3],xmm6[4,5],xmm3[6,7] +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrad $1, %xmm0, %xmm6 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm6[2,3],xmm0[4,5],xmm6[6,7] +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpaddq %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpaddq %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpaddq %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpaddq %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v8i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsrad $1, %ymm1, %ymm2 +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vpblendd {{.*#+}} ymm1 = ymm1[0],ymm2[1],ymm1[2],ymm2[3],ymm1[4],ymm2[5],ymm1[6],ymm2[7] +; AVX2-NEXT: vpaddq %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsrad $1, %ymm0, %ymm2 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vpblendd {{.*#+}} ymm0 = ymm0[0],ymm2[1],ymm0[2],ymm2[3],ymm0[4],ymm2[5],ymm0[6],ymm2[7] +; AVX2-NEXT: vpaddq %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v8i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vpandq %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxorq %zmm0, %zmm1, %zmm0 +; AVX512-NEXT: vpsraq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpaddq %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %and = and <8 x i64> %a0, %a1 + %xor = xor <8 x i64> %a1, %a0 + %shift = ashr <8 x i64> %xor, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = add <8 x i64> %and, %shift + ret <8 x i64> %res +} + +define <8 x i64> @test_ext_v8i64(<8 x i64> %a0, <8 x i64> %a1) { +; SSE2-LABEL: test_ext_v8i64: +; SSE2: # %bb.0: +; SSE2-NEXT: pushq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: pushq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: pushq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: pushq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: pushq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: pushq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 56 +; SSE2-NEXT: pushq %rax +; SSE2-NEXT: .cfi_def_cfa_offset 64 +; SSE2-NEXT: .cfi_offset %rbx, -56 +; SSE2-NEXT: .cfi_offset %r12, -48 +; SSE2-NEXT: .cfi_offset %r13, -40 +; SSE2-NEXT: .cfi_offset %r14, -32 +; SSE2-NEXT: .cfi_offset %r15, -24 +; SSE2-NEXT: .cfi_offset %rbp, -16 +; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm3[2,3,2,3] +; SSE2-NEXT: movq %xmm8, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: movq %rcx, (%rsp) # 8-byte Spill +; SSE2-NEXT: movq %xmm3, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm2[2,3,2,3] +; SSE2-NEXT: movq %xmm3, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %xmm2, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm2, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %rax, %rcx +; SSE2-NEXT: sarq $63, %rcx +; SSE2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: movq %xmm1, %rbp +; SSE2-NEXT: movq %rbp, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %rbp +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3] +; SSE2-NEXT: movq %xmm1, %rbx +; SSE2-NEXT: movq %rbx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %rbx +; SSE2-NEXT: movq %xmm0, %r15 +; SSE2-NEXT: movq %r15, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %r15 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm7[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r10 +; SSE2-NEXT: movq %r10, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %r10 +; SSE2-NEXT: movq %xmm7, %r9 +; SSE2-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %r9 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm6[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r12 +; SSE2-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %r12 +; SSE2-NEXT: movq %xmm6, %r13 +; SSE2-NEXT: movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: sarq $63, %r13 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm5[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r14 +; SSE2-NEXT: movq %r14, %rsi +; SSE2-NEXT: sarq $63, %rsi +; SSE2-NEXT: movq %xmm5, %r11 +; SSE2-NEXT: movq %r11, %rdx +; SSE2-NEXT: sarq $63, %rdx +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm4[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r8 +; SSE2-NEXT: movq %r8, %rdi +; SSE2-NEXT: sarq $63, %rdi +; SSE2-NEXT: movq %xmm4, %rcx +; SSE2-NEXT: movq %rcx, %rax +; SSE2-NEXT: sarq $63, %rax +; SSE2-NEXT: addq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; SSE2-NEXT: adcq %r15, %rax +; SSE2-NEXT: addq %r8, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; SSE2-NEXT: adcq %rbx, %rdi +; SSE2-NEXT: addq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; SSE2-NEXT: adcq %rbp, %rdx +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Reload +; SSE2-NEXT: addq %r14, %r15 +; SSE2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Folded Reload +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload +; SSE2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Folded Reload +; SSE2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r13 # 8-byte Folded Reload +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Reload +; SSE2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; SSE2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Folded Reload +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; SSE2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Folded Reload +; SSE2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Folded Reload +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; SSE2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Folded Reload +; SSE2-NEXT: adcq (%rsp), %r10 # 8-byte Folded Reload +; SSE2-NEXT: shldq $63, %rcx, %r10 +; SSE2-NEXT: shldq $63, %r8, %r9 +; SSE2-NEXT: shldq $63, %r11, %r12 +; SSE2-NEXT: shldq $63, %rbx, %r13 +; SSE2-NEXT: shldq $63, %r15, %rsi +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; SSE2-NEXT: shldq $63, %rcx, %rdx +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; SSE2-NEXT: shldq $63, %rcx, %rdi +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; SSE2-NEXT: shldq $63, %rcx, %rax +; SSE2-NEXT: movq %rax, %xmm0 +; SSE2-NEXT: movq %rdi, %xmm4 +; SSE2-NEXT: movq %rdx, %xmm1 +; SSE2-NEXT: movq %rsi, %xmm5 +; SSE2-NEXT: movq %r13, %xmm2 +; SSE2-NEXT: movq %r12, %xmm6 +; SSE2-NEXT: movq %r9, %xmm3 +; SSE2-NEXT: movq %r10, %xmm7 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm5[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm6[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm7[0] +; SSE2-NEXT: addq $8, %rsp +; SSE2-NEXT: .cfi_def_cfa_offset 56 +; SSE2-NEXT: popq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: popq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: popq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: popq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: popq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: popq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 8 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v8i64: +; SSE4: # %bb.0: +; SSE4-NEXT: pushq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: pushq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: pushq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: pushq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: pushq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: pushq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 56 +; SSE4-NEXT: pushq %rax +; SSE4-NEXT: .cfi_def_cfa_offset 64 +; SSE4-NEXT: .cfi_offset %rbx, -56 +; SSE4-NEXT: .cfi_offset %r12, -48 +; SSE4-NEXT: .cfi_offset %r13, -40 +; SSE4-NEXT: .cfi_offset %r14, -32 +; SSE4-NEXT: .cfi_offset %r15, -24 +; SSE4-NEXT: .cfi_offset %rbp, -16 +; SSE4-NEXT: movq %xmm3, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: movq %rcx, (%rsp) # 8-byte Spill +; SSE4-NEXT: pextrq $1, %xmm3, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %xmm2, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: pextrq $1, %xmm2, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %xmm1, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: movq %rax, %rcx +; SSE4-NEXT: sarq $63, %rcx +; SSE4-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: pextrq $1, %xmm1, %rbp +; SSE4-NEXT: movq %rbp, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %rbp +; SSE4-NEXT: movq %xmm0, %rbx +; SSE4-NEXT: movq %rbx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %rbx +; SSE4-NEXT: pextrq $1, %xmm0, %r14 +; SSE4-NEXT: movq %r14, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %r14 +; SSE4-NEXT: movq %xmm7, %r10 +; SSE4-NEXT: movq %r10, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %r10 +; SSE4-NEXT: pextrq $1, %xmm7, %r9 +; SSE4-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %r9 +; SSE4-NEXT: movq %xmm6, %r15 +; SSE4-NEXT: movq %r15, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %r15 +; SSE4-NEXT: pextrq $1, %xmm6, %r13 +; SSE4-NEXT: movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: sarq $63, %r13 +; SSE4-NEXT: movq %xmm5, %r12 +; SSE4-NEXT: movq %r12, %rsi +; SSE4-NEXT: sarq $63, %rsi +; SSE4-NEXT: pextrq $1, %xmm5, %r11 +; SSE4-NEXT: movq %r11, %rdx +; SSE4-NEXT: sarq $63, %rdx +; SSE4-NEXT: movq %xmm4, %r8 +; SSE4-NEXT: movq %r8, %rdi +; SSE4-NEXT: sarq $63, %rdi +; SSE4-NEXT: pextrq $1, %xmm4, %rcx +; SSE4-NEXT: movq %rcx, %rax +; SSE4-NEXT: sarq $63, %rax +; SSE4-NEXT: addq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; SSE4-NEXT: adcq %r14, %rax +; SSE4-NEXT: addq %r8, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; SSE4-NEXT: adcq %rbx, %rdi +; SSE4-NEXT: addq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; SSE4-NEXT: adcq %rbp, %rdx +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Reload +; SSE4-NEXT: addq %r12, %r14 +; SSE4-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Folded Reload +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload +; SSE4-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Folded Reload +; SSE4-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r13 # 8-byte Folded Reload +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Reload +; SSE4-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; SSE4-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Folded Reload +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; SSE4-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Folded Reload +; SSE4-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Folded Reload +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; SSE4-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Folded Reload +; SSE4-NEXT: adcq (%rsp), %r10 # 8-byte Folded Reload +; SSE4-NEXT: shldq $63, %rcx, %r10 +; SSE4-NEXT: shldq $63, %r8, %r9 +; SSE4-NEXT: shldq $63, %r11, %r15 +; SSE4-NEXT: shldq $63, %rbx, %r13 +; SSE4-NEXT: shldq $63, %r14, %rsi +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; SSE4-NEXT: shldq $63, %rcx, %rdx +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; SSE4-NEXT: shldq $63, %rcx, %rdi +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; SSE4-NEXT: shldq $63, %rcx, %rax +; SSE4-NEXT: movq %rax, %xmm4 +; SSE4-NEXT: movq %rdi, %xmm0 +; SSE4-NEXT: movq %rdx, %xmm5 +; SSE4-NEXT: movq %rsi, %xmm1 +; SSE4-NEXT: movq %r13, %xmm6 +; SSE4-NEXT: movq %r15, %xmm2 +; SSE4-NEXT: movq %r9, %xmm7 +; SSE4-NEXT: movq %r10, %xmm3 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm5[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm6[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm7[0] +; SSE4-NEXT: addq $8, %rsp +; SSE4-NEXT: .cfi_def_cfa_offset 56 +; SSE4-NEXT: popq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: popq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: popq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: popq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: popq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: popq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 8 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v8i64: +; AVX1: # %bb.0: +; AVX1-NEXT: pushq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: pushq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: pushq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: pushq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: pushq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: pushq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 56 +; AVX1-NEXT: pushq %rax +; AVX1-NEXT: .cfi_def_cfa_offset 64 +; AVX1-NEXT: .cfi_offset %rbx, -56 +; AVX1-NEXT: .cfi_offset %r12, -48 +; AVX1-NEXT: .cfi_offset %r13, -40 +; AVX1-NEXT: .cfi_offset %r14, -32 +; AVX1-NEXT: .cfi_offset %r15, -24 +; AVX1-NEXT: .cfi_offset %rbp, -16 +; AVX1-NEXT: vmovq %xmm1, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movq %rax, %rcx +; AVX1-NEXT: sarq $63, %rcx +; AVX1-NEXT: movq %rcx, (%rsp) # 8-byte Spill +; AVX1-NEXT: vpextrq $1, %xmm1, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movq %rax, %rcx +; AVX1-NEXT: sarq $63, %rcx +; AVX1-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vmovq %xmm1, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movq %rax, %rcx +; AVX1-NEXT: sarq $63, %rcx +; AVX1-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: vpextrq $1, %xmm1, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movq %rax, %rcx +; AVX1-NEXT: sarq $63, %rcx +; AVX1-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: vmovq %xmm0, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: movq %rax, %rcx +; AVX1-NEXT: sarq $63, %rcx +; AVX1-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: vpextrq $1, %xmm0, %rbp +; AVX1-NEXT: movq %rbp, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %rbp +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vmovq %xmm0, %rbx +; AVX1-NEXT: movq %rbx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %rbx +; AVX1-NEXT: vpextrq $1, %xmm0, %r15 +; AVX1-NEXT: movq %r15, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %r15 +; AVX1-NEXT: vmovq %xmm3, %r9 +; AVX1-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %r9 +; AVX1-NEXT: vpextrq $1, %xmm3, %r10 +; AVX1-NEXT: movq %r10, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %r10 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm0 +; AVX1-NEXT: vmovq %xmm0, %r12 +; AVX1-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %r12 +; AVX1-NEXT: vpextrq $1, %xmm0, %r13 +; AVX1-NEXT: movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: sarq $63, %r13 +; AVX1-NEXT: vmovq %xmm2, %r14 +; AVX1-NEXT: movq %r14, %rsi +; AVX1-NEXT: sarq $63, %rsi +; AVX1-NEXT: vpextrq $1, %xmm2, %r11 +; AVX1-NEXT: movq %r11, %rdx +; AVX1-NEXT: sarq $63, %rdx +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm0 +; AVX1-NEXT: vmovq %xmm0, %r8 +; AVX1-NEXT: movq %r8, %rdi +; AVX1-NEXT: sarq $63, %rdi +; AVX1-NEXT: vpextrq $1, %xmm0, %rcx +; AVX1-NEXT: movq %rcx, %rax +; AVX1-NEXT: sarq $63, %rax +; AVX1-NEXT: addq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; AVX1-NEXT: adcq %r15, %rax +; AVX1-NEXT: addq %r8, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; AVX1-NEXT: adcq %rbx, %rdi +; AVX1-NEXT: addq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; AVX1-NEXT: adcq %rbp, %rdx +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Reload +; AVX1-NEXT: addq %r14, %r15 +; AVX1-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Folded Reload +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload +; AVX1-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Folded Reload +; AVX1-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r13 # 8-byte Folded Reload +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Reload +; AVX1-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; AVX1-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Folded Reload +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; AVX1-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Folded Reload +; AVX1-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Folded Reload +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; AVX1-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Folded Reload +; AVX1-NEXT: adcq (%rsp), %r9 # 8-byte Folded Reload +; AVX1-NEXT: shldq $63, %rcx, %r9 +; AVX1-NEXT: shldq $63, %r8, %r10 +; AVX1-NEXT: shldq $63, %r11, %r12 +; AVX1-NEXT: shldq $63, %rbx, %r13 +; AVX1-NEXT: shldq $63, %r15, %rsi +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; AVX1-NEXT: shldq $63, %rcx, %rdx +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; AVX1-NEXT: shldq $63, %rcx, %rdi +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; AVX1-NEXT: shldq $63, %rcx, %rax +; AVX1-NEXT: vmovq %rax, %xmm0 +; AVX1-NEXT: vmovq %rdi, %xmm1 +; AVX1-NEXT: vmovq %rdx, %xmm2 +; AVX1-NEXT: vmovq %rsi, %xmm3 +; AVX1-NEXT: vmovq %r13, %xmm4 +; AVX1-NEXT: vmovq %r12, %xmm5 +; AVX1-NEXT: vmovq %r10, %xmm6 +; AVX1-NEXT: vmovq %r9, %xmm7 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: addq $8, %rsp +; AVX1-NEXT: .cfi_def_cfa_offset 56 +; AVX1-NEXT: popq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: popq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: popq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: popq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: popq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: popq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 8 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v8i64: +; AVX2: # %bb.0: +; AVX2-NEXT: pushq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: pushq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: pushq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: pushq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: pushq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: pushq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 56 +; AVX2-NEXT: pushq %rax +; AVX2-NEXT: .cfi_def_cfa_offset 64 +; AVX2-NEXT: .cfi_offset %rbx, -56 +; AVX2-NEXT: .cfi_offset %r12, -48 +; AVX2-NEXT: .cfi_offset %r13, -40 +; AVX2-NEXT: .cfi_offset %r14, -32 +; AVX2-NEXT: .cfi_offset %r15, -24 +; AVX2-NEXT: .cfi_offset %rbp, -16 +; AVX2-NEXT: vmovq %xmm1, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movq %rax, %rcx +; AVX2-NEXT: sarq $63, %rcx +; AVX2-NEXT: movq %rcx, (%rsp) # 8-byte Spill +; AVX2-NEXT: vpextrq $1, %xmm1, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movq %rax, %rcx +; AVX2-NEXT: sarq $63, %rcx +; AVX2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm1 +; AVX2-NEXT: vmovq %xmm1, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movq %rax, %rcx +; AVX2-NEXT: sarq $63, %rcx +; AVX2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: vpextrq $1, %xmm1, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movq %rax, %rcx +; AVX2-NEXT: sarq $63, %rcx +; AVX2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: vmovq %xmm0, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: movq %rax, %rcx +; AVX2-NEXT: sarq $63, %rcx +; AVX2-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: vpextrq $1, %xmm0, %rbp +; AVX2-NEXT: movq %rbp, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %rbp +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vmovq %xmm0, %rbx +; AVX2-NEXT: movq %rbx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %rbx +; AVX2-NEXT: vpextrq $1, %xmm0, %r15 +; AVX2-NEXT: movq %r15, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %r15 +; AVX2-NEXT: vmovq %xmm3, %r9 +; AVX2-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %r9 +; AVX2-NEXT: vpextrq $1, %xmm3, %r10 +; AVX2-NEXT: movq %r10, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %r10 +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm0 +; AVX2-NEXT: vmovq %xmm0, %r12 +; AVX2-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %r12 +; AVX2-NEXT: vpextrq $1, %xmm0, %r13 +; AVX2-NEXT: movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: sarq $63, %r13 +; AVX2-NEXT: vmovq %xmm2, %r14 +; AVX2-NEXT: movq %r14, %rsi +; AVX2-NEXT: sarq $63, %rsi +; AVX2-NEXT: vpextrq $1, %xmm2, %r11 +; AVX2-NEXT: movq %r11, %rdx +; AVX2-NEXT: sarq $63, %rdx +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm0 +; AVX2-NEXT: vmovq %xmm0, %r8 +; AVX2-NEXT: movq %r8, %rdi +; AVX2-NEXT: sarq $63, %rdi +; AVX2-NEXT: vpextrq $1, %xmm0, %rcx +; AVX2-NEXT: movq %rcx, %rax +; AVX2-NEXT: sarq $63, %rax +; AVX2-NEXT: addq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; AVX2-NEXT: adcq %r15, %rax +; AVX2-NEXT: addq %r8, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; AVX2-NEXT: adcq %rbx, %rdi +; AVX2-NEXT: addq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; AVX2-NEXT: adcq %rbp, %rdx +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Reload +; AVX2-NEXT: addq %r14, %r15 +; AVX2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Folded Reload +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload +; AVX2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Folded Reload +; AVX2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r13 # 8-byte Folded Reload +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Reload +; AVX2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; AVX2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Folded Reload +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; AVX2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Folded Reload +; AVX2-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Folded Reload +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; AVX2-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Folded Reload +; AVX2-NEXT: adcq (%rsp), %r9 # 8-byte Folded Reload +; AVX2-NEXT: shldq $63, %rcx, %r9 +; AVX2-NEXT: shldq $63, %r8, %r10 +; AVX2-NEXT: shldq $63, %r11, %r12 +; AVX2-NEXT: shldq $63, %rbx, %r13 +; AVX2-NEXT: shldq $63, %r15, %rsi +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; AVX2-NEXT: shldq $63, %rcx, %rdx +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; AVX2-NEXT: shldq $63, %rcx, %rdi +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; AVX2-NEXT: shldq $63, %rcx, %rax +; AVX2-NEXT: vmovq %rax, %xmm0 +; AVX2-NEXT: vmovq %rdi, %xmm1 +; AVX2-NEXT: vmovq %rdx, %xmm2 +; AVX2-NEXT: vmovq %rsi, %xmm3 +; AVX2-NEXT: vmovq %r13, %xmm4 +; AVX2-NEXT: vmovq %r12, %xmm5 +; AVX2-NEXT: vmovq %r10, %xmm6 +; AVX2-NEXT: vmovq %r9, %xmm7 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm2, %ymm1 +; AVX2-NEXT: addq $8, %rsp +; AVX2-NEXT: .cfi_def_cfa_offset 56 +; AVX2-NEXT: popq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: popq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: popq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: popq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: popq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: popq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 8 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v8i64: +; AVX512: # %bb.0: +; AVX512-NEXT: pushq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: pushq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: pushq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: pushq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: pushq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: pushq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 56 +; AVX512-NEXT: pushq %rax +; AVX512-NEXT: .cfi_def_cfa_offset 64 +; AVX512-NEXT: .cfi_offset %rbx, -56 +; AVX512-NEXT: .cfi_offset %r12, -48 +; AVX512-NEXT: .cfi_offset %r13, -40 +; AVX512-NEXT: .cfi_offset %r14, -32 +; AVX512-NEXT: .cfi_offset %r15, -24 +; AVX512-NEXT: .cfi_offset %rbp, -16 +; AVX512-NEXT: vmovq %xmm0, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: movq %rax, %rcx +; AVX512-NEXT: sarq $63, %rcx +; AVX512-NEXT: movq %rcx, (%rsp) # 8-byte Spill +; AVX512-NEXT: vpextrq $1, %xmm0, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: movq %rax, %rcx +; AVX512-NEXT: sarq $63, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX512-NEXT: vmovq %xmm2, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: movq %rax, %rcx +; AVX512-NEXT: sarq $63, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: vpextrq $1, %xmm2, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: movq %rax, %rcx +; AVX512-NEXT: sarq $63, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm0 +; AVX512-NEXT: vmovq %xmm0, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: movq %rax, %rcx +; AVX512-NEXT: sarq $63, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: vpextrq $1, %xmm0, %r13 +; AVX512-NEXT: movq %r13, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r13 +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX512-NEXT: vmovq %xmm0, %r14 +; AVX512-NEXT: movq %r14, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r14 +; AVX512-NEXT: vpextrq $1, %xmm0, %r15 +; AVX512-NEXT: movq %r15, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r15 +; AVX512-NEXT: vmovq %xmm1, %r9 +; AVX512-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r9 +; AVX512-NEXT: vpextrq $1, %xmm1, %r11 +; AVX512-NEXT: movq %r11, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r11 +; AVX512-NEXT: vextracti128 $1, %ymm1, %xmm0 +; AVX512-NEXT: vmovq %xmm0, %r12 +; AVX512-NEXT: movq %r12, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %r12 +; AVX512-NEXT: vpextrq $1, %xmm0, %rbp +; AVX512-NEXT: movq %rbp, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: sarq $63, %rbp +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm0 +; AVX512-NEXT: vmovq %xmm0, %rbx +; AVX512-NEXT: movq %rbx, %rsi +; AVX512-NEXT: sarq $63, %rsi +; AVX512-NEXT: vpextrq $1, %xmm0, %r10 +; AVX512-NEXT: movq %r10, %rdx +; AVX512-NEXT: sarq $63, %rdx +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX512-NEXT: vmovq %xmm0, %r8 +; AVX512-NEXT: movq %r8, %rdi +; AVX512-NEXT: sarq $63, %rdi +; AVX512-NEXT: vpextrq $1, %xmm0, %rcx +; AVX512-NEXT: movq %rcx, %rax +; AVX512-NEXT: sarq $63, %rax +; AVX512-NEXT: addq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; AVX512-NEXT: adcq %r15, %rax +; AVX512-NEXT: addq %r8, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Folded Spill +; AVX512-NEXT: adcq %r14, %rdi +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r15 # 8-byte Reload +; AVX512-NEXT: addq %r10, %r15 +; AVX512-NEXT: adcq %r13, %rdx +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r14 # 8-byte Reload +; AVX512-NEXT: addq %rbx, %r14 +; AVX512-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Folded Reload +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload +; AVX512-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Folded Reload +; AVX512-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %rbp # 8-byte Folded Reload +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload +; AVX512-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Folded Reload +; AVX512-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r12 # 8-byte Folded Reload +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Reload +; AVX512-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r8 # 8-byte Folded Reload +; AVX512-NEXT: adcq {{[-0-9]+}}(%r{{[sb]}}p), %r11 # 8-byte Folded Reload +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; AVX512-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Folded Reload +; AVX512-NEXT: adcq (%rsp), %r9 # 8-byte Folded Reload +; AVX512-NEXT: shldq $63, %rcx, %r9 +; AVX512-NEXT: shldq $63, %r8, %r11 +; AVX512-NEXT: shldq $63, %r10, %r12 +; AVX512-NEXT: shldq $63, %rbx, %rbp +; AVX512-NEXT: shldq $63, %r14, %rsi +; AVX512-NEXT: shldq $63, %r15, %rdx +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; AVX512-NEXT: shldq $63, %rcx, %rdi +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; AVX512-NEXT: shldq $63, %rcx, %rax +; AVX512-NEXT: vmovq %rax, %xmm0 +; AVX512-NEXT: vmovq %rdi, %xmm1 +; AVX512-NEXT: vmovq %rdx, %xmm2 +; AVX512-NEXT: vmovq %rsi, %xmm3 +; AVX512-NEXT: vmovq %rbp, %xmm4 +; AVX512-NEXT: vmovq %r12, %xmm5 +; AVX512-NEXT: vmovq %r11, %xmm6 +; AVX512-NEXT: vmovq %r9, %xmm7 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX512-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX512-NEXT: vinserti128 $1, %xmm1, %ymm2, %ymm1 +; AVX512-NEXT: vinserti64x4 $1, %ymm0, %zmm1, %zmm0 +; AVX512-NEXT: addq $8, %rsp +; AVX512-NEXT: .cfi_def_cfa_offset 56 +; AVX512-NEXT: popq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: popq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: popq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: popq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: popq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: popq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 8 +; AVX512-NEXT: retq + %x0 = sext <8 x i64> %a0 to <8 x i128> + %x1 = sext <8 x i64> %a1 to <8 x i128> + %sum = add <8 x i128> %x0, %x1 + %shift = ashr <8 x i128> %sum, <i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1> + %res = trunc <8 x i128> %shift to <8 x i64> + ret <8 x i64> %res +} + diff --git a/llvm/test/CodeGen/X86/avgflooru.ll b/llvm/test/CodeGen/X86/avgflooru.ll new file mode 100644 index 000000000000..e07c1f55991e --- /dev/null +++ b/llvm/test/CodeGen/X86/avgflooru.ll @@ -0,0 +1,2629 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE2 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE4 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1 +; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2 +; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=AVX,AVX512 + +; +; 128-bit vectors +; + +define <16 x i8> @test_fixed_v16i8(<16 x i8> %a0, <16 x i8> %a1) { +; SSE-LABEL: test_fixed_v16i8: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: pand %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm0 +; SSE-NEXT: psrlw $1, %xmm0 +; SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; SSE-NEXT: paddb %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v16i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 +; AVX1-NEXT: vpaddb %xmm0, %xmm2, %xmm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v16i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX2-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX2-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 +; AVX2-NEXT: vpaddb %xmm0, %xmm2, %xmm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v16i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX512-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX512-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX512-NEXT: vpandd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %xmm0 +; AVX512-NEXT: vpaddb %xmm0, %xmm2, %xmm0 +; AVX512-NEXT: retq + %and = and <16 x i8> %a0, %a1 + %xor = xor <16 x i8> %a0, %a1 + %shift = lshr <16 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = add <16 x i8> %and, %shift + ret <16 x i8> %res +} + +define <16 x i8> @test_ext_v16i8(<16 x i8> %a0, <16 x i8> %a1) { +; SSE2-LABEL: test_ext_v16i8: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm2, %xmm2 +; SSE2-NEXT: movdqa %xmm0, %xmm3 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm2[8],xmm3[9],xmm2[9],xmm3[10],xmm2[10],xmm3[11],xmm2[11],xmm3[12],xmm2[12],xmm3[13],xmm2[13],xmm3[14],xmm2[14],xmm3[15],xmm2[15] +; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3],xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7] +; SSE2-NEXT: movdqa %xmm1, %xmm4 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm2[8],xmm4[9],xmm2[9],xmm4[10],xmm2[10],xmm4[11],xmm2[11],xmm4[12],xmm2[12],xmm4[13],xmm2[13],xmm4[14],xmm2[14],xmm4[15],xmm2[15] +; SSE2-NEXT: paddw %xmm3, %xmm4 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1],xmm1[2],xmm2[2],xmm1[3],xmm2[3],xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7] +; SSE2-NEXT: paddw %xmm1, %xmm0 +; SSE2-NEXT: psrlw $1, %xmm4 +; SSE2-NEXT: psrlw $1, %xmm0 +; SSE2-NEXT: packuswb %xmm4, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v16i8: +; SSE4: # %bb.0: +; SSE4-NEXT: pxor %xmm3, %xmm3 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm4 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm0 = xmm0[8],xmm3[8],xmm0[9],xmm3[9],xmm0[10],xmm3[10],xmm0[11],xmm3[11],xmm0[12],xmm3[12],xmm0[13],xmm3[13],xmm0[14],xmm3[14],xmm0[15],xmm3[15] +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm2 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm1 = xmm1[8],xmm3[8],xmm1[9],xmm3[9],xmm1[10],xmm3[10],xmm1[11],xmm3[11],xmm1[12],xmm3[12],xmm1[13],xmm3[13],xmm1[14],xmm3[14],xmm1[15],xmm3[15] +; SSE4-NEXT: paddw %xmm0, %xmm1 +; SSE4-NEXT: paddw %xmm4, %xmm2 +; SSE4-NEXT: psrlw $1, %xmm1 +; SSE4-NEXT: psrlw $1, %xmm2 +; SSE4-NEXT: packuswb %xmm1, %xmm2 +; SSE4-NEXT: movdqa %xmm2, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v16i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm3 = xmm0[8],xmm2[8],xmm0[9],xmm2[9],xmm0[10],xmm2[10],xmm0[11],xmm2[11],xmm0[12],xmm2[12],xmm0[13],xmm2[13],xmm0[14],xmm2[14],xmm0[15],xmm2[15] +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm2 = xmm1[8],xmm2[8],xmm1[9],xmm2[9],xmm1[10],xmm2[10],xmm1[11],xmm2[11],xmm1[12],xmm2[12],xmm1[13],xmm2[13],xmm1[14],xmm2[14],xmm1[15],xmm2[15] +; AVX1-NEXT: vpaddw %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; AVX1-NEXT: vpaddw %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm2, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v16i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero,xmm1[8],zero,xmm1[9],zero,xmm1[10],zero,xmm1[11],zero,xmm1[12],zero,xmm1[13],zero,xmm1[14],zero,xmm1[15],zero +; AVX2-NEXT: vpaddw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 +; AVX2-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 +; AVX2-NEXT: vzeroupper +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v16i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero +; AVX512-NEXT: vpmovzxbw {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero,xmm1[8],zero,xmm1[9],zero,xmm1[10],zero,xmm1[11],zero,xmm1[12],zero,xmm1[13],zero,xmm1[14],zero,xmm1[15],zero +; AVX512-NEXT: vpaddw %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX512-NEXT: vpmovwb %ymm0, %xmm0 +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %x0 = zext <16 x i8> %a0 to <16 x i16> + %x1 = zext <16 x i8> %a1 to <16 x i16> + %sum = add <16 x i16> %x0, %x1 + %shift = lshr <16 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <16 x i16> %shift to <16 x i8> + ret <16 x i8> %res +} + +define <8 x i16> @test_fixed_v8i16(<8 x i16> %a0, <8 x i16> %a1) { +; SSE-LABEL: test_fixed_v8i16: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: pand %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm0 +; SSE-NEXT: psrlw $1, %xmm0 +; SSE-NEXT: paddw %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_fixed_v8i16: +; AVX: # %bb.0: +; AVX-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX-NEXT: vpaddw %xmm0, %xmm2, %xmm0 +; AVX-NEXT: retq + %and = and <8 x i16> %a0, %a1 + %xor = xor <8 x i16> %a1, %a0 + %shift = lshr <8 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = add <8 x i16> %and, %shift + ret <8 x i16> %res +} + +define <8 x i16> @test_ext_v8i16(<8 x i16> %a0, <8 x i16> %a1) { +; SSE2-LABEL: test_ext_v8i16: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm2, %xmm2 +; SSE2-NEXT: movdqa %xmm0, %xmm3 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4],xmm2[4],xmm3[5],xmm2[5],xmm3[6],xmm2[6],xmm3[7],xmm2[7] +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] +; SSE2-NEXT: movdqa %xmm1, %xmm4 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm4 = xmm4[4],xmm2[4],xmm4[5],xmm2[5],xmm4[6],xmm2[6],xmm4[7],xmm2[7] +; SSE2-NEXT: paddd %xmm3, %xmm4 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1],xmm1[2],xmm2[2],xmm1[3],xmm2[3] +; SSE2-NEXT: paddd %xmm1, %xmm0 +; SSE2-NEXT: pslld $15, %xmm4 +; SSE2-NEXT: psrad $16, %xmm4 +; SSE2-NEXT: pslld $15, %xmm0 +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: packssdw %xmm4, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v8i16: +; SSE4: # %bb.0: +; SSE4-NEXT: pxor %xmm3, %xmm3 +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm4 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm0 = xmm0[4],xmm3[4],xmm0[5],xmm3[5],xmm0[6],xmm3[6],xmm0[7],xmm3[7] +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm2 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm3[4],xmm1[5],xmm3[5],xmm1[6],xmm3[6],xmm1[7],xmm3[7] +; SSE4-NEXT: paddd %xmm0, %xmm1 +; SSE4-NEXT: paddd %xmm4, %xmm2 +; SSE4-NEXT: psrld $1, %xmm1 +; SSE4-NEXT: psrld $1, %xmm2 +; SSE4-NEXT: packusdw %xmm1, %xmm2 +; SSE4-NEXT: movdqa %xmm2, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v8i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm3 = xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7] +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm2 = xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7] +; AVX1-NEXT: vpaddd %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm2, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v8i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; AVX2-NEXT: vpaddd %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 +; AVX2-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 +; AVX2-NEXT: vzeroupper +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v8i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero +; AVX512-NEXT: vpmovzxwd {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; AVX512-NEXT: vpaddd %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX512-NEXT: vpmovdw %ymm0, %xmm0 +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %x0 = zext <8 x i16> %a0 to <8 x i32> + %x1 = zext <8 x i16> %a1 to <8 x i32> + %sum = add <8 x i32> %x0, %x1 + %shift = lshr <8 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <8 x i32> %shift to <8 x i16> + ret <8 x i16> %res +} + +define <4 x i32> @test_fixed_v4i32(<4 x i32> %a0, <4 x i32> %a1) { +; SSE-LABEL: test_fixed_v4i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: pand %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm0 +; SSE-NEXT: psrld $1, %xmm0 +; SSE-NEXT: paddd %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_fixed_v4i32: +; AVX: # %bb.0: +; AVX-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX-NEXT: vpaddd %xmm0, %xmm2, %xmm0 +; AVX-NEXT: retq + %and = and <4 x i32> %a0, %a1 + %xor = xor <4 x i32> %a1, %a0 + %shift = lshr <4 x i32> %xor, <i32 1, i32 1, i32 1, i32 1> + %res = add <4 x i32> %and, %shift + ret <4 x i32> %res +} + +define <4 x i32> @test_ext_v4i32(<4 x i32> %a0, <4 x i32> %a1) { +; SSE2-LABEL: test_ext_v4i32: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm2, %xmm2 +; SSE2-NEXT: movdqa %xmm0, %xmm3 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm3 = xmm3[2],xmm2[2],xmm3[3],xmm2[3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1] +; SSE2-NEXT: movdqa %xmm1, %xmm4 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm4 = xmm4[2],xmm2[2],xmm4[3],xmm2[3] +; SSE2-NEXT: paddq %xmm3, %xmm4 +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1] +; SSE2-NEXT: paddq %xmm1, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm4 +; SSE2-NEXT: psrlq $1, %xmm0 +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm4[0,2] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v4i32: +; SSE4: # %bb.0: +; SSE4-NEXT: pxor %xmm3, %xmm3 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm4 = xmm0[0],zero,xmm0[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm0 = xmm0[2],xmm3[2],xmm0[3],xmm3[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm2 = xmm1[0],zero,xmm1[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm1 = xmm1[2],xmm3[2],xmm1[3],xmm3[3] +; SSE4-NEXT: paddq %xmm0, %xmm1 +; SSE4-NEXT: paddq %xmm4, %xmm2 +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm1[0,2] +; SSE4-NEXT: movaps %xmm2, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v4i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm3 = xmm0[2],xmm2[2],xmm0[3],xmm2[3] +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm2 = xmm1[2],xmm2[2],xmm1[3],xmm2[3] +; AVX1-NEXT: vpaddq %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero +; AVX1-NEXT: vpaddq %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm2, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v4i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 +; AVX2-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] +; AVX2-NEXT: vzeroupper +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v4i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovzxdq {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX512-NEXT: vpmovzxdq {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX512-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX512-NEXT: vpmovqd %ymm0, %xmm0 +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %x0 = zext <4 x i32> %a0 to <4 x i64> + %x1 = zext <4 x i32> %a1 to <4 x i64> + %sum = add <4 x i64> %x0, %x1 + %shift = lshr <4 x i64> %sum, <i64 1, i64 1, i64 1, i64 1> + %res = trunc <4 x i64> %shift to <4 x i32> + ret <4 x i32> %res +} + +define <2 x i64> @test_fixed_v2i64(<2 x i64> %a0, <2 x i64> %a1) { +; SSE-LABEL: test_fixed_v2i64: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm0, %xmm2 +; SSE-NEXT: pand %xmm1, %xmm2 +; SSE-NEXT: pxor %xmm1, %xmm0 +; SSE-NEXT: psrlq $1, %xmm0 +; SSE-NEXT: paddq %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: test_fixed_v2i64: +; AVX: # %bb.0: +; AVX-NEXT: vpand %xmm1, %xmm0, %xmm2 +; AVX-NEXT: vpxor %xmm0, %xmm1, %xmm0 +; AVX-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX-NEXT: vpaddq %xmm0, %xmm2, %xmm0 +; AVX-NEXT: retq + %and = and <2 x i64> %a0, %a1 + %xor = xor <2 x i64> %a1, %a0 + %shift = lshr <2 x i64> %xor, <i64 1, i64 1> + %res = add <2 x i64> %and, %shift + ret <2 x i64> %res +} + +define <2 x i64> @test_ext_v2i64(<2 x i64> %a0, <2 x i64> %a1) { +; SSE2-LABEL: test_ext_v2i64: +; SSE2: # %bb.0: +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] +; SSE2-NEXT: movq %xmm2, %rax +; SSE2-NEXT: movq %xmm0, %rcx +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rdx +; SSE2-NEXT: movq %xmm1, %rsi +; SSE2-NEXT: xorl %edi, %edi +; SSE2-NEXT: addq %rcx, %rsi +; SSE2-NEXT: setb %dil +; SSE2-NEXT: xorl %ecx, %ecx +; SSE2-NEXT: addq %rax, %rdx +; SSE2-NEXT: setb %cl +; SSE2-NEXT: shldq $63, %rdx, %rcx +; SSE2-NEXT: shldq $63, %rsi, %rdi +; SSE2-NEXT: movq %rdi, %xmm0 +; SSE2-NEXT: movq %rcx, %xmm1 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v2i64: +; SSE4: # %bb.0: +; SSE4-NEXT: movq %xmm0, %rax +; SSE4-NEXT: pextrq $1, %xmm0, %rcx +; SSE4-NEXT: movq %xmm1, %rdx +; SSE4-NEXT: pextrq $1, %xmm1, %rsi +; SSE4-NEXT: xorl %edi, %edi +; SSE4-NEXT: addq %rcx, %rsi +; SSE4-NEXT: setb %dil +; SSE4-NEXT: xorl %ecx, %ecx +; SSE4-NEXT: addq %rax, %rdx +; SSE4-NEXT: setb %cl +; SSE4-NEXT: shldq $63, %rdx, %rcx +; SSE4-NEXT: shldq $63, %rsi, %rdi +; SSE4-NEXT: movq %rdi, %xmm1 +; SSE4-NEXT: movq %rcx, %xmm0 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v2i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vmovq %xmm0, %rax +; AVX1-NEXT: vpextrq $1, %xmm0, %rcx +; AVX1-NEXT: vmovq %xmm1, %rdx +; AVX1-NEXT: vpextrq $1, %xmm1, %rsi +; AVX1-NEXT: xorl %edi, %edi +; AVX1-NEXT: addq %rcx, %rsi +; AVX1-NEXT: setb %dil +; AVX1-NEXT: xorl %ecx, %ecx +; AVX1-NEXT: addq %rax, %rdx +; AVX1-NEXT: setb %cl +; AVX1-NEXT: shldq $63, %rdx, %rcx +; AVX1-NEXT: shldq $63, %rsi, %rdi +; AVX1-NEXT: vmovq %rdi, %xmm0 +; AVX1-NEXT: vmovq %rcx, %xmm1 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v2i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vmovq %xmm0, %rax +; AVX2-NEXT: vpextrq $1, %xmm0, %rcx +; AVX2-NEXT: vmovq %xmm1, %rdx +; AVX2-NEXT: vpextrq $1, %xmm1, %rsi +; AVX2-NEXT: xorl %edi, %edi +; AVX2-NEXT: addq %rcx, %rsi +; AVX2-NEXT: setb %dil +; AVX2-NEXT: xorl %ecx, %ecx +; AVX2-NEXT: addq %rax, %rdx +; AVX2-NEXT: setb %cl +; AVX2-NEXT: shldq $63, %rdx, %rcx +; AVX2-NEXT: shldq $63, %rsi, %rdi +; AVX2-NEXT: vmovq %rdi, %xmm0 +; AVX2-NEXT: vmovq %rcx, %xmm1 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v2i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vmovq %xmm0, %rax +; AVX512-NEXT: vpextrq $1, %xmm0, %rcx +; AVX512-NEXT: vpextrq $1, %xmm1, %rdx +; AVX512-NEXT: vmovq %xmm1, %rsi +; AVX512-NEXT: xorl %edi, %edi +; AVX512-NEXT: addq %rcx, %rdx +; AVX512-NEXT: setb %dil +; AVX512-NEXT: xorl %ecx, %ecx +; AVX512-NEXT: addq %rax, %rsi +; AVX512-NEXT: setb %cl +; AVX512-NEXT: shldq $63, %rsi, %rcx +; AVX512-NEXT: shldq $63, %rdx, %rdi +; AVX512-NEXT: vmovq %rdi, %xmm0 +; AVX512-NEXT: vmovq %rcx, %xmm1 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX512-NEXT: retq + %x0 = zext <2 x i64> %a0 to <2 x i128> + %x1 = zext <2 x i64> %a1 to <2 x i128> + %sum = add <2 x i128> %x0, %x1 + %shift = lshr <2 x i128> %sum, <i128 1, i128 1> + %res = trunc <2 x i128> %shift to <2 x i64> + ret <2 x i64> %res +} + +; +; 256-bit vectors +; + +define <32 x i8> @test_fixed_v32i8(<32 x i8> %a0, <32 x i8> %a1) { +; SSE-LABEL: test_fixed_v32i8: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: pand %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: pand %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm0 +; SSE-NEXT: pxor %xmm3, %xmm1 +; SSE-NEXT: psrlw $1, %xmm1 +; SSE-NEXT: movdqa {{.*#+}} xmm2 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; SSE-NEXT: pand %xmm2, %xmm1 +; SSE-NEXT: paddb %xmm4, %xmm1 +; SSE-NEXT: psrlw $1, %xmm0 +; SSE-NEXT: pand %xmm2, %xmm0 +; SSE-NEXT: paddb %xmm5, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v32i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm1, %ymm0, %ymm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm1 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; AVX1-NEXT: vpand %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpaddb %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpaddb %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v32i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 +; AVX2-NEXT: vpaddb %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v32i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX512-NEXT: vpandd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm0, %ymm0 +; AVX512-NEXT: vpaddb %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %and = and <32 x i8> %a0, %a1 + %xor = xor <32 x i8> %a0, %a1 + %shift = lshr <32 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = add <32 x i8> %and, %shift + ret <32 x i8> %res +} + +define <32 x i8> @test_ext_v32i8(<32 x i8> %a0, <32 x i8> %a1) { +; SSE2-LABEL: test_ext_v32i8: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm4, %xmm4 +; SSE2-NEXT: movdqa %xmm1, %xmm5 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm5 = xmm5[8],xmm4[8],xmm5[9],xmm4[9],xmm5[10],xmm4[10],xmm5[11],xmm4[11],xmm5[12],xmm4[12],xmm5[13],xmm4[13],xmm5[14],xmm4[14],xmm5[15],xmm4[15] +; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm4[0],xmm1[1],xmm4[1],xmm1[2],xmm4[2],xmm1[3],xmm4[3],xmm1[4],xmm4[4],xmm1[5],xmm4[5],xmm1[6],xmm4[6],xmm1[7],xmm4[7] +; SSE2-NEXT: movdqa %xmm0, %xmm6 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm6 = xmm6[8],xmm4[8],xmm6[9],xmm4[9],xmm6[10],xmm4[10],xmm6[11],xmm4[11],xmm6[12],xmm4[12],xmm6[13],xmm4[13],xmm6[14],xmm4[14],xmm6[15],xmm4[15] +; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1],xmm0[2],xmm4[2],xmm0[3],xmm4[3],xmm0[4],xmm4[4],xmm0[5],xmm4[5],xmm0[6],xmm4[6],xmm0[7],xmm4[7] +; SSE2-NEXT: movdqa %xmm3, %xmm7 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm7 = xmm7[8],xmm4[8],xmm7[9],xmm4[9],xmm7[10],xmm4[10],xmm7[11],xmm4[11],xmm7[12],xmm4[12],xmm7[13],xmm4[13],xmm7[14],xmm4[14],xmm7[15],xmm4[15] +; SSE2-NEXT: paddw %xmm5, %xmm7 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1],xmm3[2],xmm4[2],xmm3[3],xmm4[3],xmm3[4],xmm4[4],xmm3[5],xmm4[5],xmm3[6],xmm4[6],xmm3[7],xmm4[7] +; SSE2-NEXT: paddw %xmm3, %xmm1 +; SSE2-NEXT: movdqa %xmm2, %xmm3 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm4[8],xmm3[9],xmm4[9],xmm3[10],xmm4[10],xmm3[11],xmm4[11],xmm3[12],xmm4[12],xmm3[13],xmm4[13],xmm3[14],xmm4[14],xmm3[15],xmm4[15] +; SSE2-NEXT: paddw %xmm6, %xmm3 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3],xmm2[4],xmm4[4],xmm2[5],xmm4[5],xmm2[6],xmm4[6],xmm2[7],xmm4[7] +; SSE2-NEXT: paddw %xmm2, %xmm0 +; SSE2-NEXT: psrlw $1, %xmm7 +; SSE2-NEXT: psrlw $1, %xmm1 +; SSE2-NEXT: packuswb %xmm7, %xmm1 +; SSE2-NEXT: psrlw $1, %xmm3 +; SSE2-NEXT: psrlw $1, %xmm0 +; SSE2-NEXT: packuswb %xmm3, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v32i8: +; SSE4: # %bb.0: +; SSE4-NEXT: pxor %xmm5, %xmm5 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm6 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm1 = xmm1[8],xmm5[8],xmm1[9],xmm5[9],xmm1[10],xmm5[10],xmm1[11],xmm5[11],xmm1[12],xmm5[12],xmm1[13],xmm5[13],xmm1[14],xmm5[14],xmm1[15],xmm5[15] +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm7 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm0 = xmm0[8],xmm5[8],xmm0[9],xmm5[9],xmm0[10],xmm5[10],xmm0[11],xmm5[11],xmm0[12],xmm5[12],xmm0[13],xmm5[13],xmm0[14],xmm5[14],xmm0[15],xmm5[15] +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm4 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero,xmm3[4],zero,xmm3[5],zero,xmm3[6],zero,xmm3[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm5[8],xmm3[9],xmm5[9],xmm3[10],xmm5[10],xmm3[11],xmm5[11],xmm3[12],xmm5[12],xmm3[13],xmm5[13],xmm3[14],xmm5[14],xmm3[15],xmm5[15] +; SSE4-NEXT: paddw %xmm1, %xmm3 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm1 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm2 = xmm2[8],xmm5[8],xmm2[9],xmm5[9],xmm2[10],xmm5[10],xmm2[11],xmm5[11],xmm2[12],xmm5[12],xmm2[13],xmm5[13],xmm2[14],xmm5[14],xmm2[15],xmm5[15] +; SSE4-NEXT: paddw %xmm0, %xmm2 +; SSE4-NEXT: paddw %xmm6, %xmm4 +; SSE4-NEXT: paddw %xmm7, %xmm1 +; SSE4-NEXT: psrlw $1, %xmm3 +; SSE4-NEXT: psrlw $1, %xmm2 +; SSE4-NEXT: psrlw $1, %xmm4 +; SSE4-NEXT: packuswb %xmm3, %xmm4 +; SSE4-NEXT: psrlw $1, %xmm1 +; SSE4-NEXT: packuswb %xmm2, %xmm1 +; SSE4-NEXT: movdqa %xmm1, %xmm0 +; SSE4-NEXT: movdqa %xmm4, %xmm1 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v32i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm3 = xmm0[8],xmm2[8],xmm0[9],xmm2[9],xmm0[10],xmm2[10],xmm0[11],xmm2[11],xmm0[12],xmm2[12],xmm0[13],xmm2[13],xmm0[14],xmm2[14],xmm0[15],xmm2[15] +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm4 +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm5 = xmm4[8],xmm2[8],xmm4[9],xmm2[9],xmm4[10],xmm2[10],xmm4[11],xmm2[11],xmm4[12],xmm2[12],xmm4[13],xmm2[13],xmm4[14],xmm2[14],xmm4[15],xmm2[15] +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm4 = xmm4[0],zero,xmm4[1],zero,xmm4[2],zero,xmm4[3],zero,xmm4[4],zero,xmm4[5],zero,xmm4[6],zero,xmm4[7],zero +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm6 = xmm1[8],xmm2[8],xmm1[9],xmm2[9],xmm1[10],xmm2[10],xmm1[11],xmm2[11],xmm1[12],xmm2[12],xmm1[13],xmm2[13],xmm1[14],xmm2[14],xmm1[15],xmm2[15] +; AVX1-NEXT: vpaddw %xmm6, %xmm3, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm6 +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm2 = xmm6[8],xmm2[8],xmm6[9],xmm2[9],xmm6[10],xmm2[10],xmm6[11],xmm2[11],xmm6[12],xmm2[12],xmm6[13],xmm2[13],xmm6[14],xmm2[14],xmm6[15],xmm2[15] +; AVX1-NEXT: vpaddw %xmm2, %xmm5, %xmm2 +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; AVX1-NEXT: vpaddw %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm1 = xmm6[0],zero,xmm6[1],zero,xmm6[2],zero,xmm6[3],zero,xmm6[4],zero,xmm6[5],zero,xmm6[6],zero,xmm6[7],zero +; AVX1-NEXT: vpaddw %xmm1, %xmm4, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm3, %xmm3 +; AVX1-NEXT: vpsrlw $1, %xmm2, %xmm2 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpackuswb %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpackuswb %xmm2, %xmm1, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v32i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero,xmm2[8],zero,xmm2[9],zero,xmm2[10],zero,xmm2[11],zero,xmm2[12],zero,xmm2[13],zero,xmm2[14],zero,xmm2[15],zero +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm3 +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm3 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero,xmm3[4],zero,xmm3[5],zero,xmm3[6],zero,xmm3[7],zero,xmm3[8],zero,xmm3[9],zero,xmm3[10],zero,xmm3[11],zero,xmm3[12],zero,xmm3[13],zero,xmm3[14],zero,xmm3[15],zero +; AVX2-NEXT: vpaddw %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero,xmm1[8],zero,xmm1[9],zero,xmm1[10],zero,xmm1[11],zero,xmm1[12],zero,xmm1[13],zero,xmm1[14],zero,xmm1[15],zero +; AVX2-NEXT: vpaddw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm2, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpackuswb %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v32i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovzxbw {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero,ymm0[16],zero,ymm0[17],zero,ymm0[18],zero,ymm0[19],zero,ymm0[20],zero,ymm0[21],zero,ymm0[22],zero,ymm0[23],zero,ymm0[24],zero,ymm0[25],zero,ymm0[26],zero,ymm0[27],zero,ymm0[28],zero,ymm0[29],zero,ymm0[30],zero,ymm0[31],zero +; AVX512-NEXT: vpmovzxbw {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero,ymm1[16],zero,ymm1[17],zero,ymm1[18],zero,ymm1[19],zero,ymm1[20],zero,ymm1[21],zero,ymm1[22],zero,ymm1[23],zero,ymm1[24],zero,ymm1[25],zero,ymm1[26],zero,ymm1[27],zero,ymm1[28],zero,ymm1[29],zero,ymm1[30],zero,ymm1[31],zero +; AVX512-NEXT: vpaddw %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovwb %zmm0, %ymm0 +; AVX512-NEXT: retq + %x0 = zext <32 x i8> %a0 to <32 x i16> + %x1 = zext <32 x i8> %a1 to <32 x i16> + %sum = add <32 x i16> %x0, %x1 + %shift = lshr <32 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <32 x i16> %shift to <32 x i8> + ret <32 x i8> %res +} + +define <16 x i16> @test_fixed_v16i16(<16 x i16> %a0, <16 x i16> %a1) { +; SSE-LABEL: test_fixed_v16i16: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: pand %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: pand %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm0 +; SSE-NEXT: pxor %xmm3, %xmm1 +; SSE-NEXT: psrlw $1, %xmm1 +; SSE-NEXT: paddw %xmm4, %xmm1 +; SSE-NEXT: psrlw $1, %xmm0 +; SSE-NEXT: paddw %xmm5, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v16i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpaddw %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpaddw %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v16i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpaddw %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v16i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX512-NEXT: vpaddw %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %and = and <16 x i16> %a0, %a1 + %xor = xor <16 x i16> %a1, %a0 + %shift = lshr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = add <16 x i16> %and, %shift + ret <16 x i16> %res +} + +define <16 x i16> @test_ext_v16i16(<16 x i16> %a0, <16 x i16> %a1) { +; SSE2-LABEL: test_ext_v16i16: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm4, %xmm4 +; SSE2-NEXT: movdqa %xmm0, %xmm5 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm5 = xmm5[4],xmm4[4],xmm5[5],xmm4[5],xmm5[6],xmm4[6],xmm5[7],xmm4[7] +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1],xmm0[2],xmm4[2],xmm0[3],xmm4[3] +; SSE2-NEXT: movdqa %xmm1, %xmm6 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm6 = xmm6[4],xmm4[4],xmm6[5],xmm4[5],xmm6[6],xmm4[6],xmm6[7],xmm4[7] +; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm4[0],xmm1[1],xmm4[1],xmm1[2],xmm4[2],xmm1[3],xmm4[3] +; SSE2-NEXT: movdqa %xmm2, %xmm7 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm7 = xmm7[4],xmm4[4],xmm7[5],xmm4[5],xmm7[6],xmm4[6],xmm7[7],xmm4[7] +; SSE2-NEXT: paddd %xmm5, %xmm7 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3] +; SSE2-NEXT: paddd %xmm2, %xmm0 +; SSE2-NEXT: movdqa %xmm3, %xmm2 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm2 = xmm2[4],xmm4[4],xmm2[5],xmm4[5],xmm2[6],xmm4[6],xmm2[7],xmm4[7] +; SSE2-NEXT: paddd %xmm6, %xmm2 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1],xmm3[2],xmm4[2],xmm3[3],xmm4[3] +; SSE2-NEXT: paddd %xmm3, %xmm1 +; SSE2-NEXT: pslld $15, %xmm7 +; SSE2-NEXT: psrad $16, %xmm7 +; SSE2-NEXT: pslld $15, %xmm0 +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: packssdw %xmm7, %xmm0 +; SSE2-NEXT: pslld $15, %xmm2 +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: pslld $15, %xmm1 +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: packssdw %xmm2, %xmm1 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v16i16: +; SSE4: # %bb.0: +; SSE4-NEXT: pxor %xmm5, %xmm5 +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm6 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm5[4],xmm1[5],xmm5[5],xmm1[6],xmm5[6],xmm1[7],xmm5[7] +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm7 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm0 = xmm0[4],xmm5[4],xmm0[5],xmm5[5],xmm0[6],xmm5[6],xmm0[7],xmm5[7] +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm4 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4],xmm5[4],xmm3[5],xmm5[5],xmm3[6],xmm5[6],xmm3[7],xmm5[7] +; SSE4-NEXT: paddd %xmm1, %xmm3 +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm1 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm2 = xmm2[4],xmm5[4],xmm2[5],xmm5[5],xmm2[6],xmm5[6],xmm2[7],xmm5[7] +; SSE4-NEXT: paddd %xmm0, %xmm2 +; SSE4-NEXT: paddd %xmm6, %xmm4 +; SSE4-NEXT: paddd %xmm7, %xmm1 +; SSE4-NEXT: psrld $1, %xmm3 +; SSE4-NEXT: psrld $1, %xmm2 +; SSE4-NEXT: psrld $1, %xmm4 +; SSE4-NEXT: packusdw %xmm3, %xmm4 +; SSE4-NEXT: psrld $1, %xmm1 +; SSE4-NEXT: packusdw %xmm2, %xmm1 +; SSE4-NEXT: movdqa %xmm1, %xmm0 +; SSE4-NEXT: movdqa %xmm4, %xmm1 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v16i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm3 = xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7] +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm4 +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm5 = xmm4[4],xmm2[4],xmm4[5],xmm2[5],xmm4[6],xmm2[6],xmm4[7],xmm2[7] +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm4 = xmm4[0],zero,xmm4[1],zero,xmm4[2],zero,xmm4[3],zero +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm6 = xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7] +; AVX1-NEXT: vpaddd %xmm6, %xmm3, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm6 +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm2 = xmm6[4],xmm2[4],xmm6[5],xmm2[5],xmm6[6],xmm2[6],xmm6[7],xmm2[7] +; AVX1-NEXT: vpaddd %xmm2, %xmm5, %xmm2 +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm1 = xmm6[0],zero,xmm6[1],zero,xmm6[2],zero,xmm6[3],zero +; AVX1-NEXT: vpaddd %xmm1, %xmm4, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm3, %xmm3 +; AVX1-NEXT: vpsrld $1, %xmm2, %xmm2 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vpackusdw %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm1, %xmm1 +; AVX1-NEXT: vpackusdw %xmm2, %xmm1, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v16i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm3 +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm3 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero,xmm3[4],zero,xmm3[5],zero,xmm3[6],zero,xmm3[7],zero +; AVX2-NEXT: vpaddd %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; AVX2-NEXT: vpaddd %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm2, %ymm1 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpackusdw %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v16i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero +; AVX512-NEXT: vpmovzxwd {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero +; AVX512-NEXT: vpaddd %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrld $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovdw %zmm0, %ymm0 +; AVX512-NEXT: retq + %x0 = zext <16 x i16> %a0 to <16 x i32> + %x1 = zext <16 x i16> %a1 to <16 x i32> + %sum = add <16 x i32> %x0, %x1 + %shift = lshr <16 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <16 x i32> %shift to <16 x i16> + ret <16 x i16> %res +} + +define <8 x i32> @test_fixed_v8i32(<8 x i32> %a0, <8 x i32> %a1) { +; SSE-LABEL: test_fixed_v8i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: pand %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: pand %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm0 +; SSE-NEXT: pxor %xmm3, %xmm1 +; SSE-NEXT: psrld $1, %xmm1 +; SSE-NEXT: paddd %xmm4, %xmm1 +; SSE-NEXT: psrld $1, %xmm0 +; SSE-NEXT: paddd %xmm5, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v8i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpaddd %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpaddd %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v8i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpaddd %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v8i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX512-NEXT: vpaddd %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %and = and <8 x i32> %a0, %a1 + %xor = xor <8 x i32> %a1, %a0 + %shift = lshr <8 x i32> %xor, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = add <8 x i32> %and, %shift + ret <8 x i32> %res +} + +define <8 x i32> @test_ext_v8i32(<8 x i32> %a0, <8 x i32> %a1) { +; SSE2-LABEL: test_ext_v8i32: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm4, %xmm4 +; SSE2-NEXT: movdqa %xmm1, %xmm5 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm5 = xmm5[2],xmm4[2],xmm5[3],xmm4[3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm4[0],xmm1[1],xmm4[1] +; SSE2-NEXT: movdqa %xmm0, %xmm6 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm6 = xmm6[2],xmm4[2],xmm6[3],xmm4[3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1] +; SSE2-NEXT: movdqa %xmm3, %xmm7 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm7 = xmm7[2],xmm4[2],xmm7[3],xmm4[3] +; SSE2-NEXT: paddq %xmm5, %xmm7 +; SSE2-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1] +; SSE2-NEXT: paddq %xmm3, %xmm1 +; SSE2-NEXT: movdqa %xmm2, %xmm3 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm3 = xmm3[2],xmm4[2],xmm3[3],xmm4[3] +; SSE2-NEXT: paddq %xmm6, %xmm3 +; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1] +; SSE2-NEXT: paddq %xmm2, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm7 +; SSE2-NEXT: psrlq $1, %xmm1 +; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm7[0,2] +; SSE2-NEXT: psrlq $1, %xmm3 +; SSE2-NEXT: psrlq $1, %xmm0 +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm3[0,2] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v8i32: +; SSE4: # %bb.0: +; SSE4-NEXT: pxor %xmm5, %xmm5 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm6 = xmm1[0],zero,xmm1[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm1 = xmm1[2],xmm5[2],xmm1[3],xmm5[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm7 = xmm0[0],zero,xmm0[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm0 = xmm0[2],xmm5[2],xmm0[3],xmm5[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm4 = xmm3[0],zero,xmm3[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm3 = xmm3[2],xmm5[2],xmm3[3],xmm5[3] +; SSE4-NEXT: paddq %xmm1, %xmm3 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm1 = xmm2[0],zero,xmm2[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm5[2],xmm2[3],xmm5[3] +; SSE4-NEXT: paddq %xmm0, %xmm2 +; SSE4-NEXT: paddq %xmm6, %xmm4 +; SSE4-NEXT: paddq %xmm7, %xmm1 +; SSE4-NEXT: psrlq $1, %xmm3 +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: psrlq $1, %xmm4 +; SSE4-NEXT: shufps {{.*#+}} xmm4 = xmm4[0,2],xmm3[0,2] +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm2[0,2] +; SSE4-NEXT: movaps %xmm1, %xmm0 +; SSE4-NEXT: movaps %xmm4, %xmm1 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v8i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 +; AVX1-NEXT: vpxor %xmm3, %xmm3, %xmm3 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm4 = xmm2[2],xmm3[2],xmm2[3],xmm3[3] +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm5 = xmm0[2],xmm3[2],xmm0[3],xmm3[3] +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm2 = xmm2[0],zero,xmm2[1],zero +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm6 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm7 = xmm6[2],xmm3[2],xmm6[3],xmm3[3] +; AVX1-NEXT: vpaddq %xmm7, %xmm4, %xmm4 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm3 = xmm1[2],xmm3[2],xmm1[3],xmm3[3] +; AVX1-NEXT: vpaddq %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm5 = xmm6[0],zero,xmm6[1],zero +; AVX1-NEXT: vpaddq %xmm5, %xmm2, %xmm2 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero +; AVX1-NEXT: vpaddq %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm4, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm3, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm2, %xmm2 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm3, %ymm1 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 +; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm1[0,2],ymm0[4,6],ymm1[4,6] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v8i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm3 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm3 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero +; AVX2-NEXT: vpaddq %ymm3, %ymm2, %ymm2 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX2-NEXT: vpaddq %ymm1, %ymm0, %ymm0 +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm1 = ymm0[2,3],ymm2[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vinserti128 $1, %xmm2, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm1[0,2],ymm0[4,6],ymm1[4,6] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v8i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero +; AVX512-NEXT: vpaddq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovqd %zmm0, %ymm0 +; AVX512-NEXT: retq + %x0 = zext <8 x i32> %a0 to <8 x i64> + %x1 = zext <8 x i32> %a1 to <8 x i64> + %sum = add <8 x i64> %x0, %x1 + %shift = lshr <8 x i64> %sum, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = trunc <8 x i64> %shift to <8 x i32> + ret <8 x i32> %res +} + +define <4 x i64> @test_fixed_v4i64(<4 x i64> %a0, <4 x i64> %a1) { +; SSE-LABEL: test_fixed_v4i64: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm1, %xmm4 +; SSE-NEXT: pand %xmm3, %xmm4 +; SSE-NEXT: movdqa %xmm0, %xmm5 +; SSE-NEXT: pand %xmm2, %xmm5 +; SSE-NEXT: pxor %xmm2, %xmm0 +; SSE-NEXT: pxor %xmm3, %xmm1 +; SSE-NEXT: psrlq $1, %xmm1 +; SSE-NEXT: paddq %xmm4, %xmm1 +; SSE-NEXT: psrlq $1, %xmm0 +; SSE-NEXT: paddq %xmm5, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v4i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm1, %ymm0, %ymm2 +; AVX1-NEXT: vxorps %ymm0, %ymm1, %ymm0 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm1 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm3 +; AVX1-NEXT: vpaddq %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpaddq %xmm1, %xmm2, %xmm1 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v4i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX2-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vpaddq %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v4i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vpand %ymm1, %ymm0, %ymm2 +; AVX512-NEXT: vpxor %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX512-NEXT: vpaddq %ymm0, %ymm2, %ymm0 +; AVX512-NEXT: retq + %and = and <4 x i64> %a0, %a1 + %xor = xor <4 x i64> %a1, %a0 + %shift = lshr <4 x i64> %xor, <i64 1, i64 1, i64 1, i64 1> + %res = add <4 x i64> %and, %shift + ret <4 x i64> %res +} + +define <4 x i64> @test_ext_v4i64(<4 x i64> %a0, <4 x i64> %a1) { +; SSE2-LABEL: test_ext_v4i64: +; SSE2: # %bb.0: +; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm4, %rdi +; SSE2-NEXT: movq %xmm1, %r9 +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3] +; SSE2-NEXT: movq %xmm1, %r10 +; SSE2-NEXT: movq %xmm0, %r11 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm3[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r8 +; SSE2-NEXT: movq %xmm3, %rsi +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rdx +; SSE2-NEXT: movq %xmm2, %rax +; SSE2-NEXT: xorl %ecx, %ecx +; SSE2-NEXT: addq %r11, %rax +; SSE2-NEXT: setb %cl +; SSE2-NEXT: xorl %r11d, %r11d +; SSE2-NEXT: addq %r10, %rdx +; SSE2-NEXT: setb %r11b +; SSE2-NEXT: xorl %r10d, %r10d +; SSE2-NEXT: addq %r9, %rsi +; SSE2-NEXT: setb %r10b +; SSE2-NEXT: xorl %r9d, %r9d +; SSE2-NEXT: addq %rdi, %r8 +; SSE2-NEXT: setb %r9b +; SSE2-NEXT: shldq $63, %r8, %r9 +; SSE2-NEXT: shldq $63, %rsi, %r10 +; SSE2-NEXT: shldq $63, %rdx, %r11 +; SSE2-NEXT: shldq $63, %rax, %rcx +; SSE2-NEXT: movq %rcx, %xmm0 +; SSE2-NEXT: movq %r11, %xmm1 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE2-NEXT: movq %r10, %xmm1 +; SSE2-NEXT: movq %r9, %xmm2 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v4i64: +; SSE4: # %bb.0: +; SSE4-NEXT: movq %xmm1, %r8 +; SSE4-NEXT: pextrq $1, %xmm1, %r9 +; SSE4-NEXT: movq %xmm0, %r10 +; SSE4-NEXT: pextrq $1, %xmm0, %r11 +; SSE4-NEXT: movq %xmm3, %rdi +; SSE4-NEXT: pextrq $1, %xmm3, %rsi +; SSE4-NEXT: movq %xmm2, %rdx +; SSE4-NEXT: pextrq $1, %xmm2, %rax +; SSE4-NEXT: xorl %ecx, %ecx +; SSE4-NEXT: addq %r11, %rax +; SSE4-NEXT: setb %cl +; SSE4-NEXT: xorl %r11d, %r11d +; SSE4-NEXT: addq %r10, %rdx +; SSE4-NEXT: setb %r11b +; SSE4-NEXT: xorl %r10d, %r10d +; SSE4-NEXT: addq %r9, %rsi +; SSE4-NEXT: setb %r10b +; SSE4-NEXT: xorl %r9d, %r9d +; SSE4-NEXT: addq %r8, %rdi +; SSE4-NEXT: setb %r9b +; SSE4-NEXT: shldq $63, %rdi, %r9 +; SSE4-NEXT: shldq $63, %rsi, %r10 +; SSE4-NEXT: shldq $63, %rdx, %r11 +; SSE4-NEXT: shldq $63, %rax, %rcx +; SSE4-NEXT: movq %rcx, %xmm1 +; SSE4-NEXT: movq %r11, %xmm0 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; SSE4-NEXT: movq %r10, %xmm2 +; SSE4-NEXT: movq %r9, %xmm1 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0] +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v4i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vmovq %xmm0, %rdi +; AVX1-NEXT: vpextrq $1, %xmm0, %r9 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vmovq %xmm0, %r10 +; AVX1-NEXT: vpextrq $1, %xmm0, %r11 +; AVX1-NEXT: vmovq %xmm1, %r8 +; AVX1-NEXT: vpextrq $1, %xmm1, %rsi +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm0 +; AVX1-NEXT: vmovq %xmm0, %rdx +; AVX1-NEXT: vpextrq $1, %xmm0, %rax +; AVX1-NEXT: xorl %ecx, %ecx +; AVX1-NEXT: addq %r11, %rax +; AVX1-NEXT: setb %cl +; AVX1-NEXT: xorl %r11d, %r11d +; AVX1-NEXT: addq %r10, %rdx +; AVX1-NEXT: setb %r11b +; AVX1-NEXT: xorl %r10d, %r10d +; AVX1-NEXT: addq %r9, %rsi +; AVX1-NEXT: setb %r10b +; AVX1-NEXT: xorl %r9d, %r9d +; AVX1-NEXT: addq %rdi, %r8 +; AVX1-NEXT: setb %r9b +; AVX1-NEXT: shldq $63, %r8, %r9 +; AVX1-NEXT: shldq $63, %rsi, %r10 +; AVX1-NEXT: shldq $63, %rdx, %r11 +; AVX1-NEXT: shldq $63, %rax, %rcx +; AVX1-NEXT: vmovq %rcx, %xmm0 +; AVX1-NEXT: vmovq %r11, %xmm1 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX1-NEXT: vmovq %r10, %xmm1 +; AVX1-NEXT: vmovq %r9, %xmm2 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0] +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v4i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vmovq %xmm0, %rdi +; AVX2-NEXT: vpextrq $1, %xmm0, %r9 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vmovq %xmm0, %r10 +; AVX2-NEXT: vpextrq $1, %xmm0, %r11 +; AVX2-NEXT: vmovq %xmm1, %r8 +; AVX2-NEXT: vpextrq $1, %xmm1, %rsi +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm0 +; AVX2-NEXT: vmovq %xmm0, %rdx +; AVX2-NEXT: vpextrq $1, %xmm0, %rax +; AVX2-NEXT: xorl %ecx, %ecx +; AVX2-NEXT: addq %r11, %rax +; AVX2-NEXT: setb %cl +; AVX2-NEXT: xorl %r11d, %r11d +; AVX2-NEXT: addq %r10, %rdx +; AVX2-NEXT: setb %r11b +; AVX2-NEXT: xorl %r10d, %r10d +; AVX2-NEXT: addq %r9, %rsi +; AVX2-NEXT: setb %r10b +; AVX2-NEXT: xorl %r9d, %r9d +; AVX2-NEXT: addq %rdi, %r8 +; AVX2-NEXT: setb %r9b +; AVX2-NEXT: shldq $63, %r8, %r9 +; AVX2-NEXT: shldq $63, %rsi, %r10 +; AVX2-NEXT: shldq $63, %rdx, %r11 +; AVX2-NEXT: shldq $63, %rax, %rcx +; AVX2-NEXT: vmovq %rcx, %xmm0 +; AVX2-NEXT: vmovq %r11, %xmm1 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX2-NEXT: vmovq %r10, %xmm1 +; AVX2-NEXT: vmovq %r9, %xmm2 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0] +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v4i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vmovq %xmm0, %rsi +; AVX512-NEXT: vpextrq $1, %xmm0, %r9 +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX512-NEXT: vmovq %xmm0, %r10 +; AVX512-NEXT: vpextrq $1, %xmm0, %r11 +; AVX512-NEXT: vmovq %xmm1, %rdi +; AVX512-NEXT: vpextrq $1, %xmm1, %rcx +; AVX512-NEXT: vextracti128 $1, %ymm1, %xmm0 +; AVX512-NEXT: vpextrq $1, %xmm0, %rax +; AVX512-NEXT: vmovq %xmm0, %r8 +; AVX512-NEXT: xorl %edx, %edx +; AVX512-NEXT: addq %r11, %rax +; AVX512-NEXT: setb %dl +; AVX512-NEXT: xorl %r11d, %r11d +; AVX512-NEXT: addq %r10, %r8 +; AVX512-NEXT: setb %r11b +; AVX512-NEXT: xorl %r10d, %r10d +; AVX512-NEXT: addq %r9, %rcx +; AVX512-NEXT: setb %r10b +; AVX512-NEXT: xorl %r9d, %r9d +; AVX512-NEXT: addq %rsi, %rdi +; AVX512-NEXT: setb %r9b +; AVX512-NEXT: shldq $63, %rdi, %r9 +; AVX512-NEXT: shldq $63, %rcx, %r10 +; AVX512-NEXT: shldq $63, %r8, %r11 +; AVX512-NEXT: shldq $63, %rax, %rdx +; AVX512-NEXT: vmovq %rdx, %xmm0 +; AVX512-NEXT: vmovq %r11, %xmm1 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX512-NEXT: vmovq %r10, %xmm1 +; AVX512-NEXT: vmovq %r9, %xmm2 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0] +; AVX512-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX512-NEXT: retq + %x0 = zext <4 x i64> %a0 to <4 x i128> + %x1 = zext <4 x i64> %a1 to <4 x i128> + %sum = add <4 x i128> %x0, %x1 + %shift = lshr <4 x i128> %sum, <i128 1, i128 1, i128 1, i128 1> + %res = trunc <4 x i128> %shift to <4 x i64> + ret <4 x i64> %res +} + +; +; 512-bit vectors +; + +define <64 x i8> @test_fixed_v64i8(<64 x i8> %a0, <64 x i8> %a1) { +; SSE-LABEL: test_fixed_v64i8: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm9 +; SSE-NEXT: pand %xmm7, %xmm9 +; SSE-NEXT: movdqa %xmm2, %xmm10 +; SSE-NEXT: pand %xmm6, %xmm10 +; SSE-NEXT: movdqa %xmm1, %xmm11 +; SSE-NEXT: pand %xmm5, %xmm11 +; SSE-NEXT: movdqa %xmm0, %xmm8 +; SSE-NEXT: pand %xmm4, %xmm8 +; SSE-NEXT: pxor %xmm4, %xmm0 +; SSE-NEXT: pxor %xmm5, %xmm1 +; SSE-NEXT: pxor %xmm6, %xmm2 +; SSE-NEXT: pxor %xmm7, %xmm3 +; SSE-NEXT: psrlw $1, %xmm3 +; SSE-NEXT: movdqa {{.*#+}} xmm4 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; SSE-NEXT: pand %xmm4, %xmm3 +; SSE-NEXT: paddb %xmm9, %xmm3 +; SSE-NEXT: psrlw $1, %xmm2 +; SSE-NEXT: pand %xmm4, %xmm2 +; SSE-NEXT: paddb %xmm10, %xmm2 +; SSE-NEXT: psrlw $1, %xmm1 +; SSE-NEXT: pand %xmm4, %xmm1 +; SSE-NEXT: paddb %xmm11, %xmm1 +; SSE-NEXT: psrlw $1, %xmm0 +; SSE-NEXT: pand %xmm4, %xmm0 +; SSE-NEXT: paddb %xmm8, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v64i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm2, %ymm0, %ymm0 +; AVX1-NEXT: vxorps %ymm3, %ymm1, %ymm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm2 +; AVX1-NEXT: vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; AVX1-NEXT: vpand %xmm3, %xmm2, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpand %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm6 +; AVX1-NEXT: vpand %xmm3, %xmm6, %xmm6 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm3, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm3 +; AVX1-NEXT: vpaddb %xmm0, %xmm3, %xmm0 +; AVX1-NEXT: vpaddb %xmm6, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpaddb %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpaddb %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v64i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpxor %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm1, %ymm1 +; AVX2-NEXT: vpbroadcastb {{.*#+}} ymm2 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127] +; AVX2-NEXT: vpand %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vpaddb %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpaddb %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v64i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vpandq %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxorq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpandd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to16}, %zmm0, %zmm0 +; AVX512-NEXT: vpaddb %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %and = and <64 x i8> %a0, %a1 + %xor = xor <64 x i8> %a0, %a1 + %shift = lshr <64 x i8> %xor, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %res = add <64 x i8> %and, %shift + ret <64 x i8> %res +} + +define <64 x i8> @test_ext_v64i8(<64 x i8> %a0, <64 x i8> %a1) { +; SSE2-LABEL: test_ext_v64i8: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: movdqa %xmm3, %xmm10 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm10 = xmm10[8],xmm8[8],xmm10[9],xmm8[9],xmm10[10],xmm8[10],xmm10[11],xmm8[11],xmm10[12],xmm8[12],xmm10[13],xmm8[13],xmm10[14],xmm8[14],xmm10[15],xmm8[15] +; SSE2-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm8[0],xmm3[1],xmm8[1],xmm3[2],xmm8[2],xmm3[3],xmm8[3],xmm3[4],xmm8[4],xmm3[5],xmm8[5],xmm3[6],xmm8[6],xmm3[7],xmm8[7] +; SSE2-NEXT: movdqa %xmm2, %xmm11 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm11 = xmm11[8],xmm8[8],xmm11[9],xmm8[9],xmm11[10],xmm8[10],xmm11[11],xmm8[11],xmm11[12],xmm8[12],xmm11[13],xmm8[13],xmm11[14],xmm8[14],xmm11[15],xmm8[15] +; SSE2-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm8[0],xmm2[1],xmm8[1],xmm2[2],xmm8[2],xmm2[3],xmm8[3],xmm2[4],xmm8[4],xmm2[5],xmm8[5],xmm2[6],xmm8[6],xmm2[7],xmm8[7] +; SSE2-NEXT: movdqa %xmm1, %xmm12 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm12 = xmm12[8],xmm8[8],xmm12[9],xmm8[9],xmm12[10],xmm8[10],xmm12[11],xmm8[11],xmm12[12],xmm8[12],xmm12[13],xmm8[13],xmm12[14],xmm8[14],xmm12[15],xmm8[15] +; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm8[0],xmm1[1],xmm8[1],xmm1[2],xmm8[2],xmm1[3],xmm8[3],xmm1[4],xmm8[4],xmm1[5],xmm8[5],xmm1[6],xmm8[6],xmm1[7],xmm8[7] +; SSE2-NEXT: movdqa %xmm0, %xmm13 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm13 = xmm13[8],xmm8[8],xmm13[9],xmm8[9],xmm13[10],xmm8[10],xmm13[11],xmm8[11],xmm13[12],xmm8[12],xmm13[13],xmm8[13],xmm13[14],xmm8[14],xmm13[15],xmm8[15] +; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm8[0],xmm0[1],xmm8[1],xmm0[2],xmm8[2],xmm0[3],xmm8[3],xmm0[4],xmm8[4],xmm0[5],xmm8[5],xmm0[6],xmm8[6],xmm0[7],xmm8[7] +; SSE2-NEXT: movdqa %xmm7, %xmm9 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm9 = xmm9[8],xmm8[8],xmm9[9],xmm8[9],xmm9[10],xmm8[10],xmm9[11],xmm8[11],xmm9[12],xmm8[12],xmm9[13],xmm8[13],xmm9[14],xmm8[14],xmm9[15],xmm8[15] +; SSE2-NEXT: paddw %xmm10, %xmm9 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm7 = xmm7[0],xmm8[0],xmm7[1],xmm8[1],xmm7[2],xmm8[2],xmm7[3],xmm8[3],xmm7[4],xmm8[4],xmm7[5],xmm8[5],xmm7[6],xmm8[6],xmm7[7],xmm8[7] +; SSE2-NEXT: paddw %xmm7, %xmm3 +; SSE2-NEXT: movdqa %xmm6, %xmm7 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm7 = xmm7[8],xmm8[8],xmm7[9],xmm8[9],xmm7[10],xmm8[10],xmm7[11],xmm8[11],xmm7[12],xmm8[12],xmm7[13],xmm8[13],xmm7[14],xmm8[14],xmm7[15],xmm8[15] +; SSE2-NEXT: paddw %xmm11, %xmm7 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm6 = xmm6[0],xmm8[0],xmm6[1],xmm8[1],xmm6[2],xmm8[2],xmm6[3],xmm8[3],xmm6[4],xmm8[4],xmm6[5],xmm8[5],xmm6[6],xmm8[6],xmm6[7],xmm8[7] +; SSE2-NEXT: paddw %xmm6, %xmm2 +; SSE2-NEXT: movdqa %xmm5, %xmm6 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm6 = xmm6[8],xmm8[8],xmm6[9],xmm8[9],xmm6[10],xmm8[10],xmm6[11],xmm8[11],xmm6[12],xmm8[12],xmm6[13],xmm8[13],xmm6[14],xmm8[14],xmm6[15],xmm8[15] +; SSE2-NEXT: paddw %xmm12, %xmm6 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm5 = xmm5[0],xmm8[0],xmm5[1],xmm8[1],xmm5[2],xmm8[2],xmm5[3],xmm8[3],xmm5[4],xmm8[4],xmm5[5],xmm8[5],xmm5[6],xmm8[6],xmm5[7],xmm8[7] +; SSE2-NEXT: paddw %xmm5, %xmm1 +; SSE2-NEXT: movdqa %xmm4, %xmm5 +; SSE2-NEXT: punpckhbw {{.*#+}} xmm5 = xmm5[8],xmm8[8],xmm5[9],xmm8[9],xmm5[10],xmm8[10],xmm5[11],xmm8[11],xmm5[12],xmm8[12],xmm5[13],xmm8[13],xmm5[14],xmm8[14],xmm5[15],xmm8[15] +; SSE2-NEXT: paddw %xmm13, %xmm5 +; SSE2-NEXT: punpcklbw {{.*#+}} xmm4 = xmm4[0],xmm8[0],xmm4[1],xmm8[1],xmm4[2],xmm8[2],xmm4[3],xmm8[3],xmm4[4],xmm8[4],xmm4[5],xmm8[5],xmm4[6],xmm8[6],xmm4[7],xmm8[7] +; SSE2-NEXT: paddw %xmm4, %xmm0 +; SSE2-NEXT: psrlw $1, %xmm9 +; SSE2-NEXT: psrlw $1, %xmm3 +; SSE2-NEXT: packuswb %xmm9, %xmm3 +; SSE2-NEXT: psrlw $1, %xmm7 +; SSE2-NEXT: psrlw $1, %xmm2 +; SSE2-NEXT: packuswb %xmm7, %xmm2 +; SSE2-NEXT: psrlw $1, %xmm6 +; SSE2-NEXT: psrlw $1, %xmm1 +; SSE2-NEXT: packuswb %xmm6, %xmm1 +; SSE2-NEXT: psrlw $1, %xmm5 +; SSE2-NEXT: psrlw $1, %xmm0 +; SSE2-NEXT: packuswb %xmm5, %xmm0 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v64i8: +; SSE4: # %bb.0: +; SSE4-NEXT: movdqa %xmm3, %xmm9 +; SSE4-NEXT: movdqa %xmm2, %xmm10 +; SSE4-NEXT: movdqa %xmm1, %xmm11 +; SSE4-NEXT: movdqa %xmm0, %xmm8 +; SSE4-NEXT: pxor %xmm13, %xmm13 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm0 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero,xmm3[4],zero,xmm3[5],zero,xmm3[6],zero,xmm3[7],zero +; SSE4-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill +; SSE4-NEXT: punpckhbw {{.*#+}} xmm9 = xmm9[8],xmm13[8],xmm9[9],xmm13[9],xmm9[10],xmm13[10],xmm9[11],xmm13[11],xmm9[12],xmm13[12],xmm9[13],xmm13[13],xmm9[14],xmm13[14],xmm9[15],xmm13[15] +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm14 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm10 = xmm10[8],xmm13[8],xmm10[9],xmm13[9],xmm10[10],xmm13[10],xmm10[11],xmm13[11],xmm10[12],xmm13[12],xmm10[13],xmm13[13],xmm10[14],xmm13[14],xmm10[15],xmm13[15] +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm15 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm11 = xmm11[8],xmm13[8],xmm11[9],xmm13[9],xmm11[10],xmm13[10],xmm11[11],xmm13[11],xmm11[12],xmm13[12],xmm11[13],xmm13[13],xmm11[14],xmm13[14],xmm11[15],xmm13[15] +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm12 = xmm8[0],zero,xmm8[1],zero,xmm8[2],zero,xmm8[3],zero,xmm8[4],zero,xmm8[5],zero,xmm8[6],zero,xmm8[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm8 = xmm8[8],xmm13[8],xmm8[9],xmm13[9],xmm8[10],xmm13[10],xmm8[11],xmm13[11],xmm8[12],xmm13[12],xmm8[13],xmm13[13],xmm8[14],xmm13[14],xmm8[15],xmm13[15] +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm3 = xmm7[0],zero,xmm7[1],zero,xmm7[2],zero,xmm7[3],zero,xmm7[4],zero,xmm7[5],zero,xmm7[6],zero,xmm7[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm7 = xmm7[8],xmm13[8],xmm7[9],xmm13[9],xmm7[10],xmm13[10],xmm7[11],xmm13[11],xmm7[12],xmm13[12],xmm7[13],xmm13[13],xmm7[14],xmm13[14],xmm7[15],xmm13[15] +; SSE4-NEXT: paddw %xmm9, %xmm7 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm2 = xmm6[0],zero,xmm6[1],zero,xmm6[2],zero,xmm6[3],zero,xmm6[4],zero,xmm6[5],zero,xmm6[6],zero,xmm6[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm6 = xmm6[8],xmm13[8],xmm6[9],xmm13[9],xmm6[10],xmm13[10],xmm6[11],xmm13[11],xmm6[12],xmm13[12],xmm6[13],xmm13[13],xmm6[14],xmm13[14],xmm6[15],xmm13[15] +; SSE4-NEXT: paddw %xmm10, %xmm6 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm1 = xmm5[0],zero,xmm5[1],zero,xmm5[2],zero,xmm5[3],zero,xmm5[4],zero,xmm5[5],zero,xmm5[6],zero,xmm5[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm5 = xmm5[8],xmm13[8],xmm5[9],xmm13[9],xmm5[10],xmm13[10],xmm5[11],xmm13[11],xmm5[12],xmm13[12],xmm5[13],xmm13[13],xmm5[14],xmm13[14],xmm5[15],xmm13[15] +; SSE4-NEXT: paddw %xmm11, %xmm5 +; SSE4-NEXT: pmovzxbw {{.*#+}} xmm0 = xmm4[0],zero,xmm4[1],zero,xmm4[2],zero,xmm4[3],zero,xmm4[4],zero,xmm4[5],zero,xmm4[6],zero,xmm4[7],zero +; SSE4-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm13[8],xmm4[9],xmm13[9],xmm4[10],xmm13[10],xmm4[11],xmm13[11],xmm4[12],xmm13[12],xmm4[13],xmm13[13],xmm4[14],xmm13[14],xmm4[15],xmm13[15] +; SSE4-NEXT: paddw %xmm8, %xmm4 +; SSE4-NEXT: paddw {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Folded Reload +; SSE4-NEXT: paddw %xmm14, %xmm2 +; SSE4-NEXT: paddw %xmm15, %xmm1 +; SSE4-NEXT: paddw %xmm12, %xmm0 +; SSE4-NEXT: psrlw $1, %xmm7 +; SSE4-NEXT: psrlw $1, %xmm6 +; SSE4-NEXT: psrlw $1, %xmm5 +; SSE4-NEXT: psrlw $1, %xmm4 +; SSE4-NEXT: psrlw $1, %xmm3 +; SSE4-NEXT: packuswb %xmm7, %xmm3 +; SSE4-NEXT: psrlw $1, %xmm2 +; SSE4-NEXT: packuswb %xmm6, %xmm2 +; SSE4-NEXT: psrlw $1, %xmm1 +; SSE4-NEXT: packuswb %xmm5, %xmm1 +; SSE4-NEXT: psrlw $1, %xmm0 +; SSE4-NEXT: packuswb %xmm4, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v64i8: +; AVX1: # %bb.0: +; AVX1-NEXT: vpxor %xmm4, %xmm4, %xmm4 +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm5 = xmm1[8],xmm4[8],xmm1[9],xmm4[9],xmm1[10],xmm4[10],xmm1[11],xmm4[11],xmm1[12],xmm4[12],xmm1[13],xmm4[13],xmm1[14],xmm4[14],xmm1[15],xmm4[15] +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm6 +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm7 = xmm6[8],xmm4[8],xmm6[9],xmm4[9],xmm6[10],xmm4[10],xmm6[11],xmm4[11],xmm6[12],xmm4[12],xmm6[13],xmm4[13],xmm6[14],xmm4[14],xmm6[15],xmm4[15] +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm8 = xmm0[8],xmm4[8],xmm0[9],xmm4[9],xmm0[10],xmm4[10],xmm0[11],xmm4[11],xmm0[12],xmm4[12],xmm0[13],xmm4[13],xmm0[14],xmm4[14],xmm0[15],xmm4[15] +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm9 +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm10 = xmm9[8],xmm4[8],xmm9[9],xmm4[9],xmm9[10],xmm4[10],xmm9[11],xmm4[11],xmm9[12],xmm4[12],xmm9[13],xmm4[13],xmm9[14],xmm4[14],xmm9[15],xmm4[15] +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm6 = xmm6[0],zero,xmm6[1],zero,xmm6[2],zero,xmm6[3],zero,xmm6[4],zero,xmm6[5],zero,xmm6[6],zero,xmm6[7],zero +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm9 = xmm9[0],zero,xmm9[1],zero,xmm9[2],zero,xmm9[3],zero,xmm9[4],zero,xmm9[5],zero,xmm9[6],zero,xmm9[7],zero +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm11 = xmm3[8],xmm4[8],xmm3[9],xmm4[9],xmm3[10],xmm4[10],xmm3[11],xmm4[11],xmm3[12],xmm4[12],xmm3[13],xmm4[13],xmm3[14],xmm4[14],xmm3[15],xmm4[15] +; AVX1-NEXT: vpaddw %xmm5, %xmm11, %xmm5 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm11 +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm12 = xmm11[8],xmm4[8],xmm11[9],xmm4[9],xmm11[10],xmm4[10],xmm11[11],xmm4[11],xmm11[12],xmm4[12],xmm11[13],xmm4[13],xmm11[14],xmm4[14],xmm11[15],xmm4[15] +; AVX1-NEXT: vpaddw %xmm7, %xmm12, %xmm7 +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm12 = xmm2[8],xmm4[8],xmm2[9],xmm4[9],xmm2[10],xmm4[10],xmm2[11],xmm4[11],xmm2[12],xmm4[12],xmm2[13],xmm4[13],xmm2[14],xmm4[14],xmm2[15],xmm4[15] +; AVX1-NEXT: vpaddw %xmm12, %xmm8, %xmm8 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm12 +; AVX1-NEXT: vpunpckhbw {{.*#+}} xmm4 = xmm12[8],xmm4[8],xmm12[9],xmm4[9],xmm12[10],xmm4[10],xmm12[11],xmm4[11],xmm12[12],xmm4[12],xmm12[13],xmm4[13],xmm12[14],xmm4[14],xmm12[15],xmm4[15] +; AVX1-NEXT: vpaddw %xmm4, %xmm10, %xmm4 +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm3 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero,xmm3[4],zero,xmm3[5],zero,xmm3[6],zero,xmm3[7],zero +; AVX1-NEXT: vpaddw %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm3 = xmm11[0],zero,xmm11[1],zero,xmm11[2],zero,xmm11[3],zero,xmm11[4],zero,xmm11[5],zero,xmm11[6],zero,xmm11[7],zero +; AVX1-NEXT: vpaddw %xmm3, %xmm6, %xmm3 +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero +; AVX1-NEXT: vpaddw %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vpmovzxbw {{.*#+}} xmm2 = xmm12[0],zero,xmm12[1],zero,xmm12[2],zero,xmm12[3],zero,xmm12[4],zero,xmm12[5],zero,xmm12[6],zero,xmm12[7],zero +; AVX1-NEXT: vpaddw %xmm2, %xmm9, %xmm2 +; AVX1-NEXT: vpsrlw $1, %xmm5, %xmm5 +; AVX1-NEXT: vpsrlw $1, %xmm7, %xmm6 +; AVX1-NEXT: vpsrlw $1, %xmm8, %xmm7 +; AVX1-NEXT: vpsrlw $1, %xmm4, %xmm4 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpackuswb %xmm5, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm3, %xmm3 +; AVX1-NEXT: vpackuswb %xmm6, %xmm3, %xmm3 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vpackuswb %xmm7, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm2, %xmm2 +; AVX1-NEXT: vpackuswb %xmm4, %xmm2, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 +; AVX1-NEXT: vinsertf128 $1, %xmm3, %ymm1, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v64i8: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm4 +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm4 = xmm4[0],zero,xmm4[1],zero,xmm4[2],zero,xmm4[3],zero,xmm4[4],zero,xmm4[5],zero,xmm4[6],zero,xmm4[7],zero,xmm4[8],zero,xmm4[9],zero,xmm4[10],zero,xmm4[11],zero,xmm4[12],zero,xmm4[13],zero,xmm4[14],zero,xmm4[15],zero +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero,xmm1[8],zero,xmm1[9],zero,xmm1[10],zero,xmm1[11],zero,xmm1[12],zero,xmm1[13],zero,xmm1[14],zero,xmm1[15],zero +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm5 +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm5 = xmm5[0],zero,xmm5[1],zero,xmm5[2],zero,xmm5[3],zero,xmm5[4],zero,xmm5[5],zero,xmm5[6],zero,xmm5[7],zero,xmm5[8],zero,xmm5[9],zero,xmm5[10],zero,xmm5[11],zero,xmm5[12],zero,xmm5[13],zero,xmm5[14],zero,xmm5[15],zero +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm6 +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm6 = xmm6[0],zero,xmm6[1],zero,xmm6[2],zero,xmm6[3],zero,xmm6[4],zero,xmm6[5],zero,xmm6[6],zero,xmm6[7],zero,xmm6[8],zero,xmm6[9],zero,xmm6[10],zero,xmm6[11],zero,xmm6[12],zero,xmm6[13],zero,xmm6[14],zero,xmm6[15],zero +; AVX2-NEXT: vpaddw %ymm6, %ymm4, %ymm4 +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm3 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero,xmm3[4],zero,xmm3[5],zero,xmm3[6],zero,xmm3[7],zero,xmm3[8],zero,xmm3[9],zero,xmm3[10],zero,xmm3[11],zero,xmm3[12],zero,xmm3[13],zero,xmm3[14],zero,xmm3[15],zero +; AVX2-NEXT: vpaddw %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm3 +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm3 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero,xmm3[4],zero,xmm3[5],zero,xmm3[6],zero,xmm3[7],zero,xmm3[8],zero,xmm3[9],zero,xmm3[10],zero,xmm3[11],zero,xmm3[12],zero,xmm3[13],zero,xmm3[14],zero,xmm3[15],zero +; AVX2-NEXT: vpaddw %ymm3, %ymm5, %ymm3 +; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero,xmm2[8],zero,xmm2[9],zero,xmm2[10],zero,xmm2[11],zero,xmm2[12],zero,xmm2[13],zero,xmm2[14],zero,xmm2[15],zero +; AVX2-NEXT: vpaddw %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlw $1, %ymm4, %ymm2 +; AVX2-NEXT: vpsrlw $1, %ymm1, %ymm1 +; AVX2-NEXT: vpackuswb %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm3, %ymm2 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpackuswb %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: vpermq {{.*#+}} ymm1 = ymm1[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v64i8: +; AVX512: # %bb.0: +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm2 +; AVX512-NEXT: vpmovzxbw {{.*#+}} zmm2 = ymm2[0],zero,ymm2[1],zero,ymm2[2],zero,ymm2[3],zero,ymm2[4],zero,ymm2[5],zero,ymm2[6],zero,ymm2[7],zero,ymm2[8],zero,ymm2[9],zero,ymm2[10],zero,ymm2[11],zero,ymm2[12],zero,ymm2[13],zero,ymm2[14],zero,ymm2[15],zero,ymm2[16],zero,ymm2[17],zero,ymm2[18],zero,ymm2[19],zero,ymm2[20],zero,ymm2[21],zero,ymm2[22],zero,ymm2[23],zero,ymm2[24],zero,ymm2[25],zero,ymm2[26],zero,ymm2[27],zero,ymm2[28],zero,ymm2[29],zero,ymm2[30],zero,ymm2[31],zero +; AVX512-NEXT: vpmovzxbw {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero,ymm0[16],zero,ymm0[17],zero,ymm0[18],zero,ymm0[19],zero,ymm0[20],zero,ymm0[21],zero,ymm0[22],zero,ymm0[23],zero,ymm0[24],zero,ymm0[25],zero,ymm0[26],zero,ymm0[27],zero,ymm0[28],zero,ymm0[29],zero,ymm0[30],zero,ymm0[31],zero +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm3 +; AVX512-NEXT: vpmovzxbw {{.*#+}} zmm3 = ymm3[0],zero,ymm3[1],zero,ymm3[2],zero,ymm3[3],zero,ymm3[4],zero,ymm3[5],zero,ymm3[6],zero,ymm3[7],zero,ymm3[8],zero,ymm3[9],zero,ymm3[10],zero,ymm3[11],zero,ymm3[12],zero,ymm3[13],zero,ymm3[14],zero,ymm3[15],zero,ymm3[16],zero,ymm3[17],zero,ymm3[18],zero,ymm3[19],zero,ymm3[20],zero,ymm3[21],zero,ymm3[22],zero,ymm3[23],zero,ymm3[24],zero,ymm3[25],zero,ymm3[26],zero,ymm3[27],zero,ymm3[28],zero,ymm3[29],zero,ymm3[30],zero,ymm3[31],zero +; AVX512-NEXT: vpaddw %zmm3, %zmm2, %zmm2 +; AVX512-NEXT: vpmovzxbw {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero,ymm1[16],zero,ymm1[17],zero,ymm1[18],zero,ymm1[19],zero,ymm1[20],zero,ymm1[21],zero,ymm1[22],zero,ymm1[23],zero,ymm1[24],zero,ymm1[25],zero,ymm1[26],zero,ymm1[27],zero,ymm1[28],zero,ymm1[29],zero,ymm1[30],zero,ymm1[31],zero +; AVX512-NEXT: vpaddw %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlw $1, %zmm2, %zmm1 +; AVX512-NEXT: vpsrlw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovwb %zmm0, %ymm0 +; AVX512-NEXT: vpmovwb %zmm1, %ymm1 +; AVX512-NEXT: vinserti64x4 $1, %ymm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %x0 = zext <64 x i8> %a0 to <64 x i16> + %x1 = zext <64 x i8> %a1 to <64 x i16> + %sum = add <64 x i16> %x0, %x1 + %shift = lshr <64 x i16> %sum, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = trunc <64 x i16> %shift to <64 x i8> + ret <64 x i8> %res +} + +define <32 x i16> @test_fixed_v32i16(<32 x i16> %a0, <32 x i16> %a1) { +; SSE-LABEL: test_fixed_v32i16: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm8 +; SSE-NEXT: pand %xmm7, %xmm8 +; SSE-NEXT: movdqa %xmm2, %xmm9 +; SSE-NEXT: pand %xmm6, %xmm9 +; SSE-NEXT: movdqa %xmm1, %xmm10 +; SSE-NEXT: pand %xmm5, %xmm10 +; SSE-NEXT: movdqa %xmm0, %xmm11 +; SSE-NEXT: pand %xmm4, %xmm11 +; SSE-NEXT: pxor %xmm4, %xmm0 +; SSE-NEXT: pxor %xmm5, %xmm1 +; SSE-NEXT: pxor %xmm6, %xmm2 +; SSE-NEXT: pxor %xmm7, %xmm3 +; SSE-NEXT: psrlw $1, %xmm3 +; SSE-NEXT: paddw %xmm8, %xmm3 +; SSE-NEXT: psrlw $1, %xmm2 +; SSE-NEXT: paddw %xmm9, %xmm2 +; SSE-NEXT: psrlw $1, %xmm1 +; SSE-NEXT: paddw %xmm10, %xmm1 +; SSE-NEXT: psrlw $1, %xmm0 +; SSE-NEXT: paddw %xmm11, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v32i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlw $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpaddw %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpaddw %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpaddw %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpaddw %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v32i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm1, %ymm1 +; AVX2-NEXT: vpaddw %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsrlw $1, %ymm0, %ymm0 +; AVX2-NEXT: vpaddw %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v32i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vpandq %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxorq %zmm0, %zmm1, %zmm0 +; AVX512-NEXT: vpsrlw $1, %zmm0, %zmm0 +; AVX512-NEXT: vpaddw %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %and = and <32 x i16> %a0, %a1 + %xor = xor <32 x i16> %a1, %a0 + %shift = lshr <32 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %res = add <32 x i16> %and, %shift + ret <32 x i16> %res +} + +define <32 x i16> @test_ext_v32i16(<32 x i16> %a0, <32 x i16> %a1) { +; SSE2-LABEL: test_ext_v32i16: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: movdqa %xmm0, %xmm9 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm9 = xmm9[4],xmm8[4],xmm9[5],xmm8[5],xmm9[6],xmm8[6],xmm9[7],xmm8[7] +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm8[0],xmm0[1],xmm8[1],xmm0[2],xmm8[2],xmm0[3],xmm8[3] +; SSE2-NEXT: movdqa %xmm1, %xmm11 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm11 = xmm11[4],xmm8[4],xmm11[5],xmm8[5],xmm11[6],xmm8[6],xmm11[7],xmm8[7] +; SSE2-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm8[0],xmm1[1],xmm8[1],xmm1[2],xmm8[2],xmm1[3],xmm8[3] +; SSE2-NEXT: movdqa %xmm2, %xmm12 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm12 = xmm12[4],xmm8[4],xmm12[5],xmm8[5],xmm12[6],xmm8[6],xmm12[7],xmm8[7] +; SSE2-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm8[0],xmm2[1],xmm8[1],xmm2[2],xmm8[2],xmm2[3],xmm8[3] +; SSE2-NEXT: movdqa %xmm3, %xmm13 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm13 = xmm13[4],xmm8[4],xmm13[5],xmm8[5],xmm13[6],xmm8[6],xmm13[7],xmm8[7] +; SSE2-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm8[0],xmm3[1],xmm8[1],xmm3[2],xmm8[2],xmm3[3],xmm8[3] +; SSE2-NEXT: movdqa %xmm4, %xmm10 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm10 = xmm10[4],xmm8[4],xmm10[5],xmm8[5],xmm10[6],xmm8[6],xmm10[7],xmm8[7] +; SSE2-NEXT: paddd %xmm9, %xmm10 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm4 = xmm4[0],xmm8[0],xmm4[1],xmm8[1],xmm4[2],xmm8[2],xmm4[3],xmm8[3] +; SSE2-NEXT: paddd %xmm4, %xmm0 +; SSE2-NEXT: movdqa %xmm5, %xmm9 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm9 = xmm9[4],xmm8[4],xmm9[5],xmm8[5],xmm9[6],xmm8[6],xmm9[7],xmm8[7] +; SSE2-NEXT: paddd %xmm11, %xmm9 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm8[0],xmm5[1],xmm8[1],xmm5[2],xmm8[2],xmm5[3],xmm8[3] +; SSE2-NEXT: paddd %xmm5, %xmm1 +; SSE2-NEXT: movdqa %xmm6, %xmm5 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm5 = xmm5[4],xmm8[4],xmm5[5],xmm8[5],xmm5[6],xmm8[6],xmm5[7],xmm8[7] +; SSE2-NEXT: paddd %xmm12, %xmm5 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm6 = xmm6[0],xmm8[0],xmm6[1],xmm8[1],xmm6[2],xmm8[2],xmm6[3],xmm8[3] +; SSE2-NEXT: paddd %xmm6, %xmm2 +; SSE2-NEXT: movdqa %xmm7, %xmm4 +; SSE2-NEXT: punpckhwd {{.*#+}} xmm4 = xmm4[4],xmm8[4],xmm4[5],xmm8[5],xmm4[6],xmm8[6],xmm4[7],xmm8[7] +; SSE2-NEXT: paddd %xmm13, %xmm4 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm7 = xmm7[0],xmm8[0],xmm7[1],xmm8[1],xmm7[2],xmm8[2],xmm7[3],xmm8[3] +; SSE2-NEXT: paddd %xmm7, %xmm3 +; SSE2-NEXT: pslld $15, %xmm10 +; SSE2-NEXT: psrad $16, %xmm10 +; SSE2-NEXT: pslld $15, %xmm0 +; SSE2-NEXT: psrad $16, %xmm0 +; SSE2-NEXT: packssdw %xmm10, %xmm0 +; SSE2-NEXT: pslld $15, %xmm9 +; SSE2-NEXT: psrad $16, %xmm9 +; SSE2-NEXT: pslld $15, %xmm1 +; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: packssdw %xmm9, %xmm1 +; SSE2-NEXT: pslld $15, %xmm5 +; SSE2-NEXT: psrad $16, %xmm5 +; SSE2-NEXT: pslld $15, %xmm2 +; SSE2-NEXT: psrad $16, %xmm2 +; SSE2-NEXT: packssdw %xmm5, %xmm2 +; SSE2-NEXT: pslld $15, %xmm4 +; SSE2-NEXT: psrad $16, %xmm4 +; SSE2-NEXT: pslld $15, %xmm3 +; SSE2-NEXT: psrad $16, %xmm3 +; SSE2-NEXT: packssdw %xmm4, %xmm3 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v32i16: +; SSE4: # %bb.0: +; SSE4-NEXT: movdqa %xmm3, %xmm9 +; SSE4-NEXT: movdqa %xmm2, %xmm10 +; SSE4-NEXT: movdqa %xmm1, %xmm11 +; SSE4-NEXT: movdqa %xmm0, %xmm8 +; SSE4-NEXT: pxor %xmm13, %xmm13 +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm0 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero +; SSE4-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill +; SSE4-NEXT: punpckhwd {{.*#+}} xmm9 = xmm9[4],xmm13[4],xmm9[5],xmm13[5],xmm9[6],xmm13[6],xmm9[7],xmm13[7] +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm14 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm10 = xmm10[4],xmm13[4],xmm10[5],xmm13[5],xmm10[6],xmm13[6],xmm10[7],xmm13[7] +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm15 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm11 = xmm11[4],xmm13[4],xmm11[5],xmm13[5],xmm11[6],xmm13[6],xmm11[7],xmm13[7] +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm12 = xmm8[0],zero,xmm8[1],zero,xmm8[2],zero,xmm8[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm8 = xmm8[4],xmm13[4],xmm8[5],xmm13[5],xmm8[6],xmm13[6],xmm8[7],xmm13[7] +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm3 = xmm7[0],zero,xmm7[1],zero,xmm7[2],zero,xmm7[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm7 = xmm7[4],xmm13[4],xmm7[5],xmm13[5],xmm7[6],xmm13[6],xmm7[7],xmm13[7] +; SSE4-NEXT: paddd %xmm9, %xmm7 +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm2 = xmm6[0],zero,xmm6[1],zero,xmm6[2],zero,xmm6[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm6 = xmm6[4],xmm13[4],xmm6[5],xmm13[5],xmm6[6],xmm13[6],xmm6[7],xmm13[7] +; SSE4-NEXT: paddd %xmm10, %xmm6 +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm1 = xmm5[0],zero,xmm5[1],zero,xmm5[2],zero,xmm5[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm5 = xmm5[4],xmm13[4],xmm5[5],xmm13[5],xmm5[6],xmm13[6],xmm5[7],xmm13[7] +; SSE4-NEXT: paddd %xmm11, %xmm5 +; SSE4-NEXT: pmovzxwd {{.*#+}} xmm0 = xmm4[0],zero,xmm4[1],zero,xmm4[2],zero,xmm4[3],zero +; SSE4-NEXT: punpckhwd {{.*#+}} xmm4 = xmm4[4],xmm13[4],xmm4[5],xmm13[5],xmm4[6],xmm13[6],xmm4[7],xmm13[7] +; SSE4-NEXT: paddd %xmm8, %xmm4 +; SSE4-NEXT: paddd {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Folded Reload +; SSE4-NEXT: paddd %xmm14, %xmm2 +; SSE4-NEXT: paddd %xmm15, %xmm1 +; SSE4-NEXT: paddd %xmm12, %xmm0 +; SSE4-NEXT: psrld $1, %xmm7 +; SSE4-NEXT: psrld $1, %xmm6 +; SSE4-NEXT: psrld $1, %xmm5 +; SSE4-NEXT: psrld $1, %xmm4 +; SSE4-NEXT: psrld $1, %xmm3 +; SSE4-NEXT: packusdw %xmm7, %xmm3 +; SSE4-NEXT: psrld $1, %xmm2 +; SSE4-NEXT: packusdw %xmm6, %xmm2 +; SSE4-NEXT: psrld $1, %xmm1 +; SSE4-NEXT: packusdw %xmm5, %xmm1 +; SSE4-NEXT: psrld $1, %xmm0 +; SSE4-NEXT: packusdw %xmm4, %xmm0 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v32i16: +; AVX1: # %bb.0: +; AVX1-NEXT: vpxor %xmm4, %xmm4, %xmm4 +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm5 = xmm1[4],xmm4[4],xmm1[5],xmm4[5],xmm1[6],xmm4[6],xmm1[7],xmm4[7] +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm6 +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm7 = xmm6[4],xmm4[4],xmm6[5],xmm4[5],xmm6[6],xmm4[6],xmm6[7],xmm4[7] +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm8 = xmm0[4],xmm4[4],xmm0[5],xmm4[5],xmm0[6],xmm4[6],xmm0[7],xmm4[7] +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm9 +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm10 = xmm9[4],xmm4[4],xmm9[5],xmm4[5],xmm9[6],xmm4[6],xmm9[7],xmm4[7] +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm6 = xmm6[0],zero,xmm6[1],zero,xmm6[2],zero,xmm6[3],zero +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm9 = xmm9[0],zero,xmm9[1],zero,xmm9[2],zero,xmm9[3],zero +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm11 = xmm3[4],xmm4[4],xmm3[5],xmm4[5],xmm3[6],xmm4[6],xmm3[7],xmm4[7] +; AVX1-NEXT: vpaddd %xmm5, %xmm11, %xmm5 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm11 +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm12 = xmm11[4],xmm4[4],xmm11[5],xmm4[5],xmm11[6],xmm4[6],xmm11[7],xmm4[7] +; AVX1-NEXT: vpaddd %xmm7, %xmm12, %xmm7 +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm12 = xmm2[4],xmm4[4],xmm2[5],xmm4[5],xmm2[6],xmm4[6],xmm2[7],xmm4[7] +; AVX1-NEXT: vpaddd %xmm12, %xmm8, %xmm8 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm12 +; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm4 = xmm12[4],xmm4[4],xmm12[5],xmm4[5],xmm12[6],xmm4[6],xmm12[7],xmm4[7] +; AVX1-NEXT: vpaddd %xmm4, %xmm10, %xmm4 +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm3 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero +; AVX1-NEXT: vpaddd %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm3 = xmm11[0],zero,xmm11[1],zero,xmm11[2],zero,xmm11[3],zero +; AVX1-NEXT: vpaddd %xmm3, %xmm6, %xmm3 +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero +; AVX1-NEXT: vpaddd %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm2 = xmm12[0],zero,xmm12[1],zero,xmm12[2],zero,xmm12[3],zero +; AVX1-NEXT: vpaddd %xmm2, %xmm9, %xmm2 +; AVX1-NEXT: vpsrld $1, %xmm5, %xmm5 +; AVX1-NEXT: vpsrld $1, %xmm7, %xmm6 +; AVX1-NEXT: vpsrld $1, %xmm8, %xmm7 +; AVX1-NEXT: vpsrld $1, %xmm4, %xmm4 +; AVX1-NEXT: vpsrld $1, %xmm1, %xmm1 +; AVX1-NEXT: vpackusdw %xmm5, %xmm1, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm3, %xmm3 +; AVX1-NEXT: vpackusdw %xmm6, %xmm3, %xmm3 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vpackusdw %xmm7, %xmm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm2, %xmm2 +; AVX1-NEXT: vpackusdw %xmm4, %xmm2, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 +; AVX1-NEXT: vinsertf128 $1, %xmm3, %ymm1, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v32i16: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm4 +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm4 = xmm4[0],zero,xmm4[1],zero,xmm4[2],zero,xmm4[3],zero,xmm4[4],zero,xmm4[5],zero,xmm4[6],zero,xmm4[7],zero +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm5 +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm5 = xmm5[0],zero,xmm5[1],zero,xmm5[2],zero,xmm5[3],zero,xmm5[4],zero,xmm5[5],zero,xmm5[6],zero,xmm5[7],zero +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm6 +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm6 = xmm6[0],zero,xmm6[1],zero,xmm6[2],zero,xmm6[3],zero,xmm6[4],zero,xmm6[5],zero,xmm6[6],zero,xmm6[7],zero +; AVX2-NEXT: vpaddd %ymm6, %ymm4, %ymm4 +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm3 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero,xmm3[4],zero,xmm3[5],zero,xmm3[6],zero,xmm3[7],zero +; AVX2-NEXT: vpaddd %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm3 +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm3 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero,xmm3[4],zero,xmm3[5],zero,xmm3[6],zero,xmm3[7],zero +; AVX2-NEXT: vpaddd %ymm3, %ymm5, %ymm3 +; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero +; AVX2-NEXT: vpaddd %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpsrld $1, %ymm4, %ymm2 +; AVX2-NEXT: vpsrld $1, %ymm1, %ymm1 +; AVX2-NEXT: vpackusdw %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vpsrld $1, %ymm3, %ymm2 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpackusdw %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX2-NEXT: vpermq {{.*#+}} ymm1 = ymm1[0,2,1,3] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v32i16: +; AVX512: # %bb.0: +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm2 +; AVX512-NEXT: vpmovzxwd {{.*#+}} zmm2 = ymm2[0],zero,ymm2[1],zero,ymm2[2],zero,ymm2[3],zero,ymm2[4],zero,ymm2[5],zero,ymm2[6],zero,ymm2[7],zero,ymm2[8],zero,ymm2[9],zero,ymm2[10],zero,ymm2[11],zero,ymm2[12],zero,ymm2[13],zero,ymm2[14],zero,ymm2[15],zero +; AVX512-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm3 +; AVX512-NEXT: vpmovzxwd {{.*#+}} zmm3 = ymm3[0],zero,ymm3[1],zero,ymm3[2],zero,ymm3[3],zero,ymm3[4],zero,ymm3[5],zero,ymm3[6],zero,ymm3[7],zero,ymm3[8],zero,ymm3[9],zero,ymm3[10],zero,ymm3[11],zero,ymm3[12],zero,ymm3[13],zero,ymm3[14],zero,ymm3[15],zero +; AVX512-NEXT: vpaddd %zmm3, %zmm2, %zmm2 +; AVX512-NEXT: vpmovzxwd {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero +; AVX512-NEXT: vpaddd %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrld $1, %zmm2, %zmm1 +; AVX512-NEXT: vpsrld $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovdw %zmm0, %ymm0 +; AVX512-NEXT: vpmovdw %zmm1, %ymm1 +; AVX512-NEXT: vinserti64x4 $1, %ymm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %x0 = zext <32 x i16> %a0 to <32 x i32> + %x1 = zext <32 x i16> %a1 to <32 x i32> + %sum = add <32 x i32> %x0, %x1 + %shift = lshr <32 x i32> %sum, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = trunc <32 x i32> %shift to <32 x i16> + ret <32 x i16> %res +} + +define <16 x i32> @test_fixed_v16i32(<16 x i32> %a0, <16 x i32> %a1) { +; SSE-LABEL: test_fixed_v16i32: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm8 +; SSE-NEXT: pand %xmm7, %xmm8 +; SSE-NEXT: movdqa %xmm2, %xmm9 +; SSE-NEXT: pand %xmm6, %xmm9 +; SSE-NEXT: movdqa %xmm1, %xmm10 +; SSE-NEXT: pand %xmm5, %xmm10 +; SSE-NEXT: movdqa %xmm0, %xmm11 +; SSE-NEXT: pand %xmm4, %xmm11 +; SSE-NEXT: pxor %xmm4, %xmm0 +; SSE-NEXT: pxor %xmm5, %xmm1 +; SSE-NEXT: pxor %xmm6, %xmm2 +; SSE-NEXT: pxor %xmm7, %xmm3 +; SSE-NEXT: psrld $1, %xmm3 +; SSE-NEXT: paddd %xmm8, %xmm3 +; SSE-NEXT: psrld $1, %xmm2 +; SSE-NEXT: paddd %xmm9, %xmm2 +; SSE-NEXT: psrld $1, %xmm1 +; SSE-NEXT: paddd %xmm10, %xmm1 +; SSE-NEXT: psrld $1, %xmm0 +; SSE-NEXT: paddd %xmm11, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v16i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsrld $1, %xmm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrld $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpaddd %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpaddd %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpaddd %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpaddd %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v16i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsrld $1, %ymm1, %ymm1 +; AVX2-NEXT: vpaddd %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsrld $1, %ymm0, %ymm0 +; AVX2-NEXT: vpaddd %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v16i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vpandd %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxord %zmm0, %zmm1, %zmm0 +; AVX512-NEXT: vpsrld $1, %zmm0, %zmm0 +; AVX512-NEXT: vpaddd %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %and = and <16 x i32> %a0, %a1 + %xor = xor <16 x i32> %a1, %a0 + %shift = lshr <16 x i32> %xor, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %res = add <16 x i32> %and, %shift + ret <16 x i32> %res +} + +define <16 x i32> @test_ext_v16i32(<16 x i32> %a0, <16 x i32> %a1) { +; SSE2-LABEL: test_ext_v16i32: +; SSE2: # %bb.0: +; SSE2-NEXT: pxor %xmm8, %xmm8 +; SSE2-NEXT: movdqa %xmm3, %xmm10 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm10 = xmm10[2],xmm8[2],xmm10[3],xmm8[3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm8[0],xmm3[1],xmm8[1] +; SSE2-NEXT: movdqa %xmm2, %xmm11 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm11 = xmm11[2],xmm8[2],xmm11[3],xmm8[3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm8[0],xmm2[1],xmm8[1] +; SSE2-NEXT: movdqa %xmm1, %xmm12 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm12 = xmm12[2],xmm8[2],xmm12[3],xmm8[3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm8[0],xmm1[1],xmm8[1] +; SSE2-NEXT: movdqa %xmm0, %xmm13 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm13 = xmm13[2],xmm8[2],xmm13[3],xmm8[3] +; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm8[0],xmm0[1],xmm8[1] +; SSE2-NEXT: movdqa %xmm7, %xmm9 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm9 = xmm9[2],xmm8[2],xmm9[3],xmm8[3] +; SSE2-NEXT: paddq %xmm10, %xmm9 +; SSE2-NEXT: punpckldq {{.*#+}} xmm7 = xmm7[0],xmm8[0],xmm7[1],xmm8[1] +; SSE2-NEXT: paddq %xmm7, %xmm3 +; SSE2-NEXT: movdqa %xmm6, %xmm7 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm7 = xmm7[2],xmm8[2],xmm7[3],xmm8[3] +; SSE2-NEXT: paddq %xmm11, %xmm7 +; SSE2-NEXT: punpckldq {{.*#+}} xmm6 = xmm6[0],xmm8[0],xmm6[1],xmm8[1] +; SSE2-NEXT: paddq %xmm6, %xmm2 +; SSE2-NEXT: movdqa %xmm5, %xmm6 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm6 = xmm6[2],xmm8[2],xmm6[3],xmm8[3] +; SSE2-NEXT: paddq %xmm12, %xmm6 +; SSE2-NEXT: punpckldq {{.*#+}} xmm5 = xmm5[0],xmm8[0],xmm5[1],xmm8[1] +; SSE2-NEXT: paddq %xmm5, %xmm1 +; SSE2-NEXT: movdqa %xmm4, %xmm5 +; SSE2-NEXT: punpckhdq {{.*#+}} xmm5 = xmm5[2],xmm8[2],xmm5[3],xmm8[3] +; SSE2-NEXT: paddq %xmm13, %xmm5 +; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm8[0],xmm4[1],xmm8[1] +; SSE2-NEXT: paddq %xmm4, %xmm0 +; SSE2-NEXT: psrlq $1, %xmm9 +; SSE2-NEXT: psrlq $1, %xmm3 +; SSE2-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,2],xmm9[0,2] +; SSE2-NEXT: psrlq $1, %xmm7 +; SSE2-NEXT: psrlq $1, %xmm2 +; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm7[0,2] +; SSE2-NEXT: psrlq $1, %xmm6 +; SSE2-NEXT: psrlq $1, %xmm1 +; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm6[0,2] +; SSE2-NEXT: psrlq $1, %xmm5 +; SSE2-NEXT: psrlq $1, %xmm0 +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm5[0,2] +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v16i32: +; SSE4: # %bb.0: +; SSE4-NEXT: movdqa %xmm3, %xmm9 +; SSE4-NEXT: movdqa %xmm2, %xmm10 +; SSE4-NEXT: movdqa %xmm1, %xmm11 +; SSE4-NEXT: movdqa %xmm0, %xmm8 +; SSE4-NEXT: pxor %xmm13, %xmm13 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm0 = xmm3[0],zero,xmm3[1],zero +; SSE4-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill +; SSE4-NEXT: punpckhdq {{.*#+}} xmm9 = xmm9[2],xmm13[2],xmm9[3],xmm13[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm14 = xmm2[0],zero,xmm2[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm10 = xmm10[2],xmm13[2],xmm10[3],xmm13[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm15 = xmm1[0],zero,xmm1[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm11 = xmm11[2],xmm13[2],xmm11[3],xmm13[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm12 = xmm8[0],zero,xmm8[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm8 = xmm8[2],xmm13[2],xmm8[3],xmm13[3] +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm3 = xmm7[0],zero,xmm7[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm7 = xmm7[2],xmm13[2],xmm7[3],xmm13[3] +; SSE4-NEXT: paddq %xmm9, %xmm7 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm2 = xmm6[0],zero,xmm6[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm6 = xmm6[2],xmm13[2],xmm6[3],xmm13[3] +; SSE4-NEXT: paddq %xmm10, %xmm6 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm1 = xmm5[0],zero,xmm5[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm5 = xmm5[2],xmm13[2],xmm5[3],xmm13[3] +; SSE4-NEXT: paddq %xmm11, %xmm5 +; SSE4-NEXT: pmovzxdq {{.*#+}} xmm0 = xmm4[0],zero,xmm4[1],zero +; SSE4-NEXT: punpckhdq {{.*#+}} xmm4 = xmm4[2],xmm13[2],xmm4[3],xmm13[3] +; SSE4-NEXT: paddq %xmm8, %xmm4 +; SSE4-NEXT: paddq {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Folded Reload +; SSE4-NEXT: paddq %xmm14, %xmm2 +; SSE4-NEXT: paddq %xmm15, %xmm1 +; SSE4-NEXT: paddq %xmm12, %xmm0 +; SSE4-NEXT: psrlq $1, %xmm7 +; SSE4-NEXT: psrlq $1, %xmm6 +; SSE4-NEXT: psrlq $1, %xmm5 +; SSE4-NEXT: psrlq $1, %xmm4 +; SSE4-NEXT: psrlq $1, %xmm3 +; SSE4-NEXT: shufps {{.*#+}} xmm3 = xmm3[0,2],xmm7[0,2] +; SSE4-NEXT: psrlq $1, %xmm2 +; SSE4-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm6[0,2] +; SSE4-NEXT: psrlq $1, %xmm1 +; SSE4-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,2],xmm5[0,2] +; SSE4-NEXT: psrlq $1, %xmm0 +; SSE4-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm4[0,2] +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v16i32: +; AVX1: # %bb.0: +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm4 +; AVX1-NEXT: vpxor %xmm5, %xmm5, %xmm5 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm6 = xmm4[2],xmm5[2],xmm4[3],xmm5[3] +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm7 = xmm1[2],xmm5[2],xmm1[3],xmm5[3] +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm8 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm9 = xmm8[2],xmm5[2],xmm8[3],xmm5[3] +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm10 = xmm0[2],xmm5[2],xmm0[3],xmm5[3] +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm4 = xmm4[0],zero,xmm4[1],zero +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm8 = xmm8[0],zero,xmm8[1],zero +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm11 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm12 = xmm11[2],xmm5[2],xmm11[3],xmm5[3] +; AVX1-NEXT: vpaddq %xmm6, %xmm12, %xmm6 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm12 = xmm3[2],xmm5[2],xmm3[3],xmm5[3] +; AVX1-NEXT: vpaddq %xmm7, %xmm12, %xmm7 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm12 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm13 = xmm12[2],xmm5[2],xmm12[3],xmm5[3] +; AVX1-NEXT: vpaddq %xmm13, %xmm9, %xmm9 +; AVX1-NEXT: vpunpckhdq {{.*#+}} xmm5 = xmm2[2],xmm5[2],xmm2[3],xmm5[3] +; AVX1-NEXT: vpaddq %xmm5, %xmm10, %xmm5 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm10 = xmm11[0],zero,xmm11[1],zero +; AVX1-NEXT: vpaddq %xmm4, %xmm10, %xmm4 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm3 = xmm3[0],zero,xmm3[1],zero +; AVX1-NEXT: vpaddq %xmm3, %xmm1, %xmm1 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm3 = xmm12[0],zero,xmm12[1],zero +; AVX1-NEXT: vpaddq %xmm3, %xmm8, %xmm3 +; AVX1-NEXT: vpmovzxdq {{.*#+}} xmm2 = xmm2[0],zero,xmm2[1],zero +; AVX1-NEXT: vpaddq %xmm2, %xmm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm6, %xmm2 +; AVX1-NEXT: vpsrlq $1, %xmm7, %xmm6 +; AVX1-NEXT: vpsrlq $1, %xmm9, %xmm7 +; AVX1-NEXT: vpsrlq $1, %xmm5, %xmm5 +; AVX1-NEXT: vpsrlq $1, %xmm4, %xmm4 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm3, %xmm3 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vinsertf128 $1, %xmm7, %ymm5, %ymm5 +; AVX1-NEXT: vinsertf128 $1, %xmm3, %ymm0, %ymm0 +; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm5[0,2],ymm0[4,6],ymm5[4,6] +; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm6, %ymm2 +; AVX1-NEXT: vinsertf128 $1, %xmm4, %ymm1, %ymm1 +; AVX1-NEXT: vshufps {{.*#+}} ymm1 = ymm1[0,2],ymm2[0,2],ymm1[4,6],ymm2[4,6] +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v16i32: +; AVX2: # %bb.0: +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm4 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm4 = xmm4[0],zero,xmm4[1],zero,xmm4[2],zero,xmm4[3],zero +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm5 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm5 = xmm5[0],zero,xmm5[1],zero,xmm5[2],zero,xmm5[3],zero +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm6 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm6 = xmm6[0],zero,xmm6[1],zero,xmm6[2],zero,xmm6[3],zero +; AVX2-NEXT: vpaddq %ymm6, %ymm4, %ymm4 +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm6 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm6 = xmm6[0],zero,xmm6[1],zero,xmm6[2],zero,xmm6[3],zero +; AVX2-NEXT: vpaddq %ymm6, %ymm5, %ymm5 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero +; AVX2-NEXT: vpaddq %ymm2, %ymm0, %ymm0 +; AVX2-NEXT: vpmovzxdq {{.*#+}} ymm2 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero +; AVX2-NEXT: vpaddq %ymm2, %ymm1, %ymm1 +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm2 = ymm0[2,3],ymm5[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm2, %ymm2 +; AVX2-NEXT: vinserti128 $1, %xmm5, %ymm0, %ymm0 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm2[0,2],ymm0[4,6],ymm2[4,6] +; AVX2-NEXT: vperm2i128 {{.*#+}} ymm2 = ymm1[2,3],ymm4[2,3] +; AVX2-NEXT: vpsrlq $1, %ymm2, %ymm2 +; AVX2-NEXT: vinserti128 $1, %xmm4, %ymm1, %ymm1 +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vshufps {{.*#+}} ymm1 = ymm1[0,2],ymm2[0,2],ymm1[4,6],ymm2[4,6] +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v16i32: +; AVX512: # %bb.0: +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm2 +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm2 = ymm2[0],zero,ymm2[1],zero,ymm2[2],zero,ymm2[3],zero,ymm2[4],zero,ymm2[5],zero,ymm2[6],zero,ymm2[7],zero +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm3 +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm3 = ymm3[0],zero,ymm3[1],zero,ymm3[2],zero,ymm3[3],zero,ymm3[4],zero,ymm3[5],zero,ymm3[6],zero,ymm3[7],zero +; AVX512-NEXT: vpaddq %zmm3, %zmm2, %zmm2 +; AVX512-NEXT: vpmovzxdq {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero +; AVX512-NEXT: vpaddq %zmm1, %zmm0, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm2, %zmm1 +; AVX512-NEXT: vpsrlq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpmovqd %zmm0, %ymm0 +; AVX512-NEXT: vpmovqd %zmm1, %ymm1 +; AVX512-NEXT: vinserti64x4 $1, %ymm1, %zmm0, %zmm0 +; AVX512-NEXT: retq + %x0 = zext <16 x i32> %a0 to <16 x i64> + %x1 = zext <16 x i32> %a1 to <16 x i64> + %sum = add <16 x i64> %x0, %x1 + %shift = lshr <16 x i64> %sum, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = trunc <16 x i64> %shift to <16 x i32> + ret <16 x i32> %res +} + +define <8 x i64> @test_fixed_v8i64(<8 x i64> %a0, <8 x i64> %a1) { +; SSE-LABEL: test_fixed_v8i64: +; SSE: # %bb.0: +; SSE-NEXT: movdqa %xmm3, %xmm8 +; SSE-NEXT: pand %xmm7, %xmm8 +; SSE-NEXT: movdqa %xmm2, %xmm9 +; SSE-NEXT: pand %xmm6, %xmm9 +; SSE-NEXT: movdqa %xmm1, %xmm10 +; SSE-NEXT: pand %xmm5, %xmm10 +; SSE-NEXT: movdqa %xmm0, %xmm11 +; SSE-NEXT: pand %xmm4, %xmm11 +; SSE-NEXT: pxor %xmm4, %xmm0 +; SSE-NEXT: pxor %xmm5, %xmm1 +; SSE-NEXT: pxor %xmm6, %xmm2 +; SSE-NEXT: pxor %xmm7, %xmm3 +; SSE-NEXT: psrlq $1, %xmm3 +; SSE-NEXT: paddq %xmm8, %xmm3 +; SSE-NEXT: psrlq $1, %xmm2 +; SSE-NEXT: paddq %xmm9, %xmm2 +; SSE-NEXT: psrlq $1, %xmm1 +; SSE-NEXT: paddq %xmm10, %xmm1 +; SSE-NEXT: psrlq $1, %xmm0 +; SSE-NEXT: paddq %xmm11, %xmm0 +; SSE-NEXT: retq +; +; AVX1-LABEL: test_fixed_v8i64: +; AVX1: # %bb.0: +; AVX1-NEXT: vandps %ymm3, %ymm1, %ymm4 +; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm5 +; AVX1-NEXT: vxorps %ymm0, %ymm2, %ymm0 +; AVX1-NEXT: vxorps %ymm1, %ymm3, %ymm1 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm2 +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm1, %xmm1 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm3 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vpsrlq $1, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm5, %xmm6 +; AVX1-NEXT: vpaddq %xmm0, %xmm6, %xmm0 +; AVX1-NEXT: vpaddq %xmm3, %xmm5, %xmm3 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm3, %ymm0 +; AVX1-NEXT: vextractf128 $1, %ymm4, %xmm3 +; AVX1-NEXT: vpaddq %xmm1, %xmm3, %xmm1 +; AVX1-NEXT: vpaddq %xmm2, %xmm4, %xmm2 +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_fixed_v8i64: +; AVX2: # %bb.0: +; AVX2-NEXT: vpand %ymm3, %ymm1, %ymm4 +; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm5 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm3, %ymm1 +; AVX2-NEXT: vpsrlq $1, %ymm1, %ymm1 +; AVX2-NEXT: vpaddq %ymm1, %ymm4, %ymm1 +; AVX2-NEXT: vpsrlq $1, %ymm0, %ymm0 +; AVX2-NEXT: vpaddq %ymm0, %ymm5, %ymm0 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_fixed_v8i64: +; AVX512: # %bb.0: +; AVX512-NEXT: vpandq %zmm1, %zmm0, %zmm2 +; AVX512-NEXT: vpxorq %zmm0, %zmm1, %zmm0 +; AVX512-NEXT: vpsrlq $1, %zmm0, %zmm0 +; AVX512-NEXT: vpaddq %zmm0, %zmm2, %zmm0 +; AVX512-NEXT: retq + %and = and <8 x i64> %a0, %a1 + %xor = xor <8 x i64> %a1, %a0 + %shift = lshr <8 x i64> %xor, <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1> + %res = add <8 x i64> %and, %shift + ret <8 x i64> %res +} + +define <8 x i64> @test_ext_v8i64(<8 x i64> %a0, <8 x i64> %a1) { +; SSE2-LABEL: test_ext_v8i64: +; SSE2: # %bb.0: +; SSE2-NEXT: pushq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: pushq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: pushq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: pushq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: pushq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: pushq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 56 +; SSE2-NEXT: .cfi_offset %rbx, -56 +; SSE2-NEXT: .cfi_offset %r12, -48 +; SSE2-NEXT: .cfi_offset %r13, -40 +; SSE2-NEXT: .cfi_offset %r14, -32 +; SSE2-NEXT: .cfi_offset %r15, -24 +; SSE2-NEXT: .cfi_offset %rbp, -16 +; SSE2-NEXT: pshufd {{.*#+}} xmm8 = xmm3[2,3,2,3] +; SSE2-NEXT: movq %xmm3, %rbx +; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm2[2,3,2,3] +; SSE2-NEXT: movq %xmm3, %r12 +; SSE2-NEXT: movq %xmm2, %rbp +; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3] +; SSE2-NEXT: movq %xmm2, %r13 +; SSE2-NEXT: movq %xmm1, %r15 +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3] +; SSE2-NEXT: movq %xmm1, %r14 +; SSE2-NEXT: movq %xmm0, %r11 +; SSE2-NEXT: movq %xmm7, %r10 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm6[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %r9 +; SSE2-NEXT: movq %xmm6, %r8 +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm5[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rdi +; SSE2-NEXT: movq %xmm5, %rsi +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm4[2,3,2,3] +; SSE2-NEXT: movq %xmm0, %rdx +; SSE2-NEXT: movq %xmm4, %rax +; SSE2-NEXT: xorl %ecx, %ecx +; SSE2-NEXT: addq %r11, %rax +; SSE2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: setb %cl +; SSE2-NEXT: xorl %r11d, %r11d +; SSE2-NEXT: addq %r14, %rdx +; SSE2-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE2-NEXT: setb %r11b +; SSE2-NEXT: xorl %r14d, %r14d +; SSE2-NEXT: addq %r15, %rsi +; SSE2-NEXT: setb %r14b +; SSE2-NEXT: xorl %r15d, %r15d +; SSE2-NEXT: addq %r13, %rdi +; SSE2-NEXT: setb %r15b +; SSE2-NEXT: xorl %r13d, %r13d +; SSE2-NEXT: addq %rbp, %r8 +; SSE2-NEXT: setb %r13b +; SSE2-NEXT: xorl %ebp, %ebp +; SSE2-NEXT: addq %r12, %r9 +; SSE2-NEXT: setb %bpl +; SSE2-NEXT: xorl %r12d, %r12d +; SSE2-NEXT: addq %rbx, %r10 +; SSE2-NEXT: movq %xmm8, %rdx +; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm7[2,3,2,3] +; SSE2-NEXT: setb %r12b +; SSE2-NEXT: movq %xmm0, %rax +; SSE2-NEXT: xorl %ebx, %ebx +; SSE2-NEXT: addq %rdx, %rax +; SSE2-NEXT: setb %bl +; SSE2-NEXT: shldq $63, %rax, %rbx +; SSE2-NEXT: shldq $63, %r10, %r12 +; SSE2-NEXT: shldq $63, %r9, %rbp +; SSE2-NEXT: shldq $63, %r8, %r13 +; SSE2-NEXT: shldq $63, %rdi, %r15 +; SSE2-NEXT: shldq $63, %rsi, %r14 +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; SSE2-NEXT: shldq $63, %rax, %r11 +; SSE2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; SSE2-NEXT: shldq $63, %rax, %rcx +; SSE2-NEXT: movq %rcx, %xmm0 +; SSE2-NEXT: movq %r11, %xmm4 +; SSE2-NEXT: movq %r14, %xmm1 +; SSE2-NEXT: movq %r15, %xmm5 +; SSE2-NEXT: movq %r13, %xmm2 +; SSE2-NEXT: movq %rbp, %xmm6 +; SSE2-NEXT: movq %r12, %xmm3 +; SSE2-NEXT: movq %rbx, %xmm7 +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm5[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm6[0] +; SSE2-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm7[0] +; SSE2-NEXT: popq %rbx +; SSE2-NEXT: .cfi_def_cfa_offset 48 +; SSE2-NEXT: popq %r12 +; SSE2-NEXT: .cfi_def_cfa_offset 40 +; SSE2-NEXT: popq %r13 +; SSE2-NEXT: .cfi_def_cfa_offset 32 +; SSE2-NEXT: popq %r14 +; SSE2-NEXT: .cfi_def_cfa_offset 24 +; SSE2-NEXT: popq %r15 +; SSE2-NEXT: .cfi_def_cfa_offset 16 +; SSE2-NEXT: popq %rbp +; SSE2-NEXT: .cfi_def_cfa_offset 8 +; SSE2-NEXT: retq +; +; SSE4-LABEL: test_ext_v8i64: +; SSE4: # %bb.0: +; SSE4-NEXT: pushq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: pushq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: pushq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: pushq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: pushq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: pushq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 56 +; SSE4-NEXT: .cfi_offset %rbx, -56 +; SSE4-NEXT: .cfi_offset %r12, -48 +; SSE4-NEXT: .cfi_offset %r13, -40 +; SSE4-NEXT: .cfi_offset %r14, -32 +; SSE4-NEXT: .cfi_offset %r15, -24 +; SSE4-NEXT: .cfi_offset %rbp, -16 +; SSE4-NEXT: pextrq $1, %xmm3, %r14 +; SSE4-NEXT: movq %xmm2, %r13 +; SSE4-NEXT: pextrq $1, %xmm2, %rbp +; SSE4-NEXT: movq %xmm1, %r12 +; SSE4-NEXT: pextrq $1, %xmm1, %r15 +; SSE4-NEXT: movq %xmm0, %rbx +; SSE4-NEXT: pextrq $1, %xmm0, %r11 +; SSE4-NEXT: pextrq $1, %xmm7, %r10 +; SSE4-NEXT: movq %xmm6, %r9 +; SSE4-NEXT: pextrq $1, %xmm6, %r8 +; SSE4-NEXT: movq %xmm5, %rdi +; SSE4-NEXT: pextrq $1, %xmm5, %rsi +; SSE4-NEXT: movq %xmm4, %rdx +; SSE4-NEXT: pextrq $1, %xmm4, %rax +; SSE4-NEXT: xorl %ecx, %ecx +; SSE4-NEXT: addq %r11, %rax +; SSE4-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: setb %cl +; SSE4-NEXT: xorl %r11d, %r11d +; SSE4-NEXT: addq %rbx, %rdx +; SSE4-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; SSE4-NEXT: setb %r11b +; SSE4-NEXT: xorl %ebx, %ebx +; SSE4-NEXT: addq %r15, %rsi +; SSE4-NEXT: setb %bl +; SSE4-NEXT: xorl %r15d, %r15d +; SSE4-NEXT: addq %r12, %rdi +; SSE4-NEXT: setb %r15b +; SSE4-NEXT: xorl %r12d, %r12d +; SSE4-NEXT: addq %rbp, %r8 +; SSE4-NEXT: setb %r12b +; SSE4-NEXT: xorl %ebp, %ebp +; SSE4-NEXT: addq %r13, %r9 +; SSE4-NEXT: setb %bpl +; SSE4-NEXT: xorl %r13d, %r13d +; SSE4-NEXT: addq %r14, %r10 +; SSE4-NEXT: movq %xmm3, %rdx +; SSE4-NEXT: setb %r13b +; SSE4-NEXT: movq %xmm7, %rax +; SSE4-NEXT: xorl %r14d, %r14d +; SSE4-NEXT: addq %rdx, %rax +; SSE4-NEXT: setb %r14b +; SSE4-NEXT: shldq $63, %rax, %r14 +; SSE4-NEXT: shldq $63, %r10, %r13 +; SSE4-NEXT: shldq $63, %r9, %rbp +; SSE4-NEXT: shldq $63, %r8, %r12 +; SSE4-NEXT: shldq $63, %rdi, %r15 +; SSE4-NEXT: shldq $63, %rsi, %rbx +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; SSE4-NEXT: shldq $63, %rax, %r11 +; SSE4-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; SSE4-NEXT: shldq $63, %rax, %rcx +; SSE4-NEXT: movq %rcx, %xmm4 +; SSE4-NEXT: movq %r11, %xmm0 +; SSE4-NEXT: movq %rbx, %xmm5 +; SSE4-NEXT: movq %r15, %xmm1 +; SSE4-NEXT: movq %r12, %xmm6 +; SSE4-NEXT: movq %rbp, %xmm2 +; SSE4-NEXT: movq %r13, %xmm7 +; SSE4-NEXT: movq %r14, %xmm3 +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm5[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm6[0] +; SSE4-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm7[0] +; SSE4-NEXT: popq %rbx +; SSE4-NEXT: .cfi_def_cfa_offset 48 +; SSE4-NEXT: popq %r12 +; SSE4-NEXT: .cfi_def_cfa_offset 40 +; SSE4-NEXT: popq %r13 +; SSE4-NEXT: .cfi_def_cfa_offset 32 +; SSE4-NEXT: popq %r14 +; SSE4-NEXT: .cfi_def_cfa_offset 24 +; SSE4-NEXT: popq %r15 +; SSE4-NEXT: .cfi_def_cfa_offset 16 +; SSE4-NEXT: popq %rbp +; SSE4-NEXT: .cfi_def_cfa_offset 8 +; SSE4-NEXT: retq +; +; AVX1-LABEL: test_ext_v8i64: +; AVX1: # %bb.0: +; AVX1-NEXT: pushq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: pushq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: pushq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: pushq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: pushq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: pushq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 56 +; AVX1-NEXT: .cfi_offset %rbx, -56 +; AVX1-NEXT: .cfi_offset %r12, -48 +; AVX1-NEXT: .cfi_offset %r13, -40 +; AVX1-NEXT: .cfi_offset %r14, -32 +; AVX1-NEXT: .cfi_offset %r15, -24 +; AVX1-NEXT: .cfi_offset %rbp, -16 +; AVX1-NEXT: vpextrq $1, %xmm1, %rbx +; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm4 +; AVX1-NEXT: vmovq %xmm4, %r15 +; AVX1-NEXT: vpextrq $1, %xmm4, %rbp +; AVX1-NEXT: vmovq %xmm0, %r13 +; AVX1-NEXT: vpextrq $1, %xmm0, %r12 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vmovq %xmm0, %r14 +; AVX1-NEXT: vpextrq $1, %xmm0, %r11 +; AVX1-NEXT: vpextrq $1, %xmm3, %r10 +; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm0 +; AVX1-NEXT: vmovq %xmm0, %r9 +; AVX1-NEXT: vpextrq $1, %xmm0, %r8 +; AVX1-NEXT: vmovq %xmm2, %rdi +; AVX1-NEXT: vpextrq $1, %xmm2, %rsi +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm0 +; AVX1-NEXT: vmovq %xmm0, %rdx +; AVX1-NEXT: vpextrq $1, %xmm0, %rax +; AVX1-NEXT: xorl %ecx, %ecx +; AVX1-NEXT: addq %r11, %rax +; AVX1-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: setb %cl +; AVX1-NEXT: xorl %r11d, %r11d +; AVX1-NEXT: addq %r14, %rdx +; AVX1-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX1-NEXT: setb %r11b +; AVX1-NEXT: xorl %r14d, %r14d +; AVX1-NEXT: addq %r12, %rsi +; AVX1-NEXT: setb %r14b +; AVX1-NEXT: xorl %r12d, %r12d +; AVX1-NEXT: addq %r13, %rdi +; AVX1-NEXT: setb %r12b +; AVX1-NEXT: xorl %r13d, %r13d +; AVX1-NEXT: addq %rbp, %r8 +; AVX1-NEXT: setb %r13b +; AVX1-NEXT: xorl %ebp, %ebp +; AVX1-NEXT: addq %r15, %r9 +; AVX1-NEXT: setb %bpl +; AVX1-NEXT: xorl %r15d, %r15d +; AVX1-NEXT: addq %rbx, %r10 +; AVX1-NEXT: vmovq %xmm1, %rdx +; AVX1-NEXT: setb %r15b +; AVX1-NEXT: vmovq %xmm3, %rax +; AVX1-NEXT: xorl %ebx, %ebx +; AVX1-NEXT: addq %rdx, %rax +; AVX1-NEXT: setb %bl +; AVX1-NEXT: shldq $63, %rax, %rbx +; AVX1-NEXT: shldq $63, %r10, %r15 +; AVX1-NEXT: shldq $63, %r9, %rbp +; AVX1-NEXT: shldq $63, %r8, %r13 +; AVX1-NEXT: shldq $63, %rdi, %r12 +; AVX1-NEXT: shldq $63, %rsi, %r14 +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX1-NEXT: shldq $63, %rax, %r11 +; AVX1-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX1-NEXT: shldq $63, %rax, %rcx +; AVX1-NEXT: vmovq %rcx, %xmm0 +; AVX1-NEXT: vmovq %r11, %xmm1 +; AVX1-NEXT: vmovq %r14, %xmm2 +; AVX1-NEXT: vmovq %r12, %xmm3 +; AVX1-NEXT: vmovq %r13, %xmm4 +; AVX1-NEXT: vmovq %rbp, %xmm5 +; AVX1-NEXT: vmovq %r15, %xmm6 +; AVX1-NEXT: vmovq %rbx, %xmm7 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 +; AVX1-NEXT: popq %rbx +; AVX1-NEXT: .cfi_def_cfa_offset 48 +; AVX1-NEXT: popq %r12 +; AVX1-NEXT: .cfi_def_cfa_offset 40 +; AVX1-NEXT: popq %r13 +; AVX1-NEXT: .cfi_def_cfa_offset 32 +; AVX1-NEXT: popq %r14 +; AVX1-NEXT: .cfi_def_cfa_offset 24 +; AVX1-NEXT: popq %r15 +; AVX1-NEXT: .cfi_def_cfa_offset 16 +; AVX1-NEXT: popq %rbp +; AVX1-NEXT: .cfi_def_cfa_offset 8 +; AVX1-NEXT: retq +; +; AVX2-LABEL: test_ext_v8i64: +; AVX2: # %bb.0: +; AVX2-NEXT: pushq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: pushq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: pushq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: pushq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: pushq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: pushq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 56 +; AVX2-NEXT: .cfi_offset %rbx, -56 +; AVX2-NEXT: .cfi_offset %r12, -48 +; AVX2-NEXT: .cfi_offset %r13, -40 +; AVX2-NEXT: .cfi_offset %r14, -32 +; AVX2-NEXT: .cfi_offset %r15, -24 +; AVX2-NEXT: .cfi_offset %rbp, -16 +; AVX2-NEXT: vpextrq $1, %xmm1, %rbx +; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm4 +; AVX2-NEXT: vmovq %xmm4, %r15 +; AVX2-NEXT: vpextrq $1, %xmm4, %rbp +; AVX2-NEXT: vmovq %xmm0, %r13 +; AVX2-NEXT: vpextrq $1, %xmm0, %r12 +; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm0 +; AVX2-NEXT: vmovq %xmm0, %r14 +; AVX2-NEXT: vpextrq $1, %xmm0, %r11 +; AVX2-NEXT: vpextrq $1, %xmm3, %r10 +; AVX2-NEXT: vextracti128 $1, %ymm3, %xmm0 +; AVX2-NEXT: vmovq %xmm0, %r9 +; AVX2-NEXT: vpextrq $1, %xmm0, %r8 +; AVX2-NEXT: vmovq %xmm2, %rdi +; AVX2-NEXT: vpextrq $1, %xmm2, %rsi +; AVX2-NEXT: vextracti128 $1, %ymm2, %xmm0 +; AVX2-NEXT: vmovq %xmm0, %rdx +; AVX2-NEXT: vpextrq $1, %xmm0, %rax +; AVX2-NEXT: xorl %ecx, %ecx +; AVX2-NEXT: addq %r11, %rax +; AVX2-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: setb %cl +; AVX2-NEXT: xorl %r11d, %r11d +; AVX2-NEXT: addq %r14, %rdx +; AVX2-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX2-NEXT: setb %r11b +; AVX2-NEXT: xorl %r14d, %r14d +; AVX2-NEXT: addq %r12, %rsi +; AVX2-NEXT: setb %r14b +; AVX2-NEXT: xorl %r12d, %r12d +; AVX2-NEXT: addq %r13, %rdi +; AVX2-NEXT: setb %r12b +; AVX2-NEXT: xorl %r13d, %r13d +; AVX2-NEXT: addq %rbp, %r8 +; AVX2-NEXT: setb %r13b +; AVX2-NEXT: xorl %ebp, %ebp +; AVX2-NEXT: addq %r15, %r9 +; AVX2-NEXT: setb %bpl +; AVX2-NEXT: xorl %r15d, %r15d +; AVX2-NEXT: addq %rbx, %r10 +; AVX2-NEXT: vmovq %xmm1, %rdx +; AVX2-NEXT: setb %r15b +; AVX2-NEXT: vmovq %xmm3, %rax +; AVX2-NEXT: xorl %ebx, %ebx +; AVX2-NEXT: addq %rdx, %rax +; AVX2-NEXT: setb %bl +; AVX2-NEXT: shldq $63, %rax, %rbx +; AVX2-NEXT: shldq $63, %r10, %r15 +; AVX2-NEXT: shldq $63, %r9, %rbp +; AVX2-NEXT: shldq $63, %r8, %r13 +; AVX2-NEXT: shldq $63, %rdi, %r12 +; AVX2-NEXT: shldq $63, %rsi, %r14 +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX2-NEXT: shldq $63, %rax, %r11 +; AVX2-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX2-NEXT: shldq $63, %rax, %rcx +; AVX2-NEXT: vmovq %rcx, %xmm0 +; AVX2-NEXT: vmovq %r11, %xmm1 +; AVX2-NEXT: vmovq %r14, %xmm2 +; AVX2-NEXT: vmovq %r12, %xmm3 +; AVX2-NEXT: vmovq %r13, %xmm4 +; AVX2-NEXT: vmovq %rbp, %xmm5 +; AVX2-NEXT: vmovq %r15, %xmm6 +; AVX2-NEXT: vmovq %rbx, %xmm7 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX2-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm2, %ymm1 +; AVX2-NEXT: popq %rbx +; AVX2-NEXT: .cfi_def_cfa_offset 48 +; AVX2-NEXT: popq %r12 +; AVX2-NEXT: .cfi_def_cfa_offset 40 +; AVX2-NEXT: popq %r13 +; AVX2-NEXT: .cfi_def_cfa_offset 32 +; AVX2-NEXT: popq %r14 +; AVX2-NEXT: .cfi_def_cfa_offset 24 +; AVX2-NEXT: popq %r15 +; AVX2-NEXT: .cfi_def_cfa_offset 16 +; AVX2-NEXT: popq %rbp +; AVX2-NEXT: .cfi_def_cfa_offset 8 +; AVX2-NEXT: retq +; +; AVX512-LABEL: test_ext_v8i64: +; AVX512: # %bb.0: +; AVX512-NEXT: pushq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: pushq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: pushq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: pushq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: pushq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: pushq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 56 +; AVX512-NEXT: .cfi_offset %rbx, -56 +; AVX512-NEXT: .cfi_offset %r12, -48 +; AVX512-NEXT: .cfi_offset %r13, -40 +; AVX512-NEXT: .cfi_offset %r14, -32 +; AVX512-NEXT: .cfi_offset %r15, -24 +; AVX512-NEXT: .cfi_offset %rbp, -16 +; AVX512-NEXT: vpextrq $1, %xmm0, %r10 +; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm2 +; AVX512-NEXT: vpextrq $1, %xmm2, %r13 +; AVX512-NEXT: vmovq %xmm2, %r15 +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm2 +; AVX512-NEXT: vmovq %xmm2, %rbp +; AVX512-NEXT: vpextrq $1, %xmm2, %r12 +; AVX512-NEXT: vextracti128 $1, %ymm2, %xmm2 +; AVX512-NEXT: vmovq %xmm2, %r14 +; AVX512-NEXT: vpextrq $1, %xmm2, %rbx +; AVX512-NEXT: vpextrq $1, %xmm1, %r9 +; AVX512-NEXT: vextracti128 $1, %ymm1, %xmm2 +; AVX512-NEXT: vmovq %xmm2, %r8 +; AVX512-NEXT: vpextrq $1, %xmm2, %rdx +; AVX512-NEXT: vextracti64x4 $1, %zmm1, %ymm2 +; AVX512-NEXT: vpextrq $1, %xmm2, %rcx +; AVX512-NEXT: vmovq %xmm2, %r11 +; AVX512-NEXT: vextracti128 $1, %ymm2, %xmm2 +; AVX512-NEXT: vmovq %xmm2, %rdi +; AVX512-NEXT: vpextrq $1, %xmm2, %rax +; AVX512-NEXT: xorl %esi, %esi +; AVX512-NEXT: addq %rbx, %rax +; AVX512-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: setb %sil +; AVX512-NEXT: xorl %ebx, %ebx +; AVX512-NEXT: addq %r14, %rdi +; AVX512-NEXT: setb %bl +; AVX512-NEXT: xorl %r14d, %r14d +; AVX512-NEXT: addq %r12, %rcx +; AVX512-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; AVX512-NEXT: setb %r14b +; AVX512-NEXT: xorl %r12d, %r12d +; AVX512-NEXT: addq %rbp, %r11 +; AVX512-NEXT: setb %r12b +; AVX512-NEXT: xorl %ebp, %ebp +; AVX512-NEXT: addq %r13, %rdx +; AVX512-NEXT: setb %bpl +; AVX512-NEXT: xorl %r13d, %r13d +; AVX512-NEXT: addq %r15, %r8 +; AVX512-NEXT: setb %r13b +; AVX512-NEXT: xorl %r15d, %r15d +; AVX512-NEXT: addq %r10, %r9 +; AVX512-NEXT: vmovq %xmm0, %rcx +; AVX512-NEXT: setb %r15b +; AVX512-NEXT: vmovq %xmm1, %rax +; AVX512-NEXT: xorl %r10d, %r10d +; AVX512-NEXT: addq %rcx, %rax +; AVX512-NEXT: setb %r10b +; AVX512-NEXT: shldq $63, %rax, %r10 +; AVX512-NEXT: shldq $63, %r9, %r15 +; AVX512-NEXT: shldq $63, %r8, %r13 +; AVX512-NEXT: shldq $63, %rdx, %rbp +; AVX512-NEXT: shldq $63, %r11, %r12 +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX512-NEXT: shldq $63, %rax, %r14 +; AVX512-NEXT: shldq $63, %rdi, %rbx +; AVX512-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload +; AVX512-NEXT: shldq $63, %rax, %rsi +; AVX512-NEXT: vmovq %rsi, %xmm0 +; AVX512-NEXT: vmovq %rbx, %xmm1 +; AVX512-NEXT: vmovq %r14, %xmm2 +; AVX512-NEXT: vmovq %r12, %xmm3 +; AVX512-NEXT: vmovq %rbp, %xmm4 +; AVX512-NEXT: vmovq %r13, %xmm5 +; AVX512-NEXT: vmovq %r15, %xmm6 +; AVX512-NEXT: vmovq %r10, %xmm7 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0] +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm3[0],xmm2[0] +; AVX512-NEXT: vinserti128 $1, %xmm0, %ymm1, %ymm0 +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm5[0],xmm4[0] +; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm7[0],xmm6[0] +; AVX512-NEXT: vinserti128 $1, %xmm1, %ymm2, %ymm1 +; AVX512-NEXT: vinserti64x4 $1, %ymm0, %zmm1, %zmm0 +; AVX512-NEXT: popq %rbx +; AVX512-NEXT: .cfi_def_cfa_offset 48 +; AVX512-NEXT: popq %r12 +; AVX512-NEXT: .cfi_def_cfa_offset 40 +; AVX512-NEXT: popq %r13 +; AVX512-NEXT: .cfi_def_cfa_offset 32 +; AVX512-NEXT: popq %r14 +; AVX512-NEXT: .cfi_def_cfa_offset 24 +; AVX512-NEXT: popq %r15 +; AVX512-NEXT: .cfi_def_cfa_offset 16 +; AVX512-NEXT: popq %rbp +; AVX512-NEXT: .cfi_def_cfa_offset 8 +; AVX512-NEXT: retq + %x0 = zext <8 x i64> %a0 to <8 x i128> + %x1 = zext <8 x i64> %a1 to <8 x i128> + %sum = add <8 x i128> %x0, %x1 + %shift = lshr <8 x i128> %sum, <i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1, i128 1> + %res = trunc <8 x i128> %shift to <8 x i64> + ret <8 x i64> %res +} + -- GitLab From c20596ca2bbeb1926ece1f03f25fdd138933c916 Mon Sep 17 00:00:00 2001 From: Florian Mayer <fmayer@google.com> Date: Tue, 19 Mar 2024 08:38:53 -0700 Subject: [PATCH 097/307] [NFC] [hwasan] also be more consistent when getting pointer types (#84399) --- .../lib/Transforms/Instrumentation/HWAddressSanitizer.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 9c814e1de42a..469cb1c2de2d 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -410,8 +410,8 @@ private: ShadowMapping Mapping; Type *VoidTy = Type::getVoidTy(M.getContext()); - Type *IntptrTy; - PointerType *PtrTy; + Type *IntptrTy = M.getDataLayout().getIntPtrType(M.getContext()); + PointerType *PtrTy = PointerType::getUnqual(M.getContext()); Type *Int8Ty = Type::getInt8Ty(M.getContext()); Type *Int32Ty = Type::getInt32Ty(M.getContext()); Type *Int64Ty = Type::getInt64Ty(M.getContext()); @@ -594,8 +594,6 @@ void HWAddressSanitizer::createHwasanCtorComdat() { /// inserts a call to __hwasan_init to the module's constructor list. void HWAddressSanitizer::initializeModule() { LLVM_DEBUG(dbgs() << "Init " << M.getName() << "\n"); - auto &DL = M.getDataLayout(); - TargetTriple = Triple(M.getTargetTriple()); // x86_64 currently has two modes: @@ -613,8 +611,6 @@ void HWAddressSanitizer::initializeModule() { C = &(M.getContext()); IRBuilder<> IRB(*C); - IntptrTy = IRB.getIntPtrTy(DL); - PtrTy = IRB.getPtrTy(); HwasanCtorFunction = nullptr; -- GitLab From 25bb7436ca3edbb0f49cef96a27f1e507b973e6c Mon Sep 17 00:00:00 2001 From: Stanislav Mekhanoshin <rampitec@users.noreply.github.com> Date: Tue, 19 Mar 2024 08:48:30 -0700 Subject: [PATCH 098/307] Trim trailing whitespaces in MCInstrAnalysis.h. NFC. (#85805) --- llvm/include/llvm/MC/MCInstrAnalysis.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/MC/MCInstrAnalysis.h b/llvm/include/llvm/MC/MCInstrAnalysis.h index e3ddf0b8b893..87db57f74f52 100644 --- a/llvm/include/llvm/MC/MCInstrAnalysis.h +++ b/llvm/include/llvm/MC/MCInstrAnalysis.h @@ -123,14 +123,14 @@ public: /// broken. Each bit of the mask is associated with a specific input operand. /// Bits associated with explicit input operands are laid out first in the /// mask; implicit operands come after explicit operands. - /// + /// /// Dependencies are broken only for operands that have their corresponding bit /// set. Operands that have their bit cleared, or that don't have a /// corresponding bit in the mask don't have their dependency broken. Note /// that Mask may not be big enough to describe all operands. The assumption /// for operands that don't have a correspondent bit in the mask is that those /// are still data dependent. - /// + /// /// The only exception to the rule is for when Mask has all zeroes. /// A zero mask means: dependencies are broken for all explicit register /// operands. -- GitLab From 9a96fb4445f4e9d9a7899189758ee6afbeb6510b Mon Sep 17 00:00:00 2001 From: Stephen Tozer <stephen.tozer@sony.com> Date: Tue, 19 Mar 2024 15:09:24 +0000 Subject: [PATCH 099/307] Reapply "[NFC][RemoveDIs] Switch ConstantExpr::getAsInstruction to not insert (#84737)" Fixes a build error caused by an unupdated getAsInstruction callsite in clang. This reverts commit ab851f7fe946e7eed700ef9d82082eb721860189. --- clang/lib/CodeGen/CGCUDANV.cpp | 3 ++- llvm/include/llvm/IR/Constants.h | 5 ++--- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 13 ++++++++---- llvm/lib/IR/Constants.cpp | 21 +++++++++---------- llvm/lib/IR/ReplaceConstant.cpp | 13 ++++++------ .../Target/XCore/XCoreLowerThreadLocal.cpp | 9 +++++--- 6 files changed, 36 insertions(+), 28 deletions(-) diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index 49f93451db7b..d3f2573fd5e3 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -491,7 +491,8 @@ static void replaceManagedVar(llvm::GlobalVariable *Var, // variable with instructions. for (auto &&Op : WorkItem) { auto *CE = cast<llvm::ConstantExpr>(Op); - auto *NewInst = CE->getAsInstruction(I); + auto *NewInst = CE->getAsInstruction(); + NewInst->insertBefore(*I->getParent(), I->getIterator()); NewInst->replaceUsesOfWith(OldV, NewV); OldV = CE; NewV = NewInst; diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h index c0ac9a4aa675..c5e1e19d6498 100644 --- a/llvm/include/llvm/IR/Constants.h +++ b/llvm/include/llvm/IR/Constants.h @@ -1289,14 +1289,13 @@ public: Type *SrcTy = nullptr) const; /// Returns an Instruction which implements the same operation as this - /// ConstantExpr. If \p InsertBefore is not null, the new instruction is - /// inserted before it, otherwise it is not inserted into any basic block. + /// ConstantExpr. It is not inserted into any basic block. /// /// A better approach to this could be to have a constructor for Instruction /// which would take a ConstantExpr parameter, but that would have spread /// implementation details of ConstantExpr outside of Constants.cpp, which /// would make it harder to remove ConstantExprs altogether. - Instruction *getAsInstruction(Instruction *InsertBefore = nullptr) const; + Instruction *getAsInstruction() const; /// Whether creating a constant expression for this binary operator is /// desirable. diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index c07ee34bfb7a..16507a69ea85 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -5073,10 +5073,15 @@ FunctionCallee OpenMPIRBuilder::createDispatchFiniFunction(unsigned IVSize, static void replaceConstatExprUsesInFuncWithInstr(ConstantExpr *ConstExpr, Function *Func) { - for (User *User : make_early_inc_range(ConstExpr->users())) - if (auto *Instr = dyn_cast<Instruction>(User)) - if (Instr->getFunction() == Func) - Instr->replaceUsesOfWith(ConstExpr, ConstExpr->getAsInstruction(Instr)); + for (User *User : make_early_inc_range(ConstExpr->users())) { + if (auto *Instr = dyn_cast<Instruction>(User)) { + if (Instr->getFunction() == Func) { + Instruction *ConstInst = ConstExpr->getAsInstruction(); + ConstInst->insertBefore(*Instr->getParent(), Instr->getIterator()); + Instr->replaceUsesOfWith(ConstExpr, ConstInst); + } + } + } } static void replaceConstantValueUsesInFuncWithInstr(llvm::Value *Input, diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index e6b92aad392f..07b5bced96da 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -3303,7 +3303,7 @@ Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV) { NewOps, this, From, To, NumUpdated, OperandNo); } -Instruction *ConstantExpr::getAsInstruction(Instruction *InsertBefore) const { +Instruction *ConstantExpr::getAsInstruction() const { SmallVector<Value *, 4> ValueOperands(operands()); ArrayRef<Value*> Ops(ValueOperands); @@ -3322,32 +3322,31 @@ Instruction *ConstantExpr::getAsInstruction(Instruction *InsertBefore) const { case Instruction::BitCast: case Instruction::AddrSpaceCast: return CastInst::Create((Instruction::CastOps)getOpcode(), Ops[0], - getType(), "", InsertBefore); + getType(), ""); case Instruction::InsertElement: - return InsertElementInst::Create(Ops[0], Ops[1], Ops[2], "", InsertBefore); + return InsertElementInst::Create(Ops[0], Ops[1], Ops[2], ""); case Instruction::ExtractElement: - return ExtractElementInst::Create(Ops[0], Ops[1], "", InsertBefore); + return ExtractElementInst::Create(Ops[0], Ops[1], ""); case Instruction::ShuffleVector: - return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask(), "", - InsertBefore); + return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask(), ""); case Instruction::GetElementPtr: { const auto *GO = cast<GEPOperator>(this); if (GO->isInBounds()) - return GetElementPtrInst::CreateInBounds( - GO->getSourceElementType(), Ops[0], Ops.slice(1), "", InsertBefore); + return GetElementPtrInst::CreateInBounds(GO->getSourceElementType(), + Ops[0], Ops.slice(1), ""); return GetElementPtrInst::Create(GO->getSourceElementType(), Ops[0], - Ops.slice(1), "", InsertBefore); + Ops.slice(1), ""); } case Instruction::ICmp: case Instruction::FCmp: return CmpInst::Create((Instruction::OtherOps)getOpcode(), (CmpInst::Predicate)getPredicate(), Ops[0], Ops[1], - "", InsertBefore); + ""); default: assert(getNumOperands() == 2 && "Must be binary operator?"); BinaryOperator *BO = BinaryOperator::Create( - (Instruction::BinaryOps)getOpcode(), Ops[0], Ops[1], "", InsertBefore); + (Instruction::BinaryOps)getOpcode(), Ops[0], Ops[1], ""); if (isa<OverflowingBinaryOperator>(BO)) { BO->setHasNoUnsignedWrap(SubclassOptionalData & OverflowingBinaryOperator::NoUnsignedWrap); diff --git a/llvm/lib/IR/ReplaceConstant.cpp b/llvm/lib/IR/ReplaceConstant.cpp index 42dec7c72328..9b07bd804049 100644 --- a/llvm/lib/IR/ReplaceConstant.cpp +++ b/llvm/lib/IR/ReplaceConstant.cpp @@ -22,11 +22,13 @@ static bool isExpandableUser(User *U) { return isa<ConstantExpr>(U) || isa<ConstantAggregate>(U); } -static SmallVector<Instruction *, 4> expandUser(Instruction *InsertPt, +static SmallVector<Instruction *, 4> expandUser(BasicBlock::iterator InsertPt, Constant *C) { SmallVector<Instruction *, 4> NewInsts; if (auto *CE = dyn_cast<ConstantExpr>(C)) { - NewInsts.push_back(CE->getAsInstruction(InsertPt)); + Instruction *ConstInst = CE->getAsInstruction(); + ConstInst->insertBefore(*InsertPt->getParent(), InsertPt); + NewInsts.push_back(ConstInst); } else if (isa<ConstantStruct>(C) || isa<ConstantArray>(C)) { Value *V = PoisonValue::get(C->getType()); for (auto [Idx, Op] : enumerate(C->operands())) { @@ -80,12 +82,11 @@ bool convertUsersOfConstantsToInstructions(ArrayRef<Constant *> Consts) { Instruction *I = InstructionWorklist.pop_back_val(); DebugLoc Loc = I->getDebugLoc(); for (Use &U : I->operands()) { - auto *BI = I; + BasicBlock::iterator BI = I->getIterator(); if (auto *Phi = dyn_cast<PHINode>(I)) { BasicBlock *BB = Phi->getIncomingBlock(U); - BasicBlock::iterator It = BB->getFirstInsertionPt(); - assert(It != BB->end() && "Unexpected empty basic block"); - BI = &*It; + BI = BB->getFirstInsertionPt(); + assert(BI != BB->end() && "Unexpected empty basic block"); } if (auto *C = dyn_cast<Constant>(U.get())) { diff --git a/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp b/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp index b5a683de33ab..5e91cce1068b 100644 --- a/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp +++ b/llvm/lib/Target/XCore/XCoreLowerThreadLocal.cpp @@ -88,12 +88,15 @@ static bool replaceConstantExprOp(ConstantExpr *CE, Pass *P) { BasicBlock *PredBB = PN->getIncomingBlock(I); if (PredBB->getTerminator()->getNumSuccessors() > 1) PredBB = SplitEdge(PredBB, PN->getParent()); - Instruction *InsertPos = PredBB->getTerminator(); - Instruction *NewInst = CE->getAsInstruction(InsertPos); + BasicBlock::iterator InsertPos = + PredBB->getTerminator()->getIterator(); + Instruction *NewInst = CE->getAsInstruction(); + NewInst->insertBefore(*PredBB, InsertPos); PN->setOperand(I, NewInst); } } else if (Instruction *Instr = dyn_cast<Instruction>(WU)) { - Instruction *NewInst = CE->getAsInstruction(Instr); + Instruction *NewInst = CE->getAsInstruction(); + NewInst->insertBefore(*Instr->getParent(), Instr->getIterator()); Instr->replaceUsesOfWith(CE, NewInst); } else { ConstantExpr *CExpr = dyn_cast<ConstantExpr>(WU); -- GitLab From 8819f8799868a95bba24c0a574a9b1455e63b63d Mon Sep 17 00:00:00 2001 From: Guray Ozen <guray.ozen@gmail.com> Date: Tue, 19 Mar 2024 16:51:32 +0100 Subject: [PATCH 100/307] [MLIR][NVVM] Add barrier.arrive (#85412) PR adds `nvvm.barrier.arrive` Op. It is useful op for producer consumer modeling. --- mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td | 27 +++++++++++++++++++ mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp | 7 ++--- .../Conversion/NVVMToLLVM/nvvm-to-llvm.mlir | 12 +++++++++ mlir/test/Dialect/LLVMIR/nvvm.mlir | 10 +++++++ 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td index 8ec8e16f75c9..728e92c9dc8d 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td @@ -409,6 +409,33 @@ def NVVM_BarrierOp : NVVM_Op<"barrier", [AttrSizedOperandSegments]> { let assemblyFormat = "(`id` `=` $barrierId^)? (`number_of_threads` `=` $numberOfThreads^)? attr-dict"; } +def NVVM_BarrierArriveOp : NVVM_PTXBuilder_Op<"barrier.arrive"> +{ + let arguments = (ins Optional<I32>:$barrierId, I32:$numberOfThreads); + + let description = [{ + Thread that executes this op announces their arrival at the barrier with + given id and continue their execution. + + The default barrier id is 0 that is similar to `nvvm.barrier` Op. When + `barrierId` is not present, the default barrier id is used. + + [For more information, see PTX ISA] + (https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-bar) + }]; + + let assemblyFormat = "(`id` `=` $barrierId^)? `number_of_threads` `=` $numberOfThreads attr-dict"; + + let extraClassDefinition = [{ + std::string $cppClass::getPtx() { + std::string ptx = "bar.arrive "; + if (getBarrierId()) { ptx += "%0, %1'"; } + else { ptx += "0, %0;"; } + return ptx; + } + }]; +} + def NVVM_ClusterArriveOp : NVVM_Op<"cluster.arrive"> { let arguments = (ins OptionalAttr<UnitAttr>:$aligned); diff --git a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp index 4780ec09b81b..9e8407451a08 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp @@ -214,8 +214,7 @@ void MmaOp::print(OpAsmPrinter &p) { p.printOptionalAttrDict(this->getOperation()->getAttrs(), ignoreAttrNames); // Print the types of the operands and result. - p << " : " - << "("; + p << " : " << "("; llvm::interleaveComma(SmallVector<Type, 3>{frags[0].regs[0].getType(), frags[1].regs[0].getType(), frags[2].regs[0].getType()}, @@ -956,9 +955,7 @@ std::string NVVM::WgmmaMmaAsyncOp::getPtx() { ss << "},"; // Need to map read/write registers correctly. regCnt = (regCnt * 2); - ss << " $" << (regCnt) << "," - << " $" << (regCnt + 1) << "," - << " p"; + ss << " $" << (regCnt) << "," << " $" << (regCnt + 1) << "," << " p"; if (getTypeD() != WGMMATypes::s32) { ss << ", $" << (regCnt + 3) << ", $" << (regCnt + 4); } diff --git a/mlir/test/Conversion/NVVMToLLVM/nvvm-to-llvm.mlir b/mlir/test/Conversion/NVVMToLLVM/nvvm-to-llvm.mlir index 0ac7331e1f69..8920bf86d89b 100644 --- a/mlir/test/Conversion/NVVMToLLVM/nvvm-to-llvm.mlir +++ b/mlir/test/Conversion/NVVMToLLVM/nvvm-to-llvm.mlir @@ -680,3 +680,15 @@ func.func @fence_proxy() { nvvm.fence.proxy { kind = #nvvm.proxy_kind<async.shared>, space = #nvvm.shared_space<cluster>} func.return } + +// ----- + +// CHECK-LABEL: @llvm_nvvm_barrier_arrive +// CHECK-SAME: (%[[barId:.*]]: i32, %[[numberOfThreads:.*]]: i32) +llvm.func @llvm_nvvm_barrier_arrive(%barID : i32, %numberOfThreads : i32) { + // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "bar.arrive 0, $0;", "r" %[[numberOfThreads]] : (i32) -> () + nvvm.barrier.arrive number_of_threads = %numberOfThreads + // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "bar.arrive $0, $1'", "r,r" %[[barId]], %[[numberOfThreads]] : (i32, i32) -> () + nvvm.barrier.arrive id = %barID number_of_threads = %numberOfThreads + llvm.return +} diff --git a/mlir/test/Dialect/LLVMIR/nvvm.mlir b/mlir/test/Dialect/LLVMIR/nvvm.mlir index f35393c5e957..de2904d15b64 100644 --- a/mlir/test/Dialect/LLVMIR/nvvm.mlir +++ b/mlir/test/Dialect/LLVMIR/nvvm.mlir @@ -55,6 +55,16 @@ llvm.func @llvm_nvvm_barrier(%barId : i32, %numberOfThreads : i32) { llvm.return } +// CHECK-LABEL: @llvm_nvvm_barrier_arrive +// CHECK-SAME: (%[[barId:.*]]: i32, %[[numberOfThreads:.*]]: i32) +llvm.func @llvm_nvvm_barrier_arrive(%barId : i32, %numberOfThreads : i32) { + // CHECK: nvvm.barrier.arrive number_of_threads = %[[numberOfThreads]] + nvvm.barrier.arrive number_of_threads = %numberOfThreads + // CHECK: nvvm.barrier.arrive id = %[[barId]] number_of_threads = %[[numberOfThreads]] + nvvm.barrier.arrive id = %barId number_of_threads = %numberOfThreads + llvm.return +} + // CHECK-LABEL: @llvm_nvvm_cluster_arrive func.func @llvm_nvvm_cluster_arrive() { // CHECK: nvvm.cluster.arrive -- GitLab From a40becdcbeca3da91b97ed1d81f9506f74fc8000 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Tue, 19 Mar 2024 16:46:59 +0100 Subject: [PATCH 101/307] [bazel][libc] Add more mess --- .../llvm-project-overlay/libc/test/UnitTest/BUILD.bazel | 1 + .../llvm-project-overlay/libc/test/src/math/BUILD.bazel | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel index 4a94916e1205..509a89b43f17 100644 --- a/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel @@ -84,6 +84,7 @@ libc_support_library( "//libc:__support_fputil_fp_bits", "//libc:__support_fputil_fpbits_str", "//libc:__support_fputil_rounding_mode", + "//libc:internal_includes", ], ) diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel index 391b509854f9..632f55a08a24 100644 --- a/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel @@ -178,6 +178,7 @@ libc_support_library( deps = [ "//libc:__support_fputil_basic_operations", "//libc:__support_fputil_fp_bits", + "//libc:internal_includes", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", "//libc/utils/MPFRWrapper:mpfr_wrapper", @@ -323,6 +324,7 @@ libc_support_library( "//libc:__support_fputil_basic_operations", "//libc:__support_fputil_fenv_impl", "//libc:__support_fputil_fp_bits", + "//libc:internal_includes", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", ], @@ -350,6 +352,7 @@ libc_support_library( "//libc:__support_cpp_limits", "//libc:__support_fputil_fp_bits", "//libc:__support_fputil_normal_float", + "//libc:internal_includes", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", ], @@ -376,6 +379,7 @@ libc_support_library( deps = [ "//libc:__support_fputil_fenv_impl", "//libc:__support_fputil_fp_bits", + "//libc:internal_includes", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", "//libc/utils/MPFRWrapper:mpfr_wrapper", @@ -412,6 +416,7 @@ libc_support_library( deps = [ "//libc:__support_fputil_fenv_impl", "//libc:__support_fputil_fp_bits", + "//libc:internal_includes", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", "//libc/utils/MPFRWrapper:mpfr_wrapper", @@ -523,6 +528,7 @@ libc_support_library( "//libc:__support_cpp_type_traits", "//libc:__support_fputil_basic_operations", "//libc:__support_fputil_fp_bits", + "//libc:internal_includes", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", ], -- GitLab From 0081ec11d86f34982ac5b1df4f53943a92d5223f Mon Sep 17 00:00:00 2001 From: Philip Reames <preames@rivosinc.com> Date: Tue, 19 Mar 2024 08:57:09 -0700 Subject: [PATCH 102/307] [VectorCombine] Add a mask for SK_Broadcast shuffle costing (#85808) This is part of a series of small patches to compute shuffle masks for the couple of cases where we call getShuffleCost without one. My goal is to add an invariant that all calls to getShuffleCost for fixed length vectors have a mask. Note that this code appears to be reachable with scalable vectors, and thus we have to only pass a non-empty mask when the number of elements is precisely known. --- llvm/lib/Transforms/Vectorize/VectorCombine.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp index dc669e314a0d..85c8d3996bba 100644 --- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp +++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp @@ -786,9 +786,12 @@ bool VectorCombine::scalarizeVPIntrinsic(Instruction &I) { // intrinsic VectorType *VecTy = cast<VectorType>(VPI.getType()); TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput; + SmallVector<int> Mask; + if (auto *FVTy = dyn_cast<FixedVectorType>(VecTy)) + Mask.resize(FVTy->getNumElements(), 0); InstructionCost SplatCost = TTI.getVectorInstrCost(Instruction::InsertElement, VecTy, CostKind, 0) + - TTI.getShuffleCost(TargetTransformInfo::SK_Broadcast, VecTy); + TTI.getShuffleCost(TargetTransformInfo::SK_Broadcast, VecTy, Mask); // Calculate the cost of the VP Intrinsic SmallVector<Type *, 4> Args; -- GitLab From 081a66ffacfe85a37ff775addafcf3371e967328 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi <1802579+farzonl@users.noreply.github.com> Date: Tue, 19 Mar 2024 12:03:43 -0400 Subject: [PATCH 103/307] [DXIL] implement dot intrinsic lowering for integers (#85662) this implements part 1 of 2 for #83626 - `CGBuiltin.cpp` - modified to have seperate cases for signed and unsigned integers. - `SemaChecking.cpp` - modified to prevent the generation of a double dot product intrinsic if the builtin were to be called directly. - `IntrinsicsDirectX.td` creation of the signed and unsigned dot intrinsics needed for instruction expansion. - `DXILIntrinsicExpansion.cpp` - handle instruction expansion cases for integer dot product. --- clang/lib/CodeGen/CGBuiltin.cpp | 14 ++- clang/lib/Sema/SemaChecking.cpp | 14 +++ clang/test/CodeGenHLSL/builtins/dot.hlsl | 36 +++---- clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 9 ++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 11 +- .../Target/DirectX/DXILIntrinsicExpansion.cpp | 36 +++++++ llvm/test/CodeGen/DirectX/idot.ll | 100 ++++++++++++++++++ 7 files changed, 200 insertions(+), 20 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/idot.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index e965df810add..e89691ab7921 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18036,6 +18036,17 @@ llvm::Value *CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments, return Arg; } +Intrinsic::ID getDotProductIntrinsic(QualType QT) { + if (QT->hasSignedIntegerRepresentation()) + return Intrinsic::dx_sdot; + if (QT->hasUnsignedIntegerRepresentation()) + return Intrinsic::dx_udot; + + assert(QT->hasFloatingRepresentation()); + return Intrinsic::dx_dot; + ; +} + Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (!getLangOpts().HLSL) @@ -18096,7 +18107,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, "Dot product requires vectors to be of the same size."); return Builder.CreateIntrinsic( - /*ReturnType=*/T0->getScalarType(), Intrinsic::dx_dot, + /*ReturnType=*/T0->getScalarType(), + getDotProductIntrinsic(E->getArg(0)->getType()), ArrayRef<Value *>{Op0, Op1}, nullptr, "dx.dot"); } break; case Builtin::BI__builtin_hlsl_lerp: { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a0b256ab5579..f9112a29027a 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5484,6 +5484,18 @@ bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) { checkFloatorHalf); } +bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) { + auto checkDoubleVector = [](clang::QualType PassedType) -> bool { + if (const auto *VecTy = dyn_cast<VectorType>(PassedType)) { + clang::QualType BaseType = VecTy->getElementType(); + return !BaseType->isHalfType() && !BaseType->isFloat32Type(); + } + return false; + }; + return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy, + checkDoubleVector); +} + void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall, QualType ReturnType) { auto *VecTyA = TheCall->getArg(0)->getType()->getAs<VectorType>(); @@ -5520,6 +5532,8 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinVectorToScalarMath(TheCall)) return true; + if (CheckNoDoubleVectors(this, TheCall)) + return true; break; } case Builtin::BI__builtin_hlsl_elementwise_rcp: { diff --git a/clang/test/CodeGenHLSL/builtins/dot.hlsl b/clang/test/CodeGenHLSL/builtins/dot.hlsl index c064d118caf3..0f993193c00c 100644 --- a/clang/test/CodeGenHLSL/builtins/dot.hlsl +++ b/clang/test/CodeGenHLSL/builtins/dot.hlsl @@ -11,15 +11,15 @@ // NATIVE_HALF: ret i16 %dx.dot int16_t test_dot_short(int16_t p0, int16_t p1) { return dot(p0, p1); } -// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v2i16(<2 x i16> %0, <2 x i16> %1) +// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.sdot.v2i16(<2 x i16> %0, <2 x i16> %1) // NATIVE_HALF: ret i16 %dx.dot int16_t test_dot_short2(int16_t2 p0, int16_t2 p1) { return dot(p0, p1); } -// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v3i16(<3 x i16> %0, <3 x i16> %1) +// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.sdot.v3i16(<3 x i16> %0, <3 x i16> %1) // NATIVE_HALF: ret i16 %dx.dot int16_t test_dot_short3(int16_t3 p0, int16_t3 p1) { return dot(p0, p1); } -// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v4i16(<4 x i16> %0, <4 x i16> %1) +// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.sdot.v4i16(<4 x i16> %0, <4 x i16> %1) // NATIVE_HALF: ret i16 %dx.dot int16_t test_dot_short4(int16_t4 p0, int16_t4 p1) { return dot(p0, p1); } @@ -27,15 +27,15 @@ int16_t test_dot_short4(int16_t4 p0, int16_t4 p1) { return dot(p0, p1); } // NATIVE_HALF: ret i16 %dx.dot uint16_t test_dot_ushort(uint16_t p0, uint16_t p1) { return dot(p0, p1); } -// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v2i16(<2 x i16> %0, <2 x i16> %1) +// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.udot.v2i16(<2 x i16> %0, <2 x i16> %1) // NATIVE_HALF: ret i16 %dx.dot uint16_t test_dot_ushort2(uint16_t2 p0, uint16_t2 p1) { return dot(p0, p1); } -// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v3i16(<3 x i16> %0, <3 x i16> %1) +// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.udot.v3i16(<3 x i16> %0, <3 x i16> %1) // NATIVE_HALF: ret i16 %dx.dot uint16_t test_dot_ushort3(uint16_t3 p0, uint16_t3 p1) { return dot(p0, p1); } -// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v4i16(<4 x i16> %0, <4 x i16> %1) +// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.udot.v4i16(<4 x i16> %0, <4 x i16> %1) // NATIVE_HALF: ret i16 %dx.dot uint16_t test_dot_ushort4(uint16_t4 p0, uint16_t4 p1) { return dot(p0, p1); } #endif @@ -44,15 +44,15 @@ uint16_t test_dot_ushort4(uint16_t4 p0, uint16_t4 p1) { return dot(p0, p1); } // CHECK: ret i32 %dx.dot int test_dot_int(int p0, int p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i32 @llvm.dx.dot.v2i32(<2 x i32> %0, <2 x i32> %1) +// CHECK: %dx.dot = call i32 @llvm.dx.sdot.v2i32(<2 x i32> %0, <2 x i32> %1) // CHECK: ret i32 %dx.dot int test_dot_int2(int2 p0, int2 p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i32 @llvm.dx.dot.v3i32(<3 x i32> %0, <3 x i32> %1) +// CHECK: %dx.dot = call i32 @llvm.dx.sdot.v3i32(<3 x i32> %0, <3 x i32> %1) // CHECK: ret i32 %dx.dot int test_dot_int3(int3 p0, int3 p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i32 @llvm.dx.dot.v4i32(<4 x i32> %0, <4 x i32> %1) +// CHECK: %dx.dot = call i32 @llvm.dx.sdot.v4i32(<4 x i32> %0, <4 x i32> %1) // CHECK: ret i32 %dx.dot int test_dot_int4(int4 p0, int4 p1) { return dot(p0, p1); } @@ -60,15 +60,15 @@ int test_dot_int4(int4 p0, int4 p1) { return dot(p0, p1); } // CHECK: ret i32 %dx.dot uint test_dot_uint(uint p0, uint p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i32 @llvm.dx.dot.v2i32(<2 x i32> %0, <2 x i32> %1) +// CHECK: %dx.dot = call i32 @llvm.dx.udot.v2i32(<2 x i32> %0, <2 x i32> %1) // CHECK: ret i32 %dx.dot uint test_dot_uint2(uint2 p0, uint2 p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i32 @llvm.dx.dot.v3i32(<3 x i32> %0, <3 x i32> %1) +// CHECK: %dx.dot = call i32 @llvm.dx.udot.v3i32(<3 x i32> %0, <3 x i32> %1) // CHECK: ret i32 %dx.dot uint test_dot_uint3(uint3 p0, uint3 p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i32 @llvm.dx.dot.v4i32(<4 x i32> %0, <4 x i32> %1) +// CHECK: %dx.dot = call i32 @llvm.dx.udot.v4i32(<4 x i32> %0, <4 x i32> %1) // CHECK: ret i32 %dx.dot uint test_dot_uint4(uint4 p0, uint4 p1) { return dot(p0, p1); } @@ -76,15 +76,15 @@ uint test_dot_uint4(uint4 p0, uint4 p1) { return dot(p0, p1); } // CHECK: ret i64 %dx.dot int64_t test_dot_long(int64_t p0, int64_t p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i64 @llvm.dx.dot.v2i64(<2 x i64> %0, <2 x i64> %1) +// CHECK: %dx.dot = call i64 @llvm.dx.sdot.v2i64(<2 x i64> %0, <2 x i64> %1) // CHECK: ret i64 %dx.dot int64_t test_dot_long2(int64_t2 p0, int64_t2 p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i64 @llvm.dx.dot.v3i64(<3 x i64> %0, <3 x i64> %1) +// CHECK: %dx.dot = call i64 @llvm.dx.sdot.v3i64(<3 x i64> %0, <3 x i64> %1) // CHECK: ret i64 %dx.dot int64_t test_dot_long3(int64_t3 p0, int64_t3 p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i64 @llvm.dx.dot.v4i64(<4 x i64> %0, <4 x i64> %1) +// CHECK: %dx.dot = call i64 @llvm.dx.sdot.v4i64(<4 x i64> %0, <4 x i64> %1) // CHECK: ret i64 %dx.dot int64_t test_dot_long4(int64_t4 p0, int64_t4 p1) { return dot(p0, p1); } @@ -92,15 +92,15 @@ int64_t test_dot_long4(int64_t4 p0, int64_t4 p1) { return dot(p0, p1); } // CHECK: ret i64 %dx.dot uint64_t test_dot_ulong(uint64_t p0, uint64_t p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i64 @llvm.dx.dot.v2i64(<2 x i64> %0, <2 x i64> %1) +// CHECK: %dx.dot = call i64 @llvm.dx.udot.v2i64(<2 x i64> %0, <2 x i64> %1) // CHECK: ret i64 %dx.dot uint64_t test_dot_ulong2(uint64_t2 p0, uint64_t2 p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i64 @llvm.dx.dot.v3i64(<3 x i64> %0, <3 x i64> %1) +// CHECK: %dx.dot = call i64 @llvm.dx.udot.v3i64(<3 x i64> %0, <3 x i64> %1) // CHECK: ret i64 %dx.dot uint64_t test_dot_ulong3(uint64_t3 p0, uint64_t3 p1) { return dot(p0, p1); } -// CHECK: %dx.dot = call i64 @llvm.dx.dot.v4i64(<4 x i64> %0, <4 x i64> %1) +// CHECK: %dx.dot = call i64 @llvm.dx.udot.v4i64(<4 x i64> %0, <4 x i64> %1) // CHECK: ret i64 %dx.dot uint64_t test_dot_ulong4(uint64_t4 p0, uint64_t4 p1) { return dot(p0, p1); } diff --git a/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl index 59eb9482b9ef..ba7ffc20484a 100644 --- a/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl @@ -108,3 +108,12 @@ int test_builtin_dot_bool_type_promotion(bool p0, bool p1) { return __builtin_hlsl_dot(p0, p1); // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'bool')}} } + +double test_dot_double(double2 p0, double2 p1) { + return dot(p0, p1); + // expected-error@-1 {{call to 'dot' is ambiguous}} +} +double test_dot_double_builtin(double2 p0, double2 p1) { + return __builtin_hlsl_dot(p0, p1); + // expected-error@-1 {{passing 'double2' (aka 'vector<double, 2>') to parameter of incompatible type '__attribute__((__vector_size__(2 * sizeof(float)))) float' (vector of 2 'float' values)}} +} diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td index 5c72f06f96ed..1164b241ba7b 100644 --- a/llvm/include/llvm/IR/IntrinsicsDirectX.td +++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td @@ -23,9 +23,18 @@ def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">, def int_dx_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>; def int_dx_clamp : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>; def int_dx_uclamp : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>; + def int_dx_dot : Intrinsic<[LLVMVectorElementType<0>], - [llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>>], + [llvm_anyfloat_ty, LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>>], + [IntrNoMem, IntrWillReturn, Commutative] >; +def int_dx_sdot : + Intrinsic<[LLVMVectorElementType<0>], + [llvm_anyint_ty, LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>>], + [IntrNoMem, IntrWillReturn, Commutative] >; +def int_dx_udot : + Intrinsic<[LLVMVectorElementType<0>], + [llvm_anyint_ty, LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>>], [IntrNoMem, IntrWillReturn, Commutative] >; def int_dx_frac : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp index bc38c10a1fce..0db42bc0a0fb 100644 --- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp +++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp @@ -39,11 +39,44 @@ static bool isIntrinsicExpansion(Function &F) { case Intrinsic::dx_uclamp: case Intrinsic::dx_lerp: case Intrinsic::dx_rcp: + case Intrinsic::dx_sdot: + case Intrinsic::dx_udot: return true; } return false; } +static bool expandIntegerDot(CallInst *Orig, Intrinsic::ID DotIntrinsic) { + assert(DotIntrinsic == Intrinsic::dx_sdot || + DotIntrinsic == Intrinsic::dx_udot); + Intrinsic::ID MadIntrinsic = DotIntrinsic == Intrinsic::dx_sdot + ? Intrinsic::dx_imad + : Intrinsic::dx_umad; + Value *A = Orig->getOperand(0); + Value *B = Orig->getOperand(1); + Type *ATy = A->getType(); + Type *BTy = B->getType(); + assert(ATy->isVectorTy() && BTy->isVectorTy()); + + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + + auto *AVec = dyn_cast<FixedVectorType>(A->getType()); + Value *Elt0 = Builder.CreateExtractElement(A, (uint64_t)0); + Value *Elt1 = Builder.CreateExtractElement(B, (uint64_t)0); + Value *Result = Builder.CreateMul(Elt0, Elt1); + for (unsigned I = 1; I < AVec->getNumElements(); I++) { + Elt0 = Builder.CreateExtractElement(A, I); + Elt1 = Builder.CreateExtractElement(B, I); + Result = Builder.CreateIntrinsic(Result->getType(), MadIntrinsic, + ArrayRef<Value *>{Elt0, Elt1, Result}, + nullptr, "dx.mad"); + } + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + static bool expandExpIntrinsic(CallInst *Orig) { Value *X = Orig->getOperand(0); IRBuilder<> Builder(Orig->getParent()); @@ -191,6 +224,9 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) { return expandLerpIntrinsic(Orig); case Intrinsic::dx_rcp: return expandRcpIntrinsic(Orig); + case Intrinsic::dx_sdot: + case Intrinsic::dx_udot: + return expandIntegerDot(Orig, F.getIntrinsicID()); } return false; } diff --git a/llvm/test/CodeGen/DirectX/idot.ll b/llvm/test/CodeGen/DirectX/idot.ll new file mode 100644 index 000000000000..9f89a8d6d340 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/idot.ll @@ -0,0 +1,100 @@ +; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK + +; Make sure dxil operation function calls for dot are generated for int/uint vectors. + +; CHECK-LABEL: dot_int16_t2 +define noundef i16 @dot_int16_t2(<2 x i16> noundef %a, <2 x i16> noundef %b) { +entry: +; CHECK: extractelement <2 x i16> %a, i64 0 +; CHECK: extractelement <2 x i16> %b, i64 0 +; CHECK: mul i16 %{{.*}}, %{{.*}} +; CHECK: extractelement <2 x i16> %a, i64 1 +; CHECK: extractelement <2 x i16> %b, i64 1 +; EXPCHECK: call i16 @llvm.dx.imad.i16(i16 %{{.*}}, i16 %{{.*}}, i16 %{{.*}}) +; DOPCHECK: call i16 @dx.op.tertiary.i16(i32 48, i16 %{{.*}}, i16 %{{.*}}, i16 %{{.*}}) + %dx.dot = call i16 @llvm.dx.sdot.v3i16(<2 x i16> %a, <2 x i16> %b) + ret i16 %dx.dot +} + +; CHECK-LABEL: sdot_int4 +define noundef i32 @sdot_int4(<4 x i32> noundef %a, <4 x i32> noundef %b) { +entry: +; CHECK: extractelement <4 x i32> %a, i64 0 +; CHECK: extractelement <4 x i32> %b, i64 0 +; CHECK: mul i32 %{{.*}}, %{{.*}} +; CHECK: extractelement <4 x i32> %a, i64 1 +; CHECK: extractelement <4 x i32> %b, i64 1 +; EXPCHECK: call i32 @llvm.dx.imad.i32(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) +; DOPCHECK: call i32 @dx.op.tertiary.i32(i32 48, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) +; CHECK: extractelement <4 x i32> %a, i64 2 +; CHECK: extractelement <4 x i32> %b, i64 2 +; EXPCHECK: call i32 @llvm.dx.imad.i32(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) +; DOPCHECK: call i32 @dx.op.tertiary.i32(i32 48, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) +; CHECK: extractelement <4 x i32> %a, i64 3 +; CHECK: extractelement <4 x i32> %b, i64 3 +; EXPCHECK: call i32 @llvm.dx.imad.i32(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) +; DOPCHECK: call i32 @dx.op.tertiary.i32(i32 48, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) + %dx.dot = call i32 @llvm.dx.sdot.v4i32(<4 x i32> %a, <4 x i32> %b) + ret i32 %dx.dot +} + +; CHECK-LABEL: dot_uint16_t3 +define noundef i16 @dot_uint16_t3(<3 x i16> noundef %a, <3 x i16> noundef %b) { +entry: +; CHECK: extractelement <3 x i16> %a, i64 0 +; CHECK: extractelement <3 x i16> %b, i64 0 +; CHECK: mul i16 %{{.*}}, %{{.*}} +; CHECK: extractelement <3 x i16> %a, i64 1 +; CHECK: extractelement <3 x i16> %b, i64 1 +; EXPCHECK: call i16 @llvm.dx.umad.i16(i16 %{{.*}}, i16 %{{.*}}, i16 %{{.*}}) +; DOPCHECK: call i16 @dx.op.tertiary.i16(i32 49, i16 %{{.*}}, i16 %{{.*}}, i16 %{{.*}}) +; CHECK: extractelement <3 x i16> %a, i64 2 +; CHECK: extractelement <3 x i16> %b, i64 2 +; EXPCHECK: call i16 @llvm.dx.umad.i16(i16 %{{.*}}, i16 %{{.*}}, i16 %{{.*}}) +; DOPCHECK: call i16 @dx.op.tertiary.i16(i32 49, i16 %{{.*}}, i16 %{{.*}}, i16 %{{.*}}) + %dx.dot = call i16 @llvm.dx.udot.v3i16(<3 x i16> %a, <3 x i16> %b) + ret i16 %dx.dot +} + +; CHECK-LABEL: dot_uint4 +define noundef i32 @dot_uint4(<4 x i32> noundef %a, <4 x i32> noundef %b) { +entry: +; CHECK: extractelement <4 x i32> %a, i64 0 +; CHECK: extractelement <4 x i32> %b, i64 0 +; CHECK: mul i32 %{{.*}}, %{{.*}} +; CHECK: extractelement <4 x i32> %a, i64 1 +; CHECK: extractelement <4 x i32> %b, i64 1 +; EXPCHECK: call i32 @llvm.dx.umad.i32(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) +; DOPCHECK: call i32 @dx.op.tertiary.i32(i32 49, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) +; CHECK: extractelement <4 x i32> %a, i64 2 +; CHECK: extractelement <4 x i32> %b, i64 2 +; EXPCHECK: call i32 @llvm.dx.umad.i32(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) +; DOPCHECK: call i32 @dx.op.tertiary.i32(i32 49, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) +; CHECK: extractelement <4 x i32> %a, i64 3 +; CHECK: extractelement <4 x i32> %b, i64 3 +; EXPCHECK: call i32 @llvm.dx.umad.i32(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) +; DOPCHECK: call i32 @dx.op.tertiary.i32(i32 49, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) + %dx.dot = call i32 @llvm.dx.udot.v4i32(<4 x i32> %a, <4 x i32> %b) + ret i32 %dx.dot +} + +; CHECK-LABEL: dot_uint64_t4 +define noundef i64 @dot_uint64_t4(<2 x i64> noundef %a, <2 x i64> noundef %b) { +entry: +; CHECK: extractelement <2 x i64> %a, i64 0 +; CHECK: extractelement <2 x i64> %b, i64 0 +; CHECK: mul i64 %{{.*}}, %{{.*}} +; CHECK: extractelement <2 x i64> %a, i64 1 +; CHECK: extractelement <2 x i64> %b, i64 1 +; EXPCHECK: call i64 @llvm.dx.umad.i64(i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) +; DOPCHECK: call i64 @dx.op.tertiary.i64(i32 49, i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) + %dx.dot = call i64 @llvm.dx.udot.v2i64(<2 x i64> %a, <2 x i64> %b) + ret i64 %dx.dot +} + +declare i16 @llvm.dx.sdot.v2i16(<2 x i16>, <2 x i16>) +declare i32 @llvm.dx.sdot.v4i32(<4 x i32>, <4 x i32>) +declare i16 @llvm.dx.udot.v3i32(<3 x i16>, <3 x i16>) +declare i32 @llvm.dx.udot.v4i32(<4 x i32>, <4 x i32>) +declare i64 @llvm.dx.udot.v2i64(<2 x i64>, <2 x i64>) -- GitLab From 252e2551eab9b59f7dcbf8bb79a1432884d546e4 Mon Sep 17 00:00:00 2001 From: Christian Ulmann <christianulmann@gmail.com> Date: Tue, 19 Mar 2024 17:18:28 +0100 Subject: [PATCH 104/307] [MLIR][LLVM][SROA] Avoid splitting dynamically indexed allocas (#85758) This commit ensures that SROA does no longer attempt to split allocas that are indexed into dynamically. Dynamic indices into arrays are allowed to be negative or out-of-bounds, when the alloca containing the array has memory backing these produced indices. --- mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp | 8 ++++++++ mlir/test/Dialect/LLVMIR/sroa.mlir | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp index bf24194d03dd..81766b307d3d 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp @@ -344,6 +344,10 @@ LogicalResult LLVM::GEPOp::ensureOnlySafeAccesses( return failure(); if (!isFirstIndexZero(*this)) return failure(); + // Dynamic indices can be out-of-bounds (even negative), so an access with + // dynamic indices can never be considered safe. + if (!getDynamicIndices().empty()) + return failure(); Type reachedType = getResultPtrElementType(); if (!reachedType) return failure(); @@ -362,6 +366,10 @@ bool LLVM::GEPOp::canRewire(const DestructurableMemorySlot &slot, return false; if (!isFirstIndexZero(*this)) return false; + // Dynamic indices can be out-of-bounds (even negative), so an access with + // dynamic indices can never be properly rewired. + if (!getDynamicIndices().empty()) + return false; Type reachedType = getResultPtrElementType(); if (!reachedType || getIndices().size() < 2) return false; diff --git a/mlir/test/Dialect/LLVMIR/sroa.mlir b/mlir/test/Dialect/LLVMIR/sroa.mlir index f56ea53ac029..02d25f27f978 100644 --- a/mlir/test/Dialect/LLVMIR/sroa.mlir +++ b/mlir/test/Dialect/LLVMIR/sroa.mlir @@ -197,3 +197,21 @@ llvm.func @no_dynamic_indexing(%arg: i32) -> i32 { // CHECK: llvm.return %[[RES]] : i32 llvm.return %3 : i32 } + +// ----- + +// CHECK-LABEL: llvm.func @no_nested_dynamic_indexing +// CHECK-SAME: (%[[ARG:.*]]: i32) +llvm.func @no_nested_dynamic_indexing(%arg: i32) -> i32 { + // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) + %0 = llvm.mlir.constant(1 : i32) : i32 + // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x !llvm.struct<(array<10 x i32>, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr + %1 = llvm.alloca %0 x !llvm.struct<(array<10 x i32>, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr + // CHECK-NOT: = llvm.alloca + // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ALLOCA]][0, 0, %[[ARG]]] + %2 = llvm.getelementptr %1[0, 0, %arg] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<(array<10 x i32>, i32)> + // CHECK: %[[RES:.*]] = llvm.load %[[GEP]] + %3 = llvm.load %2 : !llvm.ptr -> i32 + // CHECK: llvm.return %[[RES]] : i32 + llvm.return %3 : i32 +} -- GitLab From c63a291c64852a086cb447c7078e5312aac1a05c Mon Sep 17 00:00:00 2001 From: Nick Desaulniers <nickdesaulniers@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:25:57 -0700 Subject: [PATCH 105/307] [libc][cpp] reverse_iterator support (#85702) Towards the goal of implementing __cxa_finalize (#85651) I'd like to be able to reverse iterate over cpp::arrays such as the one used in FixedVector. Implement the enough iterator support to be able to iterate a cpp::array in reverse, and add tests. Of note, reverse iterator's begin() refers to forward iterator's end() (and vice versa). When dereferenced (operator*), the reverse iterator returns a copy that's been pre-decremented (the underlying forward iterator is advanced). --- libc/src/__support/CPP/array.h | 23 ++++++++ libc/src/__support/CPP/iterator.h | 63 +++++++++++++++++++++ libc/test/src/__support/CPP/CMakeLists.txt | 10 ++++ libc/test/src/__support/CPP/array_test.cpp | 66 ++++++++++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 libc/src/__support/CPP/iterator.h create mode 100644 libc/test/src/__support/CPP/array_test.cpp diff --git a/libc/src/__support/CPP/array.h b/libc/src/__support/CPP/array.h index fb5a79225beb..4e69ba003e80 100644 --- a/libc/src/__support/CPP/array.h +++ b/libc/src/__support/CPP/array.h @@ -9,6 +9,7 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_ARRAY_H #define LLVM_LIBC_SRC___SUPPORT_CPP_ARRAY_H +#include "src/__support/CPP/iterator.h" // reverse_iterator #include "src/__support/macros/attributes.h" #include <stddef.h> // For size_t. @@ -23,6 +24,8 @@ template <class T, size_t N> struct array { using value_type = T; using iterator = T *; using const_iterator = const T *; + using reverse_iterator = cpp::reverse_iterator<iterator>; + using const_reverse_iterator = cpp::reverse_iterator<const_iterator>; LIBC_INLINE constexpr T *data() { return Data; } LIBC_INLINE constexpr const T *data() const { return Data; } @@ -45,9 +48,29 @@ template <class T, size_t N> struct array { LIBC_INLINE constexpr iterator begin() { return Data; } LIBC_INLINE constexpr const_iterator begin() const { return Data; } + LIBC_INLINE constexpr const_iterator cbegin() const { return begin(); } LIBC_INLINE constexpr iterator end() { return Data + N; } LIBC_INLINE constexpr const_iterator end() const { return Data + N; } + LIBC_INLINE constexpr const_iterator cend() const { return end(); } + + LIBC_INLINE constexpr reverse_iterator rbegin() { + return reverse_iterator{end()}; + } + LIBC_INLINE constexpr const_reverse_iterator rbegin() const { + return const_reverse_iterator{end()}; + } + LIBC_INLINE constexpr const_reverse_iterator crbegin() const { + return rbegin(); + } + + LIBC_INLINE constexpr reverse_iterator rend() { + return reverse_iterator{begin()}; + } + LIBC_INLINE constexpr const_reverse_iterator rend() const { + return const_reverse_iterator{begin()}; + } + LIBC_INLINE constexpr const_reverse_iterator crend() const { return rend(); } }; } // namespace cpp diff --git a/libc/src/__support/CPP/iterator.h b/libc/src/__support/CPP/iterator.h new file mode 100644 index 000000000000..c5bfb1912c7b --- /dev/null +++ b/libc/src/__support/CPP/iterator.h @@ -0,0 +1,63 @@ +//===-- Standalone implementation of iterator -------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_ITERATOR_H +#define LLVM_LIBC_SRC___SUPPORT_CPP_ITERATOR_H + +#include "src/__support/CPP/type_traits/enable_if.h" +#include "src/__support/CPP/type_traits/is_convertible.h" +#include "src/__support/CPP/type_traits/is_same.h" +#include "src/__support/macros/attributes.h" + +namespace LIBC_NAMESPACE { +namespace cpp { + +template <typename T> struct iterator_traits; +template <typename T> struct iterator_traits<T *> { + using reference = T &; +}; + +template <typename Iter> class reverse_iterator { + Iter current; + +public: + using reference = typename iterator_traits<Iter>::reference; + + LIBC_INLINE reverse_iterator() : current() {} + LIBC_INLINE constexpr explicit reverse_iterator(Iter it) : current(it) {} + + template <typename Other, + cpp::enable_if_t<!cpp::is_same_v<Iter, Other> && + cpp::is_convertible_v<const Other &, Iter>, + int> = 0> + LIBC_INLINE constexpr explicit reverse_iterator(const Other &it) + : current(it) {} + + LIBC_INLINE constexpr reference operator*() const { + Iter tmp = current; + return *--tmp; + } + LIBC_INLINE constexpr reverse_iterator operator--() { + ++current; + return *this; + } + LIBC_INLINE constexpr reverse_iterator &operator++() { + --current; + return *this; + } + LIBC_INLINE constexpr reverse_iterator operator++(int) { + reverse_iterator tmp(*this); + --current; + return tmp; + } +}; + +} // namespace cpp +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC___SUPPORT_CPP_ITERATOR_H diff --git a/libc/test/src/__support/CPP/CMakeLists.txt b/libc/test/src/__support/CPP/CMakeLists.txt index f94429e03b3c..74aa0c705ec4 100644 --- a/libc/test/src/__support/CPP/CMakeLists.txt +++ b/libc/test/src/__support/CPP/CMakeLists.txt @@ -1,5 +1,15 @@ add_custom_target(libc-cpp-utils-tests) +add_libc_test( + array_test + SUITE + libc-cpp-utils-tests + SRCS + array_test.cpp + DEPENDS + libc.src.__support.CPP.array + ) + add_libc_test( bit_test SUITE diff --git a/libc/test/src/__support/CPP/array_test.cpp b/libc/test/src/__support/CPP/array_test.cpp new file mode 100644 index 000000000000..f2d7bff636e4 --- /dev/null +++ b/libc/test/src/__support/CPP/array_test.cpp @@ -0,0 +1,66 @@ +//===-- Unittests for Array -----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/CPP/array.h" +#include "test/UnitTest/Test.h" + +using LIBC_NAMESPACE::cpp::array; + +TEST(LlvmLibcArrayTest, Basic) { + array<int, 3> a = {0, 1, 2}; + + ASSERT_EQ(a.data(), &a.front()); + ASSERT_EQ(a.front(), 0); + ASSERT_EQ(a.back(), 2); + ASSERT_EQ(a.size(), size_t{3}); + ASSERT_EQ(a[1], 1); + ASSERT_FALSE(a.empty()); + ASSERT_NE(a.begin(), a.end()); + ASSERT_EQ(*a.begin(), a.front()); + + auto it = a.rbegin(); + ASSERT_EQ(*it, 2); + ASSERT_EQ(*(++it), 1); + ASSERT_EQ(*(++it), 0); + + for (int &x : a) + ASSERT_GE(x, 0); +} + +// Test const_iterator and const variant methods. +TEST(LlvmLibcArrayTest, Const) { + const array<int, 3> z = {3, 4, 5}; + + ASSERT_EQ(3, z.front()); + ASSERT_EQ(4, z[1]); + ASSERT_EQ(5, z.back()); + ASSERT_EQ(3, *z.data()); + + // begin, cbegin, end, cend + array<int, 3>::const_iterator it2 = z.begin(); + ASSERT_EQ(*it2, z.front()); + it2 = z.cbegin(); + ASSERT_EQ(*it2, z.front()); + it2 = z.end(); + ASSERT_NE(it2, z.begin()); + it2 = z.cend(); + ASSERT_NE(it2, z.begin()); + + // rbegin, crbegin, rend, crend + array<int, 3>::const_reverse_iterator it = z.rbegin(); + ASSERT_EQ(*it, z.back()); + it = z.crbegin(); + ASSERT_EQ(*it, z.back()); + it = z.rend(); + ASSERT_EQ(*--it, z.front()); + it = z.crend(); + ASSERT_EQ(*--it, z.front()); + + for (const int &x : z) + ASSERT_GE(x, 0); +} -- GitLab From b9d83eff254668385fd3d9d5ddb5af762f378d7f Mon Sep 17 00:00:00 2001 From: Jeremy Morse <jeremy.morse@sony.com> Date: Tue, 19 Mar 2024 16:36:29 +0000 Subject: [PATCH 106/307] [NFC][RemoveDIs] Use iterators for insertion at various call-sites (#84736) These are the last remaining "trivial" changes to passes that use Instruction pointers for insertion. All of this should be NFC, it's just changing the spelling of how we identify a position. In one or two locations, I'm also switching uses of getNextNode etc to using std::next with iterators. This too should be NFC. --------- Merged by: Stephen Tozer <stephen.tozer@sony.com> --- llvm/lib/Analysis/PHITransAddr.cpp | 11 +++--- llvm/lib/CodeGen/CodeGenPrepare.cpp | 25 ++++++------ llvm/lib/CodeGen/DwarfEHPrepare.cpp | 5 ++- llvm/lib/CodeGen/GCRootLowering.cpp | 9 +++-- llvm/lib/CodeGen/IndirectBrExpandPass.cpp | 13 ++++--- llvm/lib/CodeGen/InterleavedAccessPass.cpp | 7 ++-- llvm/lib/CodeGen/IntrinsicLowering.cpp | 2 +- llvm/lib/CodeGen/JMCInstrumenter.cpp | 2 +- llvm/lib/CodeGen/SjLjEHPrepare.cpp | 17 +++++---- llvm/lib/CodeGen/WinEHPrepare.cpp | 16 ++++---- llvm/lib/Passes/PassBuilder.cpp | 2 +- .../AArch64/AArch64TargetTransformInfo.cpp | 2 +- llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp | 10 +++-- .../AMDGPU/AMDGPUPrintfRuntimeBinding.cpp | 18 +++++---- .../Target/ARM/MVEGatherScatterLowering.cpp | 38 +++++++++++-------- .../Target/BPF/BPFAbstractMemberAccess.cpp | 14 ++++--- llvm/lib/Target/BPF/BPFPreserveDIType.cpp | 4 +- llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp | 2 +- llvm/lib/Target/Mips/Mips16HardFloat.cpp | 2 +- llvm/lib/Target/NVPTX/NVPTXImageOptimizer.cpp | 2 +- llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp | 14 +++---- .../Target/NVPTX/NVPTXLowerUnreachable.cpp | 2 +- llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp | 3 +- .../Target/PowerPC/PPCLoopInstrFormPrep.cpp | 27 +++++++------ .../RISCV/RISCVGatherScatterLowering.cpp | 2 +- .../WebAssemblyLowerEmscriptenEHSjLj.cpp | 6 +-- .../WebAssemblyLowerRefTypesIntPtrConv.cpp | 2 +- llvm/lib/Target/X86/X86LowerAMXType.cpp | 4 +- polly/lib/CodeGen/IslNodeBuilder.cpp | 7 ++-- polly/lib/CodeGen/LoopGenerators.cpp | 2 +- polly/lib/Support/ScopHelper.cpp | 5 ++- 31 files changed, 152 insertions(+), 123 deletions(-) diff --git a/llvm/lib/Analysis/PHITransAddr.cpp b/llvm/lib/Analysis/PHITransAddr.cpp index 5700fd664a4c..d16dec0d4292 100644 --- a/llvm/lib/Analysis/PHITransAddr.cpp +++ b/llvm/lib/Analysis/PHITransAddr.cpp @@ -369,7 +369,7 @@ Value *PHITransAddr::insertTranslatedSubExpr( // Otherwise insert a cast at the end of PredBB. CastInst *New = CastInst::Create(Cast->getOpcode(), OpVal, InVal->getType(), InVal->getName() + ".phi.trans.insert", - PredBB->getTerminator()); + PredBB->getTerminator()->getIterator()); New->setDebugLoc(Inst->getDebugLoc()); NewInsts.push_back(New); return New; @@ -387,7 +387,8 @@ Value *PHITransAddr::insertTranslatedSubExpr( GetElementPtrInst *Result = GetElementPtrInst::Create( GEP->getSourceElementType(), GEPOps[0], ArrayRef(GEPOps).slice(1), - InVal->getName() + ".phi.trans.insert", PredBB->getTerminator()); + InVal->getName() + ".phi.trans.insert", + PredBB->getTerminator()->getIterator()); Result->setDebugLoc(Inst->getDebugLoc()); Result->setIsInBounds(GEP->isInBounds()); NewInsts.push_back(Result); @@ -408,9 +409,9 @@ Value *PHITransAddr::insertTranslatedSubExpr( if (OpVal == nullptr) return nullptr; - BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1), - InVal->getName()+".phi.trans.insert", - PredBB->getTerminator()); + BinaryOperator *Res = BinaryOperator::CreateAdd( + OpVal, Inst->getOperand(1), InVal->getName() + ".phi.trans.insert", + PredBB->getTerminator()->getIterator()); Res->setHasNoSignedWrap(cast<BinaryOperator>(Inst)->hasNoSignedWrap()); Res->setHasNoUnsignedWrap(cast<BinaryOperator>(Inst)->hasNoUnsignedWrap()); NewInsts.push_back(Res); diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 921a5b710683..e7bf656491da 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -2057,9 +2057,9 @@ static bool sinkAndCmp0Expression(Instruction *AndI, const TargetLowering &TLI, // Keep the 'and' in the same place if the use is already in the same block. Instruction *InsertPt = User->getParent() == AndI->getParent() ? AndI : User; - Instruction *InsertedAnd = - BinaryOperator::Create(Instruction::And, AndI->getOperand(0), - AndI->getOperand(1), "", InsertPt); + Instruction *InsertedAnd = BinaryOperator::Create( + Instruction::And, AndI->getOperand(0), AndI->getOperand(1), "", + InsertPt->getIterator()); // Propagate the debug info. InsertedAnd->setDebugLoc(AndI->getDebugLoc()); @@ -4153,9 +4153,10 @@ private: if (SelectInst *CurrentSelect = dyn_cast<SelectInst>(Current)) { // Is it OK to get metadata from OrigSelect?! // Create a Select placeholder with dummy value. - SelectInst *Select = SelectInst::Create( - CurrentSelect->getCondition(), Dummy, Dummy, - CurrentSelect->getName(), CurrentSelect, CurrentSelect); + SelectInst *Select = + SelectInst::Create(CurrentSelect->getCondition(), Dummy, Dummy, + CurrentSelect->getName(), + CurrentSelect->getIterator(), CurrentSelect); Map[Current] = Select; ST.insertNewSelect(Select); // We are interested in True and False values. @@ -6466,8 +6467,8 @@ bool CodeGenPrepare::optimizePhiType( ValMap[D] = D->getOperand(0); DeletedInstrs.insert(D); } else { - ValMap[D] = - new BitCastInst(D, ConvertTy, D->getName() + ".bc", D->getNextNode()); + BasicBlock::iterator insertPt = std::next(D->getIterator()); + ValMap[D] = new BitCastInst(D, ConvertTy, D->getName() + ".bc", insertPt); } } for (PHINode *Phi : PhiNodes) @@ -6487,8 +6488,8 @@ bool CodeGenPrepare::optimizePhiType( DeletedInstrs.insert(U); replaceAllUsesWith(U, ValMap[U->getOperand(0)], FreshBBs, IsHugeFunc); } else { - U->setOperand(0, - new BitCastInst(ValMap[U->getOperand(0)], PhiTy, "bc", U)); + U->setOperand(0, new BitCastInst(ValMap[U->getOperand(0)], PhiTy, "bc", + U->getIterator())); } } @@ -8384,7 +8385,7 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) { if (GEPI->hasAllZeroIndices()) { /// The GEP operand must be a pointer, so must its result -> BitCast Instruction *NC = new BitCastInst(GEPI->getOperand(0), GEPI->getType(), - GEPI->getName(), GEPI); + GEPI->getName(), GEPI->getIterator()); NC->setDebugLoc(GEPI->getDebugLoc()); replaceAllUsesWith(GEPI, NC, FreshBBs, IsHugeFunc); RecursivelyDeleteTriviallyDeadInstructions( @@ -8416,7 +8417,7 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) { isa<ConstantPointerNull>(Op1); if (Const0 || Const1) { if (!Const0 || !Const1) { - auto *F = new FreezeInst(Const0 ? Op1 : Op0, "", CmpI); + auto *F = new FreezeInst(Const0 ? Op1 : Op0, "", CmpI->getIterator()); F->takeName(FI); CmpI->setOperand(Const0 ? 1 : 0, F); } diff --git a/llvm/lib/CodeGen/DwarfEHPrepare.cpp b/llvm/lib/CodeGen/DwarfEHPrepare.cpp index e7eb34d8e651..09e7cfb12bdb 100644 --- a/llvm/lib/CodeGen/DwarfEHPrepare.cpp +++ b/llvm/lib/CodeGen/DwarfEHPrepare.cpp @@ -111,7 +111,8 @@ Value *DwarfEHPrepare::GetExceptionObject(ResumeInst *RI) { } if (!ExnObj) - ExnObj = ExtractValueInst::Create(RI->getOperand(0), 0, "exn.obj", RI); + ExnObj = ExtractValueInst::Create(RI->getOperand(0), 0, "exn.obj", + RI->getIterator()); RI->eraseFromParent(); @@ -158,7 +159,7 @@ size_t DwarfEHPrepare::pruneUnreachableResumes( Resumes[ResumesLeft++] = RI; } else { BasicBlock *BB = RI->getParent(); - new UnreachableInst(Ctx, RI); + new UnreachableInst(Ctx, RI->getIterator()); RI->eraseFromParent(); simplifyCFG(BB, *TTI, DTU); } diff --git a/llvm/lib/CodeGen/GCRootLowering.cpp b/llvm/lib/CodeGen/GCRootLowering.cpp index 0d82f2bab896..700714d53984 100644 --- a/llvm/lib/CodeGen/GCRootLowering.cpp +++ b/llvm/lib/CodeGen/GCRootLowering.cpp @@ -181,7 +181,7 @@ static bool InsertRootInitializers(Function &F, ArrayRef<AllocaInst *> Roots) { if (!InitedRoots.count(Root)) { new StoreInst( ConstantPointerNull::get(cast<PointerType>(Root->getAllocatedType())), - Root, Root->getNextNode()); + Root, std::next(Root->getIterator())); MadeChange = true; } @@ -216,8 +216,8 @@ bool DoLowering(Function &F, GCStrategy &S) { default: break; case Intrinsic::gcwrite: { // Replace a write barrier with a simple store. - Value *St = new StoreInst(CI->getArgOperand(0), - CI->getArgOperand(2), CI); + Value *St = new StoreInst(CI->getArgOperand(0), CI->getArgOperand(2), + CI->getIterator()); CI->replaceAllUsesWith(St); CI->eraseFromParent(); MadeChange = true; @@ -225,7 +225,8 @@ bool DoLowering(Function &F, GCStrategy &S) { } case Intrinsic::gcread: { // Replace a read barrier with a simple load. - Value *Ld = new LoadInst(CI->getType(), CI->getArgOperand(1), "", CI); + Value *Ld = new LoadInst(CI->getType(), CI->getArgOperand(1), "", + CI->getIterator()); Ld->takeName(CI); CI->replaceAllUsesWith(Ld); CI->eraseFromParent(); diff --git a/llvm/lib/CodeGen/IndirectBrExpandPass.cpp b/llvm/lib/CodeGen/IndirectBrExpandPass.cpp index f7b931a3bdac..13f595bef8ee 100644 --- a/llvm/lib/CodeGen/IndirectBrExpandPass.cpp +++ b/llvm/lib/CodeGen/IndirectBrExpandPass.cpp @@ -113,7 +113,7 @@ bool runImpl(Function &F, const TargetLowering *TLI, DomTreeUpdater *DTU) { // Handle the degenerate case of no successors by replacing the indirectbr // with unreachable as there is no successor available. if (IBr->getNumSuccessors() == 0) { - (void)new UnreachableInst(F.getContext(), IBr); + (void)new UnreachableInst(F.getContext(), IBr->getIterator()); IBr->eraseFromParent(); continue; } @@ -183,7 +183,7 @@ bool runImpl(Function &F, const TargetLowering *TLI, DomTreeUpdater *DTU) { for (BasicBlock *SuccBB : IBr->successors()) Updates.push_back({DominatorTree::Delete, IBr->getParent(), SuccBB}); } - (void)new UnreachableInst(F.getContext(), IBr); + (void)new UnreachableInst(F.getContext(), IBr->getIterator()); IBr->eraseFromParent(); } if (DTU) { @@ -207,9 +207,10 @@ bool runImpl(Function &F, const TargetLowering *TLI, DomTreeUpdater *DTU) { } auto GetSwitchValue = [CommonITy](IndirectBrInst *IBr) { - return CastInst::CreatePointerCast( - IBr->getAddress(), CommonITy, - Twine(IBr->getAddress()->getName()) + ".switch_cast", IBr); + return CastInst::CreatePointerCast(IBr->getAddress(), CommonITy, + Twine(IBr->getAddress()->getName()) + + ".switch_cast", + IBr->getIterator()); }; SmallVector<DominatorTree::UpdateType, 8> Updates; @@ -243,7 +244,7 @@ bool runImpl(Function &F, const TargetLowering *TLI, DomTreeUpdater *DTU) { Updates.reserve(IndirectBrs.size() + 2 * IndirectBrSuccs.size()); for (auto *IBr : IndirectBrs) { SwitchPN->addIncoming(GetSwitchValue(IBr), IBr->getParent()); - BranchInst::Create(SwitchBB, IBr); + BranchInst::Create(SwitchBB, IBr->getIterator()); if (DTU) { Updates.push_back({DominatorTree::Insert, IBr->getParent(), SwitchBB}); for (BasicBlock *SuccBB : IBr->successors()) diff --git a/llvm/lib/CodeGen/InterleavedAccessPass.cpp b/llvm/lib/CodeGen/InterleavedAccessPass.cpp index 2a0daf404c97..438ac1c3cc6e 100644 --- a/llvm/lib/CodeGen/InterleavedAccessPass.cpp +++ b/llvm/lib/CodeGen/InterleavedAccessPass.cpp @@ -388,14 +388,15 @@ bool InterleavedAccessImpl::replaceBinOpShuffles( return Idx < (int)cast<FixedVectorType>(BIOp0Ty)->getNumElements(); })); + BasicBlock::iterator insertPos = SVI->getIterator(); auto *NewSVI1 = new ShuffleVectorInst(BI->getOperand(0), PoisonValue::get(BIOp0Ty), - Mask, SVI->getName(), SVI); + Mask, SVI->getName(), insertPos); auto *NewSVI2 = new ShuffleVectorInst( BI->getOperand(1), PoisonValue::get(BI->getOperand(1)->getType()), Mask, - SVI->getName(), SVI); + SVI->getName(), insertPos); BinaryOperator *NewBI = BinaryOperator::CreateWithCopiedFlags( - BI->getOpcode(), NewSVI1, NewSVI2, BI, BI->getName(), SVI); + BI->getOpcode(), NewSVI1, NewSVI2, BI, BI->getName(), insertPos); SVI->replaceAllUsesWith(NewBI); LLVM_DEBUG(dbgs() << " Replaced: " << *BI << "\n And : " << *SVI << "\n With : " << *NewSVI1 << "\n And : " diff --git a/llvm/lib/CodeGen/IntrinsicLowering.cpp b/llvm/lib/CodeGen/IntrinsicLowering.cpp index fe450cba4a33..09d282d12c5f 100644 --- a/llvm/lib/CodeGen/IntrinsicLowering.cpp +++ b/llvm/lib/CodeGen/IntrinsicLowering.cpp @@ -472,7 +472,7 @@ bool IntrinsicLowering::LowerToByteSwap(CallInst *CI) { Function *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Ty); Value *Op = CI->getArgOperand(0); - Op = CallInst::Create(Int, Op, CI->getName(), CI); + Op = CallInst::Create(Int, Op, CI->getName(), CI->getIterator()); CI->replaceAllUsesWith(Op); CI->eraseFromParent(); diff --git a/llvm/lib/CodeGen/JMCInstrumenter.cpp b/llvm/lib/CodeGen/JMCInstrumenter.cpp index 62a381918875..e2aaebedf5a4 100644 --- a/llvm/lib/CodeGen/JMCInstrumenter.cpp +++ b/llvm/lib/CodeGen/JMCInstrumenter.cpp @@ -227,7 +227,7 @@ bool runImpl(Module &M) { // FIXME: it would be nice to make CI scheduling boundary, although in // practice it does not matter much. auto *CI = CallInst::Create(getCheckFunctionType(Ctx), CheckFunction, - {Flag}, "", &*F.begin()->getFirstInsertionPt()); + {Flag}, "", F.begin()->getFirstInsertionPt()); CI->addParamAttr(0, Attribute::NoUndef); if (UseX86FastCall) { CI->setCallingConv(CallingConv::X86_FastCall); diff --git a/llvm/lib/CodeGen/SjLjEHPrepare.cpp b/llvm/lib/CodeGen/SjLjEHPrepare.cpp index 4bad57d279e9..20c827ce08d8 100644 --- a/llvm/lib/CodeGen/SjLjEHPrepare.cpp +++ b/llvm/lib/CodeGen/SjLjEHPrepare.cpp @@ -202,7 +202,7 @@ SjLjEHPrepareImpl::setupFunctionContext(Function &F, auto &DL = F.getParent()->getDataLayout(); const Align Alignment = DL.getPrefTypeAlign(FunctionContextTy); FuncCtx = new AllocaInst(FunctionContextTy, DL.getAllocaAddrSpace(), nullptr, - Alignment, "fn_context", &EntryBB->front()); + Alignment, "fn_context", EntryBB->begin()); // Fill in the function context structure. for (LandingPadInst *LPI : LPads) { @@ -271,7 +271,7 @@ void SjLjEHPrepareImpl::lowerIncomingArguments(Function &F) { Value *TrueValue = ConstantInt::getTrue(F.getContext()); Value *UndefValue = UndefValue::get(Ty); Instruction *SI = SelectInst::Create( - TrueValue, &AI, UndefValue, AI.getName() + ".tmp", &*AfterAllocaInsPt); + TrueValue, &AI, UndefValue, AI.getName() + ".tmp", AfterAllocaInsPt); AI.replaceAllUsesWith(SI); // Reset the operand, because it was clobbered by the RAUW above. @@ -386,7 +386,7 @@ bool SjLjEHPrepareImpl::setupEntryBlockAndCallSites(Function &F) { if (Function *Callee = II->getCalledFunction()) if (Callee->getIntrinsicID() == Intrinsic::donothing) { // Remove the NOP invoke. - BranchInst::Create(II->getNormalDest(), II); + BranchInst::Create(II->getNormalDest(), II->getIterator()); II->eraseFromParent(); continue; } @@ -445,7 +445,7 @@ bool SjLjEHPrepareImpl::setupEntryBlockAndCallSites(Function &F) { // Record the call site value for the back end so it stays associated with // the invoke. - CallInst::Create(CallSiteFn, CallSiteNum, "", Invokes[I]); + CallInst::Create(CallSiteFn, CallSiteNum, "", Invokes[I]->getIterator()); } // Mark call instructions that aren't nounwind as no-action (call_site == @@ -462,8 +462,8 @@ bool SjLjEHPrepareImpl::setupEntryBlockAndCallSites(Function &F) { } // Register the function context and make sure it's known to not throw - CallInst *Register = - CallInst::Create(RegisterFn, FuncCtx, "", EntryBB->getTerminator()); + CallInst *Register = CallInst::Create( + RegisterFn, FuncCtx, "", EntryBB->getTerminator()->getIterator()); Register->setDoesNotThrow(); // Following any allocas not in the entry block, update the saved SP in the @@ -480,7 +480,8 @@ bool SjLjEHPrepareImpl::setupEntryBlockAndCallSites(Function &F) { } Instruction *StackAddr = CallInst::Create(StackAddrFn, "sp"); StackAddr->insertAfter(&I); - new StoreInst(StackAddr, StackPtr, true, StackAddr->getNextNode()); + new StoreInst(StackAddr, StackPtr, true, + std::next(StackAddr->getIterator())); } } @@ -490,7 +491,7 @@ bool SjLjEHPrepareImpl::setupEntryBlockAndCallSites(Function &F) { Instruction *InsertPoint = Return; if (CallInst *CI = Return->getParent()->getTerminatingMustTailCall()) InsertPoint = CI; - CallInst::Create(UnregisterFn, FuncCtx, "", InsertPoint); + CallInst::Create(UnregisterFn, FuncCtx, "", InsertPoint->getIterator()); } return true; diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp index 95976c218c2f..93a18f5bc9e8 100644 --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -1234,10 +1234,10 @@ AllocaInst *WinEHPrepareImpl::insertPHILoads(PHINode *PN, Function &F) { // that will dominate all uses. SpillSlot = new AllocaInst(PN->getType(), DL->getAllocaAddrSpace(), nullptr, Twine(PN->getName(), ".wineh.spillslot"), - &F.getEntryBlock().front()); + F.getEntryBlock().begin()); Value *V = new LoadInst(PN->getType(), SpillSlot, Twine(PN->getName(), ".wineh.reload"), - &*PHIBlock->getFirstInsertionPt()); + PHIBlock->getFirstInsertionPt()); PN->replaceAllUsesWith(V); return SpillSlot; } @@ -1309,7 +1309,7 @@ void WinEHPrepareImpl::insertPHIStore( } // Otherwise, insert the store at the end of the basic block. - new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator()); + new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator()->getIterator()); } void WinEHPrepareImpl::replaceUseWithLoad( @@ -1319,7 +1319,7 @@ void WinEHPrepareImpl::replaceUseWithLoad( if (!SpillSlot) SpillSlot = new AllocaInst(V->getType(), DL->getAllocaAddrSpace(), nullptr, Twine(V->getName(), ".wineh.spillslot"), - &F.getEntryBlock().front()); + F.getEntryBlock().begin()); auto *UsingInst = cast<Instruction>(U.getUser()); if (auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) { @@ -1376,16 +1376,16 @@ void WinEHPrepareImpl::replaceUseWithLoad( Value *&Load = Loads[IncomingBlock]; // Insert the load into the predecessor block if (!Load) - Load = new LoadInst(V->getType(), SpillSlot, - Twine(V->getName(), ".wineh.reload"), - /*isVolatile=*/false, IncomingBlock->getTerminator()); + Load = new LoadInst( + V->getType(), SpillSlot, Twine(V->getName(), ".wineh.reload"), + /*isVolatile=*/false, IncomingBlock->getTerminator()->getIterator()); U.set(Load); } else { // Reload right before the old use. auto *Load = new LoadInst(V->getType(), SpillSlot, Twine(V->getName(), ".wineh.reload"), - /*isVolatile=*/false, UsingInst); + /*isVolatile=*/false, UsingInst->getIterator()); U.set(Load); } } diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 0204730f750a..9d98ae7dde52 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -358,7 +358,7 @@ public: // Intentionally break the Function by inserting a terminator // instruction in the middle of a basic block. BasicBlock &BB = F.getEntryBlock(); - new UnreachableInst(F.getContext(), BB.getTerminator()); + new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator()); return PreservedAnalyses::none(); } diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp index 755b034764ed..7a86c5c60881 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -1129,7 +1129,7 @@ static std::optional<Instruction *> instCombineSVELast(InstCombiner &IC, auto *NewRHS = IC.Builder.CreateIntrinsic(IntrinsicID, {Vec->getType()}, {Pg, RHS}); auto *NewBinOp = BinaryOperator::CreateWithCopiedFlags( - OpC, NewLHS, NewRHS, OldBinOp, OldBinOp->getName(), &II); + OpC, NewLHS, NewRHS, OldBinOp, OldBinOp->getName(), II.getIterator()); return IC.replaceInstUsesWith(II, NewBinOp); } } diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp index 2da896edc79a..84b4ccc1ae7b 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp @@ -470,9 +470,11 @@ bool AMDGPULibCalls::sincosUseNative(CallInst *aCI, const FuncInfo &FInfo) { nf.setId(AMDGPULibFunc::EI_COS); FunctionCallee cosExpr = getFunction(M, nf); if (sinExpr && cosExpr) { - Value *sinval = CallInst::Create(sinExpr, opr0, "splitsin", aCI); - Value *cosval = CallInst::Create(cosExpr, opr0, "splitcos", aCI); - new StoreInst(cosval, aCI->getArgOperand(1), aCI); + Value *sinval = + CallInst::Create(sinExpr, opr0, "splitsin", aCI->getIterator()); + Value *cosval = + CallInst::Create(cosExpr, opr0, "splitcos", aCI->getIterator()); + new StoreInst(cosval, aCI->getArgOperand(1), aCI->getIterator()); DEBUG_WITH_TYPE("usenative", dbgs() << "<useNative> replace " << *aCI << " with native version of sin/cos"); @@ -1655,7 +1657,7 @@ bool AMDGPULibCalls::evaluateCall(CallInst *aCI, const FuncInfo &FInfo) { // sincos assert(FInfo.getId() == AMDGPULibFunc::EI_SINCOS && "math function with ptr arg not supported yet"); - new StoreInst(nval1, aCI->getArgOperand(1), aCI); + new StoreInst(nval1, aCI->getArgOperand(1), aCI->getIterator()); } replaceCall(aCI, nval0); diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp index 7b5dc3795b02..aef0ade6d9be 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp @@ -290,8 +290,8 @@ bool AMDGPUPrintfRuntimeBindingImpl::lowerPrintfForGpu(Module &M) { Value *sumC = ConstantInt::get(SizetTy, Sum, false); SmallVector<Value *, 1> alloc_args; alloc_args.push_back(sumC); - CallInst *pcall = - CallInst::Create(PrintfAllocFn, alloc_args, "printf_alloc_fn", CI); + CallInst *pcall = CallInst::Create(PrintfAllocFn, alloc_args, + "printf_alloc_fn", CI->getIterator()); // // Insert code to split basicblock with a @@ -309,25 +309,27 @@ bool AMDGPUPrintfRuntimeBindingImpl::lowerPrintfForGpu(Module &M) { SplitBlock(CI->getParent(), cmp); Instruction *Brnch = SplitBlockAndInsertIfThen(cmp, cmp->getNextNode(), false); + BasicBlock::iterator BrnchPoint = Brnch->getIterator(); Builder.SetInsertPoint(Brnch); // store unique printf id in the buffer // GetElementPtrInst *BufferIdx = GetElementPtrInst::Create( - I8Ty, pcall, ConstantInt::get(Ctx, APInt(32, 0)), "PrintBuffID", Brnch); + I8Ty, pcall, ConstantInt::get(Ctx, APInt(32, 0)), "PrintBuffID", + BrnchPoint); Type *idPointer = PointerType::get(I32Ty, AMDGPUAS::GLOBAL_ADDRESS); Value *id_gep_cast = - new BitCastInst(BufferIdx, idPointer, "PrintBuffIdCast", Brnch); + new BitCastInst(BufferIdx, idPointer, "PrintBuffIdCast", BrnchPoint); - new StoreInst(ConstantInt::get(I32Ty, UniqID), id_gep_cast, Brnch); + new StoreInst(ConstantInt::get(I32Ty, UniqID), id_gep_cast, BrnchPoint); // 1st 4 bytes hold the printf_id // the following GEP is the buffer pointer BufferIdx = GetElementPtrInst::Create(I8Ty, pcall, ConstantInt::get(Ctx, APInt(32, 4)), - "PrintBuffGep", Brnch); + "PrintBuffGep", BrnchPoint); Type *Int32Ty = Type::getInt32Ty(Ctx); for (unsigned ArgCount = 1; @@ -405,7 +407,7 @@ bool AMDGPUPrintfRuntimeBindingImpl::lowerPrintfForGpu(Module &M) { for (unsigned I = 0, E = WhatToStore.size(); I != E; ++I) { Value *TheBtCast = WhatToStore[I]; unsigned ArgSize = TD->getTypeAllocSize(TheBtCast->getType()); - StoreInst *StBuff = new StoreInst(TheBtCast, BufferIdx, Brnch); + StoreInst *StBuff = new StoreInst(TheBtCast, BufferIdx, BrnchPoint); LLVM_DEBUG(dbgs() << "inserting store to printf buffer:\n" << *StBuff << '\n'); (void)StBuff; @@ -413,7 +415,7 @@ bool AMDGPUPrintfRuntimeBindingImpl::lowerPrintfForGpu(Module &M) { break; BufferIdx = GetElementPtrInst::Create( I8Ty, BufferIdx, {ConstantInt::get(I32Ty, ArgSize)}, - "PrintBuffNextPtr", Brnch); + "PrintBuffNextPtr", BrnchPoint); LLVM_DEBUG(dbgs() << "inserting gep to the printf buffer:\n" << *BufferIdx << '\n'); } diff --git a/llvm/lib/Target/ARM/MVEGatherScatterLowering.cpp b/llvm/lib/Target/ARM/MVEGatherScatterLowering.cpp index 404c280ab979..924a4580aa5f 100644 --- a/llvm/lib/Target/ARM/MVEGatherScatterLowering.cpp +++ b/llvm/lib/Target/ARM/MVEGatherScatterLowering.cpp @@ -780,8 +780,9 @@ Instruction *MVEGatherScatterLowering::tryCreateIncrementingGatScat( // Make sure the offsets are scaled correctly Instruction *ScaledOffsets = BinaryOperator::Create( Instruction::Shl, OffsetsIncoming, - Builder.CreateVectorSplat(Ty->getNumElements(), Builder.getInt32(TypeScale)), - "ScaledIndex", I); + Builder.CreateVectorSplat(Ty->getNumElements(), + Builder.getInt32(TypeScale)), + "ScaledIndex", I->getIterator()); // Add the base to the offsets OffsetsIncoming = BinaryOperator::Create( Instruction::Add, ScaledOffsets, @@ -790,7 +791,7 @@ Instruction *MVEGatherScatterLowering::tryCreateIncrementingGatScat( Builder.CreatePtrToInt( BasePtr, cast<VectorType>(ScaledOffsets->getType())->getElementType())), - "StartIndex", I); + "StartIndex", I->getIterator()); if (I->getIntrinsicID() == Intrinsic::masked_gather) return tryCreateMaskedGatherBase(I, OffsetsIncoming, Builder, Immediate); @@ -838,7 +839,8 @@ Instruction *MVEGatherScatterLowering::tryCreateIncrementingWBGatScat( Instruction *ScaledOffsets = BinaryOperator::Create( Instruction::Shl, Phi->getIncomingValue(1 - IncrementIndex), Builder.CreateVectorSplat(NumElems, Builder.getInt32(TypeScale)), - "ScaledIndex", &Phi->getIncomingBlock(1 - IncrementIndex)->back()); + "ScaledIndex", + Phi->getIncomingBlock(1 - IncrementIndex)->back().getIterator()); // Add the base to the offsets OffsetsIncoming = BinaryOperator::Create( Instruction::Add, ScaledOffsets, @@ -847,13 +849,14 @@ Instruction *MVEGatherScatterLowering::tryCreateIncrementingWBGatScat( Builder.CreatePtrToInt( BasePtr, cast<VectorType>(ScaledOffsets->getType())->getElementType())), - "StartIndex", &Phi->getIncomingBlock(1 - IncrementIndex)->back()); + "StartIndex", + Phi->getIncomingBlock(1 - IncrementIndex)->back().getIterator()); // The gather is pre-incrementing OffsetsIncoming = BinaryOperator::Create( Instruction::Sub, OffsetsIncoming, Builder.CreateVectorSplat(NumElems, Builder.getInt32(Immediate)), "PreIncrementStartIndex", - &Phi->getIncomingBlock(1 - IncrementIndex)->back()); + Phi->getIncomingBlock(1 - IncrementIndex)->back().getIterator()); Phi->setIncomingValue(1 - IncrementIndex, OffsetsIncoming); Builder.SetInsertPoint(I); @@ -886,8 +889,8 @@ void MVEGatherScatterLowering::pushOutAdd(PHINode *&Phi, Value *OffsSecondOperand, unsigned StartIndex) { LLVM_DEBUG(dbgs() << "masked gathers/scatters: optimising add instruction\n"); - Instruction *InsertionPoint = - &cast<Instruction>(Phi->getIncomingBlock(StartIndex)->back()); + BasicBlock::iterator InsertionPoint = + Phi->getIncomingBlock(StartIndex)->back().getIterator(); // Initialize the phi with a vector that contains a sum of the constants Instruction *NewIndex = BinaryOperator::Create( Instruction::Add, Phi->getIncomingValue(StartIndex), OffsSecondOperand, @@ -911,8 +914,8 @@ void MVEGatherScatterLowering::pushOutMulShl(unsigned Opcode, PHINode *&Phi, // Create a new scalar add outside of the loop and transform it to a splat // by which loop variable can be incremented - Instruction *InsertionPoint = &cast<Instruction>( - Phi->getIncomingBlock(LoopIncrement == 1 ? 0 : 1)->back()); + BasicBlock::iterator InsertionPoint = + Phi->getIncomingBlock(LoopIncrement == 1 ? 0 : 1)->back().getIterator(); // Create a new index Value *StartIndex = @@ -923,11 +926,14 @@ void MVEGatherScatterLowering::pushOutMulShl(unsigned Opcode, PHINode *&Phi, Instruction *Product = BinaryOperator::Create((Instruction::BinaryOps)Opcode, IncrementPerRound, OffsSecondOperand, "Product", InsertionPoint); + + BasicBlock::iterator NewIncrInsertPt = + Phi->getIncomingBlock(LoopIncrement)->back().getIterator(); + NewIncrInsertPt = std::prev(NewIncrInsertPt); + // Increment NewIndex by Product instead of the multiplication Instruction *NewIncrement = BinaryOperator::Create( - Instruction::Add, Phi, Product, "IncrementPushedOutMul", - cast<Instruction>(Phi->getIncomingBlock(LoopIncrement)->back()) - .getPrevNode()); + Instruction::Add, Phi, Product, "IncrementPushedOutMul", NewIncrInsertPt); Phi->addIncoming(StartIndex, Phi->getIncomingBlock(LoopIncrement == 1 ? 0 : 1)); @@ -1054,7 +1060,7 @@ bool MVEGatherScatterLowering::optimiseOffsets(Value *Offsets, BasicBlock *BB, // our phi, we need to copy it IncInstruction = BinaryOperator::Create( Instruction::BinaryOps(IncInstruction->getOpcode()), Phi, - IncrementPerRound, "LoopIncrement", IncInstruction); + IncrementPerRound, "LoopIncrement", IncInstruction->getIterator()); Phi->setIncomingValue(IncrementingBlock, IncInstruction); } NewPhi = Phi; @@ -1066,7 +1072,7 @@ bool MVEGatherScatterLowering::optimiseOffsets(Value *Offsets, BasicBlock *BB, Phi->getIncomingBlock(IncrementingBlock == 1 ? 0 : 1)); IncInstruction = BinaryOperator::Create( Instruction::BinaryOps(IncInstruction->getOpcode()), NewPhi, - IncrementPerRound, "LoopIncrement", IncInstruction); + IncrementPerRound, "LoopIncrement", IncInstruction->getIterator()); NewPhi->addIncoming(IncInstruction, Phi->getIncomingBlock(IncrementingBlock)); IncrementingBlock = 1; @@ -1229,7 +1235,7 @@ bool MVEGatherScatterLowering::optimiseAddress(Value *Address, BasicBlock *BB, BaseTy = FixedVectorType::get(BaseTy, VecTy); GetElementPtrInst *NewAddress = GetElementPtrInst::Create( Builder.getInt8Ty(), Builder.CreateBitCast(Base, BaseTy), Offsets, - "gep.merged", GEP); + "gep.merged", GEP->getIterator()); LLVM_DEBUG(dbgs() << "Folded GEP: " << *GEP << "\n new : " << *NewAddress << "\n"); GEP->replaceAllUsesWith( diff --git a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp index f2d1206d0231..4be6220b358b 100644 --- a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp +++ b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp @@ -426,8 +426,9 @@ static void replaceWithGEP(CallInst *Call, uint32_t DimensionIndex, IdxList.push_back(Zero); IdxList.push_back(Call->getArgOperand(GEPIndex)); - auto *GEP = GetElementPtrInst::CreateInBounds( - getBaseElementType(Call), Call->getArgOperand(0), IdxList, "", Call); + auto *GEP = GetElementPtrInst::CreateInBounds(getBaseElementType(Call), + Call->getArgOperand(0), IdxList, + "", Call->getIterator()); Call->replaceAllUsesWith(GEP); Call->eraseFromParent(); } @@ -1091,9 +1092,11 @@ bool BPFAbstractMemberAccess::transformGEPChain(CallInst *Call, // Load the global variable which represents the returned field info. LoadInst *LDInst; if (IsInt32Ret) - LDInst = new LoadInst(Type::getInt32Ty(BB->getContext()), GV, "", Call); + LDInst = new LoadInst(Type::getInt32Ty(BB->getContext()), GV, "", + Call->getIterator()); else - LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call); + LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", + Call->getIterator()); Instruction *PassThroughInst = BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call); @@ -1113,7 +1116,8 @@ bool BPFAbstractMemberAccess::transformGEPChain(CallInst *Call, // The original Call inst is removed. // Load the global variable. - auto *LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call); + auto *LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", + Call->getIterator()); // Generate a BitCast auto *BCInst = diff --git a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp index dae1aeea3521..afc154988050 100644 --- a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp +++ b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp @@ -116,8 +116,8 @@ static bool BPFPreserveDITypeImpl(Function &F) { GV->setMetadata(LLVMContext::MD_preserve_access_index, MD); // Load the global variable which represents the type info. - auto *LDInst = - new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call); + auto *LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", + Call->getIterator()); Instruction *PassThroughInst = BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call); Call->replaceAllUsesWith(PassThroughInst); diff --git a/llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp b/llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp index 4ead8c68cb90..b0de0405ce96 100644 --- a/llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp +++ b/llvm/lib/Target/Hexagon/HexagonCommonGEP.cpp @@ -1109,7 +1109,7 @@ Value *HexagonCommonGEP::fabricateGEP(NodeVect &NA, BasicBlock::iterator At, break; } } - NewInst = GetElementPtrInst::Create(InpTy, Input, IdxList, "cgep", &*At); + NewInst = GetElementPtrInst::Create(InpTy, Input, IdxList, "cgep", At); NewInst->setIsInBounds(RN->Flags & GepNode::InBounds); LLVM_DEBUG(dbgs() << "new GEP: " << *NewInst << '\n'); if (Idx < Num) { diff --git a/llvm/lib/Target/Mips/Mips16HardFloat.cpp b/llvm/lib/Target/Mips/Mips16HardFloat.cpp index 5c96044b1f0b..f7b623785b70 100644 --- a/llvm/lib/Target/Mips/Mips16HardFloat.cpp +++ b/llvm/lib/Target/Mips/Mips16HardFloat.cpp @@ -414,7 +414,7 @@ static bool fixupFPReturnAndCall(Function &F, Module *M, C, Attribute::getWithMemoryEffects(C, MemoryEffects::none())); A = A.addFnAttribute(C, Attribute::NoInline); FunctionCallee F = (M->getOrInsertFunction(Name, A, MyVoid, T)); - CallInst::Create(F, Params, "", &I); + CallInst::Create(F, Params, "", I.getIterator()); } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) { FunctionType *FT = CI->getFunctionType(); Function *F_ = CI->getCalledFunction(); diff --git a/llvm/lib/Target/NVPTX/NVPTXImageOptimizer.cpp b/llvm/lib/Target/NVPTX/NVPTXImageOptimizer.cpp index 202134ed7035..c3fce14df068 100644 --- a/llvm/lib/Target/NVPTX/NVPTXImageOptimizer.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXImageOptimizer.cpp @@ -157,7 +157,7 @@ void NVPTXImageOptimizer::replaceWith(Instruction *From, ConstantInt *To) { else // Get true block Dest = BI->getSuccessor(0); - BranchInst::Create(Dest, BI); + BranchInst::Create(Dest, BI->getIterator()); InstrToDelete.push_back(BI); } } diff --git a/llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp b/llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp index 9e06f4689304..cde02c25c483 100644 --- a/llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp @@ -183,16 +183,16 @@ static void convertToParamAS(Value *OldUser, Value *Param) { } if (auto *GEP = dyn_cast<GetElementPtrInst>(I.OldInstruction)) { SmallVector<Value *, 4> Indices(GEP->indices()); - auto *NewGEP = GetElementPtrInst::Create(GEP->getSourceElementType(), - I.NewParam, Indices, - GEP->getName(), GEP); + auto *NewGEP = GetElementPtrInst::Create( + GEP->getSourceElementType(), I.NewParam, Indices, GEP->getName(), + GEP->getIterator()); NewGEP->setIsInBounds(GEP->isInBounds()); return NewGEP; } if (auto *BC = dyn_cast<BitCastInst>(I.OldInstruction)) { auto *NewBCType = PointerType::get(BC->getContext(), ADDRESS_SPACE_PARAM); return BitCastInst::Create(BC->getOpcode(), I.NewParam, NewBCType, - BC->getName(), BC); + BC->getName(), BC->getIterator()); } if (auto *ASC = dyn_cast<AddrSpaceCastInst>(I.OldInstruction)) { assert(ASC->getDestAddressSpace() == ADDRESS_SPACE_PARAM); @@ -316,7 +316,7 @@ static void adjustByValArgAlignment(Argument *Arg, Value *ArgInParamAS, void NVPTXLowerArgs::handleByValParam(const NVPTXTargetMachine &TM, Argument *Arg) { Function *Func = Arg->getParent(); - Instruction *FirstInst = &(Func->getEntryBlock().front()); + BasicBlock::iterator FirstInst = Func->getEntryBlock().begin(); Type *StructType = Arg->getParamByValType(); assert(StructType && "Missing byval type"); @@ -407,9 +407,9 @@ void NVPTXLowerArgs::markPointerAsGlobal(Value *Ptr) { Instruction *PtrInGlobal = new AddrSpaceCastInst( Ptr, PointerType::get(Ptr->getContext(), ADDRESS_SPACE_GLOBAL), - Ptr->getName(), &*InsertPt); + Ptr->getName(), InsertPt); Value *PtrInGeneric = new AddrSpaceCastInst(PtrInGlobal, Ptr->getType(), - Ptr->getName(), &*InsertPt); + Ptr->getName(), InsertPt); // Replace with PtrInGeneric all uses of Ptr except PtrInGlobal. Ptr->replaceAllUsesWith(PtrInGeneric); PtrInGlobal->setOperand(0, Ptr); diff --git a/llvm/lib/Target/NVPTX/NVPTXLowerUnreachable.cpp b/llvm/lib/Target/NVPTX/NVPTXLowerUnreachable.cpp index 34f06b548db2..92b90e255915 100644 --- a/llvm/lib/Target/NVPTX/NVPTXLowerUnreachable.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXLowerUnreachable.cpp @@ -143,7 +143,7 @@ bool NVPTXLowerUnreachable::runOnFunction(Function &F) { if (auto unreachableInst = dyn_cast<UnreachableInst>(&I)) { if (isLoweredToTrap(*unreachableInst)) continue; // trap is emitted as `trap; exit;`. - CallInst::Create(ExitFTy, Exit, "", unreachableInst); + CallInst::Create(ExitFTy, Exit, "", unreachableInst->getIterator()); Changed = true; } } diff --git a/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp b/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp index f1abb78d4dd3..4a3b64f30d8d 100644 --- a/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp +++ b/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp @@ -263,7 +263,8 @@ class PPCBoolRetToInt : public FunctionPass { Value *IntRetVal = BoolToIntMap[U]; Type *Int1Ty = Type::getInt1Ty(U->getContext()); auto *I = cast<Instruction>(U.getUser()); - Value *BackToBool = new TruncInst(IntRetVal, Int1Ty, "backToBool", I); + Value *BackToBool = + new TruncInst(IntRetVal, Int1Ty, "backToBool", I->getIterator()); U.set(BackToBool); return true; diff --git a/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp b/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp index dc739a2c7a4d..f19eb2af5e07 100644 --- a/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp +++ b/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp @@ -725,7 +725,7 @@ PPCLoopInstrFormPrep::rewriteForBase(Loop *L, const SCEVAddRecExpr *BasePtrSCEV, Instruction *PtrInc = nullptr; Instruction *NewBasePtr = nullptr; if (CanPreInc) { - Instruction *InsPoint = &*Header->getFirstInsertionPt(); + BasicBlock::iterator InsPoint = Header->getFirstInsertionPt(); PtrInc = GetElementPtrInst::Create( I8Ty, NewPHI, IncNode, getInstrName(BaseMemI, GEPNodeIncNameSuffix), InsPoint); @@ -752,7 +752,7 @@ PPCLoopInstrFormPrep::rewriteForBase(Loop *L, const SCEVAddRecExpr *BasePtrSCEV, // For the latch predecessor, we need to insert a GEP just before the // terminator to increase the address. BasicBlock *BB = PI; - Instruction *InsPoint = BB->getTerminator(); + BasicBlock::iterator InsPoint = BB->getTerminator()->getIterator(); PtrInc = GetElementPtrInst::Create( I8Ty, NewPHI, IncNode, getInstrName(BaseMemI, GEPNodeIncNameSuffix), InsPoint); @@ -764,7 +764,7 @@ PPCLoopInstrFormPrep::rewriteForBase(Loop *L, const SCEVAddRecExpr *BasePtrSCEV, if (NewPHI->getType() != BasePtr->getType()) NewBasePtr = new BitCastInst(NewPHI, BasePtr->getType(), getInstrName(NewPHI, CastNodeNameSuffix), - &*Header->getFirstInsertionPt()); + Header->getFirstInsertionPt()); else NewBasePtr = NewPHI; } @@ -794,20 +794,25 @@ Instruction *PPCLoopInstrFormPrep::rewriteForBucketElement( cast<SCEVConstant>(Element.Offset)->getValue()->isZero())) { RealNewPtr = NewBasePtr; } else { - Instruction *PtrIP = dyn_cast<Instruction>(Ptr); + std::optional<BasicBlock::iterator> PtrIP = std::nullopt; + if (Instruction *I = dyn_cast<Instruction>(Ptr)) + PtrIP = I->getIterator(); + if (PtrIP && isa<Instruction>(NewBasePtr) && - cast<Instruction>(NewBasePtr)->getParent() == PtrIP->getParent()) - PtrIP = nullptr; - else if (PtrIP && isa<PHINode>(PtrIP)) - PtrIP = &*PtrIP->getParent()->getFirstInsertionPt(); + cast<Instruction>(NewBasePtr)->getParent() == (*PtrIP)->getParent()) + PtrIP = std::nullopt; + else if (PtrIP && isa<PHINode>(*PtrIP)) + PtrIP = (*PtrIP)->getParent()->getFirstInsertionPt(); else if (!PtrIP) - PtrIP = Element.Instr; + PtrIP = Element.Instr->getIterator(); assert(OffToBase && "There should be an offset for non base element!\n"); GetElementPtrInst *NewPtr = GetElementPtrInst::Create( I8Ty, PtrInc, OffToBase, - getInstrName(Element.Instr, GEPNodeOffNameSuffix), PtrIP); - if (!PtrIP) + getInstrName(Element.Instr, GEPNodeOffNameSuffix)); + if (PtrIP) + NewPtr->insertBefore(*(*PtrIP)->getParent(), *PtrIP); + else NewPtr->insertAfter(cast<Instruction>(PtrInc)); NewPtr->setIsInBounds(IsPtrInBounds(Ptr)); RealNewPtr = NewPtr; diff --git a/llvm/lib/Target/RISCV/RISCVGatherScatterLowering.cpp b/llvm/lib/Target/RISCV/RISCVGatherScatterLowering.cpp index 0530e3d08be8..f0bd25f167d8 100644 --- a/llvm/lib/Target/RISCV/RISCVGatherScatterLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVGatherScatterLowering.cpp @@ -231,7 +231,7 @@ bool RISCVGatherScatterLowering::matchStridedRecurrence(Value *Index, Loop *L, BasePtr = PHINode::Create(Start->getType(), 2, Phi->getName() + ".scalar", Phi->getIterator()); Inc = BinaryOperator::CreateAdd(BasePtr, Step, Inc->getName() + ".scalar", - Inc); + Inc->getIterator()); BasePtr->addIncoming(Start, Phi->getIncomingBlock(1 - IncrementingBlock)); BasePtr->addIncoming(Inc, Phi->getIncomingBlock(IncrementingBlock)); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp index 77e6640d5a82..0427fe473f8e 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp @@ -1283,9 +1283,9 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) { DebugLoc FirstDL = getOrCreateDebugLoc(&*Entry->begin(), F.getSubprogram()); SplitBlock(Entry, &*Entry->getFirstInsertionPt()); - BinaryOperator *SetjmpTableSize = - BinaryOperator::Create(Instruction::Add, IRB.getInt32(4), IRB.getInt32(0), - "setjmpTableSize", Entry->getTerminator()); + BinaryOperator *SetjmpTableSize = BinaryOperator::Create( + Instruction::Add, IRB.getInt32(4), IRB.getInt32(0), "setjmpTableSize", + Entry->getTerminator()->getIterator()); SetjmpTableSize->setDebugLoc(FirstDL); // setjmpTable = (int *) malloc(40); Type *IntPtrTy = getAddrIntType(&M); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp index e0a219211228..2594430d1d8f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp @@ -73,7 +73,7 @@ bool WebAssemblyLowerRefTypesIntPtrConv::runOnFunction(Function &F) { Function *TrapIntrin = Intrinsic::getDeclaration(F.getParent(), Intrinsic::debugtrap); - CallInst::Create(TrapIntrin, {}, "", &*I); + CallInst::Create(TrapIntrin, {}, "", I->getIterator()); worklist.insert(&*I); } diff --git a/llvm/lib/Target/X86/X86LowerAMXType.cpp b/llvm/lib/Target/X86/X86LowerAMXType.cpp index a57c0fe15788..b69058787a4e 100644 --- a/llvm/lib/Target/X86/X86LowerAMXType.cpp +++ b/llvm/lib/Target/X86/X86LowerAMXType.cpp @@ -102,7 +102,7 @@ static AllocaInst *createAllocaInstAtEntry(IRBuilder<> &Builder, BasicBlock *BB, auto AllocaAlignment = DL.getPrefTypeAlign(Type::getX86_AMXTy(Ctx)); unsigned AllocaAS = DL.getAllocaAddrSpace(); AllocaInst *AllocaRes = - new AllocaInst(Ty, AllocaAS, "", &F.getEntryBlock().front()); + new AllocaInst(Ty, AllocaAS, "", F.getEntryBlock().begin()); AllocaRes->setAlignment(AllocaAlignment); return AllocaRes; } @@ -453,7 +453,7 @@ static Value *getAllocaPos(BasicBlock *BB) { unsigned AllocaAS = DL.getAllocaAddrSpace(); Type *V256I32Ty = VectorType::get(Builder.getInt32Ty(), 256, false); AllocaInst *AllocaRes = - new AllocaInst(V256I32Ty, AllocaAS, "", &F->getEntryBlock().front()); + new AllocaInst(V256I32Ty, AllocaAS, "", F->getEntryBlock().begin()); BasicBlock::iterator Iter = AllocaRes->getIterator(); ++Iter; Builder.SetInsertPoint(&*Iter); diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp index a226cc2a1b25..8b2207ecbf36 100644 --- a/polly/lib/CodeGen/IslNodeBuilder.cpp +++ b/polly/lib/CodeGen/IslNodeBuilder.cpp @@ -1212,7 +1212,7 @@ bool IslNodeBuilder::preloadInvariantEquivClass( BasicBlock *EntryBB = &Builder.GetInsertBlock()->getParent()->getEntryBlock(); auto *Alloca = new AllocaInst(AccInstTy, DL.getAllocaAddrSpace(), AccInst->getName() + ".preload.s2a", - &*EntryBB->getFirstInsertionPt()); + EntryBB->getFirstInsertionPt()); Builder.CreateStore(PreloadVal, Alloca); ValueMapT PreloadedPointer; PreloadedPointer[PreloadVal] = AccInst; @@ -1308,10 +1308,11 @@ void IslNodeBuilder::allocateNewArrays(BBPair StartExitBlocks) { auto InstIt = Builder.GetInsertBlock() ->getParent() ->getEntryBlock() - .getTerminator(); + .getTerminator() + ->getIterator(); auto *CreatedArray = new AllocaInst(NewArrayType, DL.getAllocaAddrSpace(), - SAI->getName(), &*InstIt); + SAI->getName(), InstIt); if (PollyTargetFirstLevelCacheLineSize) CreatedArray->setAlignment(Align(PollyTargetFirstLevelCacheLineSize)); SAI->setBasePtr(CreatedArray); diff --git a/polly/lib/CodeGen/LoopGenerators.cpp b/polly/lib/CodeGen/LoopGenerators.cpp index 5c99515c5444..b4f8bb8948c2 100644 --- a/polly/lib/CodeGen/LoopGenerators.cpp +++ b/polly/lib/CodeGen/LoopGenerators.cpp @@ -225,7 +225,7 @@ ParallelLoopGenerator::storeValuesIntoStruct(SetVector<Value *> &Values) { // in the entry block of the function and use annotations to denote the actual // live span (similar to clang). BasicBlock &EntryBB = Builder.GetInsertBlock()->getParent()->getEntryBlock(); - Instruction *IP = &*EntryBB.getFirstInsertionPt(); + BasicBlock::iterator IP = EntryBB.getFirstInsertionPt(); StructType *Ty = StructType::get(Builder.getContext(), Members); AllocaInst *Struct = new AllocaInst(Ty, DL.getAllocaAddrSpace(), nullptr, "polly.par.userContext", IP); diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp index afdb61f25b6c..24c7011b06de 100644 --- a/polly/lib/Support/ScopHelper.cpp +++ b/polly/lib/Support/ScopHelper.cpp @@ -328,8 +328,9 @@ private: Value *LHS = expandCodeFor(LHSScev, E->getType(), IP); Value *RHS = expandCodeFor(RHSScev, E->getType(), IP); - Inst = BinaryOperator::Create((Instruction::BinaryOps)Inst->getOpcode(), - LHS, RHS, Inst->getName() + Name, IP); + Inst = + BinaryOperator::Create((Instruction::BinaryOps)Inst->getOpcode(), LHS, + RHS, Inst->getName() + Name, IP->getIterator()); return SE.getSCEV(Inst); } -- GitLab From e59f120e3a14ccdc55fcb7be996efaa768daabe0 Mon Sep 17 00:00:00 2001 From: Luke Lau <luke@igalia.com> Date: Wed, 20 Mar 2024 00:27:15 +0800 Subject: [PATCH 107/307] [RISCV] Add test for strided load combine regression. NFC This adds a reduced test case for the regression seen in x264 with #83035. If the intermediate concatenating shuffles are large enough then the splitting combine will prevent the strided load combine which is preferable. --- .../rvv/fixed-vectors-strided-load-combine.ll | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-strided-load-combine.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-strided-load-combine.ll index ba5db552b854..4ec2e59672ad 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-strided-load-combine.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-strided-load-combine.ll @@ -566,3 +566,28 @@ define void @reverse_strided_runtime_4xv2f32(ptr %x, ptr %z, i64 %s) { store <8 x float> %e.2, ptr %z ret void } + +; The middle end sometimes produces this pattern of shuffles, where the +; intermediate shuffles are the full result vector size padded with poison +; elements. +define <16 x i8> @widen_4xv4i8_immediate_expand(ptr %p, i64 %s) { +; CHECK-LABEL: widen_4xv4i8_immediate_expand: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; CHECK-NEXT: vlse32.v v8, (a0), a1 +; CHECK-NEXT: ret + %a = load <4 x i8>, ptr %p + %b.ptr = getelementptr i8, ptr %p, i64 %s + %b = load <4 x i8>, ptr %b.ptr + %c.ptr = getelementptr i8, ptr %b.ptr, i64 %s + %c = load <4 x i8>, ptr %c.ptr + %d.ptr = getelementptr i8, ptr %c.ptr, i64 %s + %d = load <4 x i8>, ptr %d.ptr + + %ab = shufflevector <4 x i8> %a, <4 x i8> %b, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> + %cx = shufflevector <4 x i8> %c, <4 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> + %dx = shufflevector <4 x i8> %d, <4 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison> + %abcx = shufflevector <16 x i8> %ab, <16 x i8> %cx, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 16, i32 17, i32 18, i32 19, i32 poison, i32 poison, i32 poison, i32 poison> + %abcd = shufflevector <16 x i8> %abcx, <16 x i8> %dx, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 16, i32 17, i32 18, i32 19> + ret <16 x i8> %abcd +} -- GitLab From 24f22b3f93f950348cbff35feb7ad9a5d16d916d Mon Sep 17 00:00:00 2001 From: Fangrui Song <i@maskray.me> Date: Tue, 19 Mar 2024 09:38:55 -0700 Subject: [PATCH 108/307] [llvm-readelf] Print a blank line for the first hex/string dump GNU readelf prints a blank line before the first hex/string dump, which serves as a separator when there are other dump operations. Port the behavior. Pull Request: https://github.com/llvm/llvm-project/pull/85744 --- lld/test/ELF/aarch64-tlsdesc-zrel.s | 1 + lld/test/ELF/pack-dyn-relocs.s | 1 + .../ELF/decompress-zlib-unsupported.test | 1 + .../tools/llvm-readobj/ELF/decompress-zlib.test | 2 ++ .../ELF/decompress-zstd-unsupported.test | 1 + llvm/test/tools/llvm-readobj/ELF/hex-dump-multi.s | 6 ++++-- llvm/test/tools/llvm-readobj/ELF/hex-dump.test | 9 ++++++--- .../tools/llvm-readobj/ELF/string-dump-multi.s | 6 ++++-- llvm/test/tools/llvm-readobj/ELF/string-dump.test | 6 ++++-- llvm/tools/llvm-readobj/ObjDumper.cpp | 14 ++------------ 10 files changed, 26 insertions(+), 21 deletions(-) diff --git a/lld/test/ELF/aarch64-tlsdesc-zrel.s b/lld/test/ELF/aarch64-tlsdesc-zrel.s index 1b35e0d29a26..e2e560bd13f5 100644 --- a/lld/test/ELF/aarch64-tlsdesc-zrel.s +++ b/lld/test/ELF/aarch64-tlsdesc-zrel.s @@ -13,6 +13,7 @@ // RELA-NEXT: 0x[[#ADDR+16]] R_AARCH64_TLSDESC - 0x4 // RELA-NEXT: } // RELA-NEXT: ] +// RELA-EMPTY: // RELA-NEXT: Hex dump of section '.got': // RELA-NEXT: 0x000[[#ADDR]] 00000000 00000000 00000000 00000000 // RELA-NO-ADDENDS-NEXT: 0x000[[#ADDR+16]] 00000000 00000000 00000000 00000000 diff --git a/lld/test/ELF/pack-dyn-relocs.s b/lld/test/ELF/pack-dyn-relocs.s index 9de5bee2e747..733ddd4ecad3 100644 --- a/lld/test/ELF/pack-dyn-relocs.s +++ b/lld/test/ELF/pack-dyn-relocs.s @@ -353,6 +353,7 @@ // RELR64-NEXT: 0000000000030550 0000000000000403 R_AARCH64_RELATIVE // RELR64-NEXT: 0000000000030558 0000000000000403 R_AARCH64_RELATIVE // RELR64-NEXT: 0000000000030560 0000000000000403 R_AARCH64_RELATIVE +// RELR64-EMPTY: // RELR64-NEXT: Hex dump of section '.data': // RELR64-NEXT: 0x00030490 00000000 00000000 01000000 00000000 . // RELR64-NEXT: 0x000304a0 02000000 00000000 ffffffff ffffffff . diff --git a/llvm/test/tools/llvm-readobj/ELF/decompress-zlib-unsupported.test b/llvm/test/tools/llvm-readobj/ELF/decompress-zlib-unsupported.test index f4c73de7ca6c..083c296b8cc1 100644 --- a/llvm/test/tools/llvm-readobj/ELF/decompress-zlib-unsupported.test +++ b/llvm/test/tools/llvm-readobj/ELF/decompress-zlib-unsupported.test @@ -10,6 +10,7 @@ # CHECK-NEXT: [ 18] x.c. # CHECK-NEXT: [ 1e] . # CHECK-NEXT: [ 20] . +# CHECK-EMPTY: # CHECK-NEXT: Hex dump of section '.b': # CHECK-NEXT: warning: '[[FILE]]': LLVM was not built with LLVM_ENABLE_ZLIB or did not find zlib at build time # CHECK-NEXT: 0x00000000 01000000 00000000 01000000 00000000 ................ diff --git a/llvm/test/tools/llvm-readobj/ELF/decompress-zlib.test b/llvm/test/tools/llvm-readobj/ELF/decompress-zlib.test index ea7a8854eb1a..c1d12a6d560e 100644 --- a/llvm/test/tools/llvm-readobj/ELF/decompress-zlib.test +++ b/llvm/test/tools/llvm-readobj/ELF/decompress-zlib.test @@ -28,6 +28,7 @@ # COMPRESSED: String dump of section '.not_null_terminated': # COMPRESSED-NEXT: [ 0] no # COMPRESSED-NEXT: [ 3] null +# COMPRESSED-EMPTY: # COMPRESSED-NEXT: Hex dump of section '.strings': # COMPRESSED-NEXT: 0x00000000 01000000 00000000 16000000 00000000 ................ # COMPRESSED-NEXT: 0x00000010 00000000 00000000 789ccb48 2d4a6548 ........x..H-JeH @@ -39,6 +40,7 @@ # INVALID: String dump of section '.invalid1': # INVALID-NEXT: warning: '[[FILE]]': corrupted compressed section header # INVALID-NEXT: [ 0] . +# INVALID-EMPTY: # INVALID-NEXT: Hex dump of section '.invalid2': # INVALID-NEXT: warning: '[[FILE]]': zlib error: Z_DATA_ERROR # INVALID-NEXT: 0x00000000 01000000 00000000 16000000 00000000 ................ diff --git a/llvm/test/tools/llvm-readobj/ELF/decompress-zstd-unsupported.test b/llvm/test/tools/llvm-readobj/ELF/decompress-zstd-unsupported.test index 65da952687f5..98c7cb002769 100644 --- a/llvm/test/tools/llvm-readobj/ELF/decompress-zstd-unsupported.test +++ b/llvm/test/tools/llvm-readobj/ELF/decompress-zstd-unsupported.test @@ -9,6 +9,7 @@ # CHECK-NEXT: [ 10] . # CHECK-NEXT: [ 18] (./. .. # CHECK-NEXT: [ 21] . +# CHECK-EMPTY: # CHECK-NEXT: Hex dump of section '.b': # CHECK-NEXT: warning: '[[FILE]]': LLVM was not built with LLVM_ENABLE_ZSTD or did not find zstd at build time # CHECK-NEXT: 0x00000000 02000000 00000000 01000000 00000000 ................ diff --git a/llvm/test/tools/llvm-readobj/ELF/hex-dump-multi.s b/llvm/test/tools/llvm-readobj/ELF/hex-dump-multi.s index 33ef534e81e1..942bfc4b7fb0 100644 --- a/llvm/test/tools/llvm-readobj/ELF/hex-dump-multi.s +++ b/llvm/test/tools/llvm-readobj/ELF/hex-dump-multi.s @@ -1,10 +1,12 @@ # REQUIRES: x86-registered-target # RUN: llvm-mc -filetype=obj -triple x86_64 %s -o %t.o -# RUN: llvm-readobj -x .a -x .b %t.o | FileCheck %s +# RUN: llvm-readobj -x .a -x .b %t.o | FileCheck %s --check-prefixes=HEADER,CHECK # RUN: llvm-readelf -x .a -x .b %t.o | FileCheck %s -# CHECK: Hex dump of section '.a': +# HEADER: LoadName: +# CHECK: {{^$}} +# CHECK-NEXT: Hex dump of section '.a': # CHECK-NEXT: 0x00000000 00 # CHECK-EMPTY: # CHECK-NEXT: Hex dump of section '.b': diff --git a/llvm/test/tools/llvm-readobj/ELF/hex-dump.test b/llvm/test/tools/llvm-readobj/ELF/hex-dump.test index 7829944806f3..71212dee5e07 100644 --- a/llvm/test/tools/llvm-readobj/ELF/hex-dump.test +++ b/llvm/test/tools/llvm-readobj/ELF/hex-dump.test @@ -46,7 +46,8 @@ FileHeader: # RUN: llvm-readelf --hex-dump=.sec %t2.out1 | \ # RUN: FileCheck %s --match-full-lines --strict-whitespace --check-prefix=SPACES1 -# SPACES1:Hex dump of section '.sec': +# SPACES1:{{^$}} +# SPACES1-NEXT:Hex dump of section '.sec': # SPACES1-NEXT:0x00000000 00000000 00000000 00000000 00000000 ................ # SPACES1-NEXT:0x00000010 0000 .. @@ -55,7 +56,8 @@ FileHeader: # RUN: llvm-readelf --hex-dump=.sec %t2.out2 | \ # RUN: FileCheck %s --match-full-lines --strict-whitespace --check-prefix=SPACES2 -# SPACES2:Hex dump of section '.sec': +# SPACES2:{{^$}} +# SPACES2-NEXT:Hex dump of section '.sec': # SPACES2-NEXT:0x00000000 00000000 00000000 00000000 00000000 ................ # SPACES2-NEXT:0x00000010 00000000 00000000 00000000 0000 .............. @@ -64,7 +66,8 @@ FileHeader: # RUN: llvm-readelf --hex-dump=.sec %t2.out3 | \ # RUN: FileCheck %s --match-full-lines --strict-whitespace --check-prefix=SPACES3 -# SPACES3:Hex dump of section '.sec': +# SPACES3:{{^$}} +# SPACES3-NEXT:Hex dump of section '.sec': # SPACES3-NEXT:0x00000000 00000000 00000000 00000000 00000000 ................ # SPACES3-NEXT:0x00000010 00000000 00000000 00000000 ............ diff --git a/llvm/test/tools/llvm-readobj/ELF/string-dump-multi.s b/llvm/test/tools/llvm-readobj/ELF/string-dump-multi.s index 29d7ef011005..36a115bd259a 100644 --- a/llvm/test/tools/llvm-readobj/ELF/string-dump-multi.s +++ b/llvm/test/tools/llvm-readobj/ELF/string-dump-multi.s @@ -1,10 +1,12 @@ # REQUIRES: x86-registered-target # RUN: llvm-mc -filetype=obj -triple x86_64 %s -o %t.o -# RUN: llvm-readobj -p .a -p .b %t.o | FileCheck %s +# RUN: llvm-readobj -p .a -p .b %t.o | FileCheck %s --check-prefixes=HEADER,CHECK # RUN: llvm-readelf -p .a -p .b %t.o | FileCheck %s -# CHECK: String dump of section '.a': +# HEADER: LoadName: +# CHECK: {{^$}} +# CHECK-NEXT: String dump of section '.a': # CHECK-NEXT: [ 0] 0 # CHECK-EMPTY: # CHECK-NEXT: String dump of section '.b': diff --git a/llvm/test/tools/llvm-readobj/ELF/string-dump.test b/llvm/test/tools/llvm-readobj/ELF/string-dump.test index c06b274d2528..1d7a177b32de 100644 --- a/llvm/test/tools/llvm-readobj/ELF/string-dump.test +++ b/llvm/test/tools/llvm-readobj/ELF/string-dump.test @@ -3,7 +3,7 @@ # RUN: llvm-readobj --string-dump=.strings \ # RUN: --string-dump=.not_null_terminated %t > %t.readobj.out -# RUN: FileCheck %s --input-file=%t.readobj.out +# RUN: FileCheck %s --input-file=%t.readobj.out --check-prefixes=HEADER,CHECK # Also test the different ways --string-dump can be specified, i.e. as a short # flag (-p), with different prefix modes (-p .foo, -p=.foo, -p.foo), and with @@ -23,7 +23,9 @@ # RUN: llvm-readelf -hp1 -p2 %t | cmp %t.readelf.out - # RUN: llvm-readelf -hp 1 -p.not_null_terminated %t | cmp %t.readelf.out - -# CHECK: String dump of section '.strings': +# HEADER: LoadName: +# CHECK: {{^$}} +# CHECK-NEXT: String dump of section '.strings': # CHECK-NEXT: [ 0] here # CHECK-NEXT: [ 5] are # CHECK-NEXT: [ 9] some diff --git a/llvm/tools/llvm-readobj/ObjDumper.cpp b/llvm/tools/llvm-readobj/ObjDumper.cpp index 0d3fea71aafd..0980d2ad3a85 100644 --- a/llvm/tools/llvm-readobj/ObjDumper.cpp +++ b/llvm/tools/llvm-readobj/ObjDumper.cpp @@ -160,15 +160,10 @@ void ObjDumper::printSectionsAsString(const object::ObjectFile &Obj, ArrayRef<std::string> Sections, bool Decompress) { SmallString<0> Out; - bool First = true; for (object::SectionRef Section : getSectionRefsByNameOrIndex(Obj, Sections)) { StringRef SectionName = unwrapOrError(Obj.getFileName(), Section.getName()); - - if (!First) - W.startLine() << '\n'; - First = false; - W.startLine() << "String dump of section '" << SectionName << "':\n"; + W.startLine() << "\nString dump of section '" << SectionName << "':\n"; StringRef SectionContent = unwrapOrError(Obj.getFileName(), Section.getContents()); @@ -182,15 +177,10 @@ void ObjDumper::printSectionsAsHex(const object::ObjectFile &Obj, ArrayRef<std::string> Sections, bool Decompress) { SmallString<0> Out; - bool First = true; for (object::SectionRef Section : getSectionRefsByNameOrIndex(Obj, Sections)) { StringRef SectionName = unwrapOrError(Obj.getFileName(), Section.getName()); - - if (!First) - W.startLine() << '\n'; - First = false; - W.startLine() << "Hex dump of section '" << SectionName << "':\n"; + W.startLine() << "\nHex dump of section '" << SectionName << "':\n"; StringRef SectionContent = unwrapOrError(Obj.getFileName(), Section.getContents()); -- GitLab From 09eb9f1136c8572c4c3f2ec46be50899c32fc881 Mon Sep 17 00:00:00 2001 From: Michele Scandale <michele.scandale@gmail.com> Date: Tue, 19 Mar 2024 09:47:07 -0700 Subject: [PATCH 109/307] [InstCombine] Fix for folding `select` into floating point binary operators. (#83200) Folding a `select` into a floating point binary operators can only be done if the result is preserved for both case. In particular, if the other operand of the `select` can be a NaN, then the transformation won't preserve the result value. --- .../InstCombine/InstCombineSelect.cpp | 36 ++-- .../InstCombine/fold-select-fmul-if-zero.ll | 56 ++--- .../select-binop-foldable-floating-point.ll | 196 ++++++++++-------- .../Transforms/InstCombine/select_meta.ll | 8 +- .../LoopVectorize/ARM/mve-selectandorcost.ll | 4 +- .../LoopVectorize/reduction-inloop-cond.ll | 8 +- .../LoopVectorize/reduction-inloop-pred.ll | 58 +++--- .../LoopVectorize/reduction-inloop.ll | 14 +- .../Transforms/LoopVectorize/reduction.ll | 14 +- ...ting-sinking-required-for-vectorization.ll | 8 +- 10 files changed, 217 insertions(+), 185 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index ee76a6294428..9ab2bd8f70aa 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -536,19 +536,29 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal, // between 0, 1 and -1. const APInt *OOpC; bool OOpIsAPInt = match(OOp, m_APInt(OOpC)); - if (!isa<Constant>(OOp) || - (OOpIsAPInt && isSelect01(C->getUniqueInteger(), *OOpC))) { - Value *NewSel = Builder.CreateSelect(SI.getCondition(), Swapped ? C : OOp, - Swapped ? OOp : C, "", &SI); - if (isa<FPMathOperator>(&SI)) - cast<Instruction>(NewSel)->setFastMathFlags(FMF); - NewSel->takeName(TVI); - BinaryOperator *BO = - BinaryOperator::Create(TVI->getOpcode(), FalseVal, NewSel); - BO->copyIRFlags(TVI); - return BO; - } - return nullptr; + if (isa<Constant>(OOp) && + (!OOpIsAPInt || !isSelect01(C->getUniqueInteger(), *OOpC))) + return nullptr; + + // If the false value is a NaN then we have that the floating point math + // operation in the transformed code may not preserve the exact NaN + // bit-pattern -- e.g. `fadd sNaN, 0.0 -> qNaN`. + // This makes the transformation incorrect since the original program would + // have preserved the exact NaN bit-pattern. + // Avoid the folding if the false value might be a NaN. + if (isa<FPMathOperator>(&SI) && + !computeKnownFPClass(FalseVal, FMF, fcNan, &SI).isKnownNeverNaN()) + return nullptr; + + Value *NewSel = Builder.CreateSelect(SI.getCondition(), Swapped ? C : OOp, + Swapped ? OOp : C, "", &SI); + if (isa<FPMathOperator>(&SI)) + cast<Instruction>(NewSel)->setFastMathFlags(FMF); + NewSel->takeName(TVI); + BinaryOperator *BO = + BinaryOperator::Create(TVI->getOpcode(), FalseVal, NewSel); + BO->copyIRFlags(TVI); + return BO; }; if (Instruction *R = TryFoldSelectIntoOp(SI, TrueVal, FalseVal, false)) diff --git a/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll b/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll index a7adcd1ac61e..dedd12f8cc7a 100644 --- a/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll +++ b/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll @@ -427,13 +427,13 @@ define float @fmul_by_snan_if_0_oeq_zero_f32(float %x) { define float @fmul_by_var_if_0_oeq_zero_f32(float %x, float %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, %y - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } @@ -441,14 +441,14 @@ define float @fmul_by_fabs_var_if_0_oeq_zero_f32(float %x, float %y) { ; CHECK-LABEL: @fmul_by_fabs_var_if_0_oeq_zero_f32( ; CHECK-NEXT: [[Y_FABS:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]]) ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y_FABS]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y_FABS]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %y.fabs = call float @llvm.fabs.f32(float %y) %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, %y.fabs - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } @@ -467,13 +467,13 @@ define float @fmul_by_fabs_nnan_ninf_var_if_0_oeq_zero_f32(float %x, float %y) { define float @fmul_by_var_if_0_oeq_zero_f32_nsz_fmul(float %x, float %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_nsz_fmul( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul nsz float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul nsz float %x, %y - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } @@ -481,13 +481,13 @@ define float @fmul_by_var_if_0_oeq_zero_f32_nsz_fmul(float %x, float %y) { define float @fmul_by_var_if_0_oeq_zero_f32_nsz_ninf_fmul(float %x, float %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_nsz_ninf_fmul( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul ninf nsz float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul nsz ninf float %x, %y - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } @@ -495,13 +495,13 @@ define float @fmul_by_var_if_0_oeq_zero_f32_nsz_ninf_fmul(float %x, float %y) { define float @fmul_by_var_if_0_oeq_zero_f32_nsz_nnan_fmul(float %x, float %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_nsz_nnan_fmul( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul nnan nsz float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul nsz nnan float %x, %y - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } @@ -509,13 +509,13 @@ define float @fmul_by_var_if_0_oeq_zero_f32_nsz_nnan_fmul(float %x, float %y) { define float @fmul_by_var_if_0_oeq_zero_f32_nnan_ninf_fmul(float %x, float %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_nnan_ninf_fmul( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul nnan ninf float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul nnan ninf float %x, %y - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } @@ -558,26 +558,26 @@ define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_nsz_inverted(f define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz(float %x, float %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul nnan ninf nsz float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul nnan ninf nsz float %x, %y - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz_commuted(float %x, float %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz_commuted( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul nnan ninf nsz float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul nnan ninf nsz float %y, %x - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } @@ -585,26 +585,26 @@ define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz_commuted(float %x define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_known_never_negzero(float %x, float nofpclass(nzero) %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_known_never_negzero( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul nnan ninf float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul nnan ninf float %x, %y - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } define float @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_known_never_negzero_negsub(float %x, float nofpclass(nzero nsub) %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_nnan_ninf_select_known_never_negzero_negsub( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul nnan ninf float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul nnan ninf float %x, %y - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } @@ -622,26 +622,26 @@ define float @fmul_by_var_if_0_oeq_zero_f32_known_never_nan_inf_select_nsz(float define float @fmul_by_var_if_0_oeq_zero_f32_fmul_known_never_nan_inf_negzero(float %x, float nofpclass(nan inf nzero) %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_known_never_nan_inf_negzero( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, %y - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } define float @fmul_by_var_if_0_oeq_zero_f32_fmul_known_never_nan_inf_negzero_nsub(float %x, float nofpclass(nan inf nzero nsub) %y) { ; CHECK-LABEL: @fmul_by_var_if_0_oeq_zero_f32_fmul_known_never_nan_inf_negzero_nsub( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[Y:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, %y - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } @@ -692,26 +692,26 @@ define float @fmul_by_var_if_not_one_0_zero_f32_assume_finite_fmul_nsz(float %x, define float @fmul_by_self_if_0_oeq_zero_f32(float %x) { ; CHECK-LABEL: @fmul_by_self_if_0_oeq_zero_f32( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[X]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[X]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul float %x, %x - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } define float @fmul_by_self_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz(float %x) { ; CHECK-LABEL: @fmul_by_self_if_0_oeq_zero_f32_fmul_nnan_ninf_nsz( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 -; CHECK-NEXT: [[SCALED_X:%.*]] = select i1 [[X_IS_ZERO]], float [[X]], float 1.000000e+00 +; CHECK-NEXT: [[SCALED_X:%.*]] = select nnan i1 [[X_IS_ZERO]], float [[X]], float 1.000000e+00 ; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = fmul nnan ninf nsz float [[SCALED_X]], [[X]] ; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = fmul nnan ninf nsz float %x, %x - %scaled.if.denormal = select i1 %x.is.zero, float %scaled.x, float %x + %scaled.if.denormal = select nnan i1 %x.is.zero, float %scaled.x, float %x ret float %scaled.if.denormal } diff --git a/llvm/test/Transforms/InstCombine/select-binop-foldable-floating-point.ll b/llvm/test/Transforms/InstCombine/select-binop-foldable-floating-point.ll index 496854c7d731..77ff16a8b2e3 100644 --- a/llvm/test/Transforms/InstCombine/select-binop-foldable-floating-point.ll +++ b/llvm/test/Transforms/InstCombine/select-binop-foldable-floating-point.ll @@ -1,8 +1,19 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instcombine -S | FileCheck %s -define float @select_fadd(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fadd( +define float @select_maybe_nan_fadd(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_maybe_nan_fadd( +; CHECK-NEXT: [[C:%.*]] = fadd float [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[D:%.*]] = select i1 [[COND:%.*]], float [[C]], float [[A]] +; CHECK-NEXT: ret float [[D]] +; + %C = fadd float %A, %B + %D = select i1 %cond, float %C, float %A + ret float %D +} + +define float @select_fpclass_fadd(i1 %cond, float nofpclass(nan) %A, float %B) { +; CHECK-LABEL: @select_fpclass_fadd( ; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float [[B:%.*]], float -0.000000e+00 ; CHECK-NEXT: [[D:%.*]] = fadd float [[C]], [[A:%.*]] ; CHECK-NEXT: ret float [[D]] @@ -12,41 +23,52 @@ define float @select_fadd(i1 %cond, float %A, float %B) { ret float %D } -define float @select_fadd_swapped(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fadd_swapped( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float -0.000000e+00, float [[B:%.*]] +define float @select_nnan_fadd(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fadd( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float -0.000000e+00 ; CHECK-NEXT: [[D:%.*]] = fadd float [[C]], [[A:%.*]] ; CHECK-NEXT: ret float [[D]] ; %C = fadd float %A, %B - %D = select i1 %cond, float %A, float %C + %D = select nnan i1 %cond, float %C, float %A ret float %D } -define float @select_fadd_fast_math(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fadd_fast_math( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float [[B:%.*]], float -0.000000e+00 +define float @select_nnan_fadd_swapped(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fadd_swapped( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float -0.000000e+00, float [[B:%.*]] +; CHECK-NEXT: [[D:%.*]] = fadd float [[C]], [[A:%.*]] +; CHECK-NEXT: ret float [[D]] +; + %C = fadd float %A, %B + %D = select nnan i1 %cond, float %A, float %C + ret float %D +} + +define float @select_nnan_fadd_fast_math(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fadd_fast_math( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float -0.000000e+00 ; CHECK-NEXT: [[D:%.*]] = fadd fast float [[C]], [[A:%.*]] ; CHECK-NEXT: ret float [[D]] ; %C = fadd fast float %A, %B - %D = select i1 %cond, float %C, float %A + %D = select nnan i1 %cond, float %C, float %A ret float %D } -define float @select_fadd_swapped_fast_math(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fadd_swapped_fast_math( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float -0.000000e+00, float [[B:%.*]] +define float @select_nnan_fadd_swapped_fast_math(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fadd_swapped_fast_math( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float -0.000000e+00, float [[B:%.*]] ; CHECK-NEXT: [[D:%.*]] = fadd fast float [[C]], [[A:%.*]] ; CHECK-NEXT: ret float [[D]] ; %C = fadd fast float %A, %B - %D = select i1 %cond, float %A, float %C + %D = select nnan i1 %cond, float %A, float %C ret float %D } -define <4 x float> @select_nsz_fadd_v4f32(<4 x i1> %cond, <4 x float> %A, <4 x float> %B) { -; CHECK-LABEL: @select_nsz_fadd_v4f32( +define <4 x float> @select_nnan_nsz_fadd_v4f32(<4 x i1> %cond, <4 x float> %A, <4 x float> %B) { +; CHECK-LABEL: @select_nnan_nsz_fadd_v4f32( ; CHECK-NEXT: [[C:%.*]] = select nnan nsz <4 x i1> [[COND:%.*]], <4 x float> [[B:%.*]], <4 x float> zeroinitializer ; CHECK-NEXT: [[D:%.*]] = fadd nnan nsz <4 x float> [[C]], [[A:%.*]] ; CHECK-NEXT: ret <4 x float> [[D]] @@ -56,202 +78,202 @@ define <4 x float> @select_nsz_fadd_v4f32(<4 x i1> %cond, <4 x float> %A, <4 x f ret <4 x float> %D } -define <vscale x 4 x float> @select_nsz_fadd_nxv4f32(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) { -; CHECK-LABEL: @select_nsz_fadd_nxv4f32( +define <vscale x 4 x float> @select_nnan_nsz_fadd_nxv4f32(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) { +; CHECK-LABEL: @select_nnan_nsz_fadd_nxv4f32( ; CHECK-NEXT: [[C:%.*]] = select nnan nsz <vscale x 4 x i1> [[COND:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> zeroinitializer ; CHECK-NEXT: [[D:%.*]] = fadd nnan nsz <vscale x 4 x float> [[C]], [[A:%.*]] ; CHECK-NEXT: ret <vscale x 4 x float> [[D]] ; - %C = fadd nsz nnan <vscale x 4 x float> %A, %B - %D = select nsz nnan <vscale x 4 x i1> %cond, <vscale x 4 x float> %C, <vscale x 4 x float> %A + %C = fadd nnan nsz <vscale x 4 x float> %A, %B + %D = select nnan nsz <vscale x 4 x i1> %cond, <vscale x 4 x float> %C, <vscale x 4 x float> %A ret <vscale x 4 x float> %D } -define <vscale x 4 x float> @select_nsz_fadd_nxv4f32_swapops(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) { -; CHECK-LABEL: @select_nsz_fadd_nxv4f32_swapops( +define <vscale x 4 x float> @select_nnan_nsz_fadd_nxv4f32_swapops(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) { +; CHECK-LABEL: @select_nnan_nsz_fadd_nxv4f32_swapops( ; CHECK-NEXT: [[C:%.*]] = select fast <vscale x 4 x i1> [[COND:%.*]], <vscale x 4 x float> zeroinitializer, <vscale x 4 x float> [[B:%.*]] ; CHECK-NEXT: [[D:%.*]] = fadd fast <vscale x 4 x float> [[C]], [[A:%.*]] ; CHECK-NEXT: ret <vscale x 4 x float> [[D]] ; %C = fadd fast <vscale x 4 x float> %A, %B - %D = select fast <vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %C + %D = select nnan fast <vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %C ret <vscale x 4 x float> %D } -define float @select_fmul(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fmul( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 +define float @select_nnan_fmul(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fmul( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[D:%.*]] = fmul float [[C]], [[A:%.*]] ; CHECK-NEXT: ret float [[D]] ; %C = fmul float %A, %B - %D = select i1 %cond, float %C, float %A + %D = select nnan i1 %cond, float %C, float %A ret float %D } -define float @select_fmul_swapped(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fmul_swapped( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] +define float @select_nnan_fmul_swapped(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fmul_swapped( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] ; CHECK-NEXT: [[D:%.*]] = fmul float [[C]], [[A:%.*]] ; CHECK-NEXT: ret float [[D]] ; %C = fmul float %A, %B - %D = select i1 %cond, float %A, float %C + %D = select nnan i1 %cond, float %A, float %C ret float %D } -define float @select_fmul_fast_math(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fmul_fast_math( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 +define float @select_nnan_fmul_fast_math(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fmul_fast_math( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[D:%.*]] = fmul fast float [[C]], [[A:%.*]] ; CHECK-NEXT: ret float [[D]] ; %C = fmul fast float %A, %B - %D = select i1 %cond, float %C, float %A + %D = select nnan i1 %cond, float %C, float %A ret float %D } -define float @select_fmul_swapped_fast_math(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fmul_swapped_fast_math( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] +define float @select_nnan_fmul_swapped_fast_math(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fmul_swapped_fast_math( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] ; CHECK-NEXT: [[D:%.*]] = fmul fast float [[C]], [[A:%.*]] ; CHECK-NEXT: ret float [[D]] ; %C = fmul fast float %A, %B - %D = select i1 %cond, float %A, float %C + %D = select nnan i1 %cond, float %A, float %C ret float %D } -define float @select_fsub(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fsub( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float [[B:%.*]], float 0.000000e+00 +define float @select_nnan_fsub(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fsub( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 0.000000e+00 ; CHECK-NEXT: [[D:%.*]] = fsub float [[A:%.*]], [[C]] ; CHECK-NEXT: ret float [[D]] ; %C = fsub float %A, %B - %D = select i1 %cond, float %C, float %A + %D = select nnan i1 %cond, float %C, float %A ret float %D } -define float @select_fsub_swapped(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fsub_swapped( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float 0.000000e+00, float [[B:%.*]] +define float @select_nnan_fsub_swapped(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fsub_swapped( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 0.000000e+00, float [[B:%.*]] ; CHECK-NEXT: [[D:%.*]] = fsub float [[A:%.*]], [[C]] ; CHECK-NEXT: ret float [[D]] ; %C = fsub float %A, %B - %D = select i1 %cond, float %A, float %C + %D = select nnan i1 %cond, float %A, float %C ret float %D } -define float @select_fsub_fast_math(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fsub_fast_math( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float [[B:%.*]], float 0.000000e+00 +define float @select_nnan_fsub_fast_math(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fsub_fast_math( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 0.000000e+00 ; CHECK-NEXT: [[D:%.*]] = fsub fast float [[A:%.*]], [[C]] ; CHECK-NEXT: ret float [[D]] ; %C = fsub fast float %A, %B - %D = select i1 %cond, float %C, float %A + %D = select nnan i1 %cond, float %C, float %A ret float %D } -define float @select_fsub_swapped_fast_math(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fsub_swapped_fast_math( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float 0.000000e+00, float [[B:%.*]] +define float @select_nnan_fsub_swapped_fast_math(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fsub_swapped_fast_math( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 0.000000e+00, float [[B:%.*]] ; CHECK-NEXT: [[D:%.*]] = fsub fast float [[A:%.*]], [[C]] ; CHECK-NEXT: ret float [[D]] ; %C = fsub fast float %A, %B - %D = select i1 %cond, float %A, float %C + %D = select nnan i1 %cond, float %A, float %C ret float %D } -define <4 x float> @select_nsz_fsub_v4f32(<4 x i1> %cond, <4 x float> %A, <4 x float> %B) { -; CHECK-LABEL: @select_nsz_fsub_v4f32( -; CHECK-NEXT: [[C:%.*]] = select nsz <4 x i1> [[COND:%.*]], <4 x float> [[B:%.*]], <4 x float> zeroinitializer +define <4 x float> @select_nnan_nsz_fsub_v4f32(<4 x i1> %cond, <4 x float> %A, <4 x float> %B) { +; CHECK-LABEL: @select_nnan_nsz_fsub_v4f32( +; CHECK-NEXT: [[C:%.*]] = select nnan nsz <4 x i1> [[COND:%.*]], <4 x float> [[B:%.*]], <4 x float> zeroinitializer ; CHECK-NEXT: [[D:%.*]] = fsub <4 x float> [[A:%.*]], [[C]] ; CHECK-NEXT: ret <4 x float> [[D]] ; %C = fsub <4 x float> %A, %B - %D = select nsz <4 x i1> %cond, <4 x float> %C, <4 x float> %A + %D = select nnan nsz <4 x i1> %cond, <4 x float> %C, <4 x float> %A ret <4 x float> %D } -define <vscale x 4 x float> @select_nsz_fsub_nxv4f32(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) { -; CHECK-LABEL: @select_nsz_fsub_nxv4f32( -; CHECK-NEXT: [[C:%.*]] = select nsz <vscale x 4 x i1> [[COND:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> zeroinitializer +define <vscale x 4 x float> @select_nnan_nsz_fsub_nxv4f32(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) { +; CHECK-LABEL: @select_nnan_nsz_fsub_nxv4f32( +; CHECK-NEXT: [[C:%.*]] = select nnan nsz <vscale x 4 x i1> [[COND:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> zeroinitializer ; CHECK-NEXT: [[D:%.*]] = fsub <vscale x 4 x float> [[A:%.*]], [[C]] ; CHECK-NEXT: ret <vscale x 4 x float> [[D]] ; %C = fsub <vscale x 4 x float> %A, %B - %D = select nsz <vscale x 4 x i1> %cond, <vscale x 4 x float> %C, <vscale x 4 x float> %A + %D = select nnan nsz <vscale x 4 x i1> %cond, <vscale x 4 x float> %C, <vscale x 4 x float> %A ret <vscale x 4 x float> %D } ; 'fsub' can only fold on the amount subtracted. -define float @select_fsub_invalid(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fsub_invalid( +define float @select_nnan_fsub_invalid(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fsub_invalid( ; CHECK-NEXT: [[C:%.*]] = fsub float [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: [[D:%.*]] = select i1 [[COND:%.*]], float [[C]], float [[A]] +; CHECK-NEXT: [[D:%.*]] = select nnan i1 [[COND:%.*]], float [[C]], float [[A]] ; CHECK-NEXT: ret float [[D]] ; %C = fsub float %B, %A - %D = select i1 %cond, float %C, float %A + %D = select nnan i1 %cond, float %C, float %A ret float %D } -define float @select_fdiv(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fdiv( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 +define float @select_nnan_fdiv(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fdiv( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[D:%.*]] = fdiv float [[A:%.*]], [[C]] ; CHECK-NEXT: ret float [[D]] ; %C = fdiv float %A, %B - %D = select i1 %cond, float %C, float %A + %D = select nnan i1 %cond, float %C, float %A ret float %D } -define float @select_fdiv_swapped(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fdiv_swapped( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] +define float @select_nnan_fdiv_swapped(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fdiv_swapped( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] ; CHECK-NEXT: [[D:%.*]] = fdiv float [[A:%.*]], [[C]] ; CHECK-NEXT: ret float [[D]] ; %C = fdiv float %A, %B - %D = select i1 %cond, float %A, float %C + %D = select nnan i1 %cond, float %A, float %C ret float %D } -define float @select_fdiv_fast_math(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fdiv_fast_math( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 +define float @select_nnan_fdiv_fast_math(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fdiv_fast_math( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 ; CHECK-NEXT: [[D:%.*]] = fdiv fast float [[A:%.*]], [[C]] ; CHECK-NEXT: ret float [[D]] ; %C = fdiv fast float %A, %B - %D = select i1 %cond, float %C, float %A + %D = select nnan i1 %cond, float %C, float %A ret float %D } -define float @select_fdiv_swapped_fast_math(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fdiv_swapped_fast_math( -; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] +define float @select_nnan_fdiv_swapped_fast_math(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fdiv_swapped_fast_math( +; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] ; CHECK-NEXT: [[D:%.*]] = fdiv fast float [[A:%.*]], [[C]] ; CHECK-NEXT: ret float [[D]] ; %C = fdiv fast float %A, %B - %D = select i1 %cond, float %A, float %C + %D = select nnan i1 %cond, float %A, float %C ret float %D } ; 'fdiv' can only fold on the divisor amount. -define float @select_fdiv_invalid(i1 %cond, float %A, float %B) { -; CHECK-LABEL: @select_fdiv_invalid( +define float @select_nnan_fdiv_invalid(i1 %cond, float %A, float %B) { +; CHECK-LABEL: @select_nnan_fdiv_invalid( ; CHECK-NEXT: [[C:%.*]] = fdiv float [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: [[D:%.*]] = select i1 [[COND:%.*]], float [[C]], float [[A]] +; CHECK-NEXT: [[D:%.*]] = select nnan i1 [[COND:%.*]], float [[C]], float [[A]] ; CHECK-NEXT: ret float [[D]] ; %C = fdiv float %B, %A - %D = select i1 %cond, float %C, float %A + %D = select nnan i1 %cond, float %C, float %A ret float %D } diff --git a/llvm/test/Transforms/InstCombine/select_meta.ll b/llvm/test/Transforms/InstCombine/select_meta.ll index cd133101736c..aa794e82e0fd 100644 --- a/llvm/test/Transforms/InstCombine/select_meta.ll +++ b/llvm/test/Transforms/InstCombine/select_meta.ll @@ -360,23 +360,23 @@ define i128 @select_ashr(i1 %cond, i128 %x, i128 %y) { define double @select_fmul(i1 %cond, double %x, double %y) { ; CHECK-LABEL: @select_fmul( -; CHECK-NEXT: [[OP:%.*]] = select i1 [[COND:%.*]], double [[Y:%.*]], double 1.000000e+00, !prof [[PROF0]], !unpredictable [[META2]] +; CHECK-NEXT: [[OP:%.*]] = select nnan i1 [[COND:%.*]], double [[Y:%.*]], double 1.000000e+00, !prof [[PROF0]], !unpredictable [[META2]] ; CHECK-NEXT: [[RET:%.*]] = fmul double [[OP]], [[X:%.*]] ; CHECK-NEXT: ret double [[RET]] ; %op = fmul double %x, %y - %ret = select i1 %cond, double %op, double %x, !prof !1, !unpredictable !3 + %ret = select nnan i1 %cond, double %op, double %x, !prof !1, !unpredictable !3 ret double %ret } define <2 x float> @select_fdiv(i1 %cond, <2 x float> %x, <2 x float> %y) { ; CHECK-LABEL: @select_fdiv( -; CHECK-NEXT: [[OP:%.*]] = select i1 [[COND:%.*]], <2 x float> [[Y:%.*]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, !prof [[PROF0]], !unpredictable [[META2]] +; CHECK-NEXT: [[OP:%.*]] = select nnan i1 [[COND:%.*]], <2 x float> [[Y:%.*]], <2 x float> <float 1.000000e+00, float 1.000000e+00>, !prof [[PROF0]], !unpredictable [[META2]] ; CHECK-NEXT: [[RET:%.*]] = fdiv <2 x float> [[X:%.*]], [[OP]] ; CHECK-NEXT: ret <2 x float> [[RET]] ; %op = fdiv <2 x float> %x, %y - %ret = select i1 %cond, <2 x float> %op, <2 x float> %x, !prof !1, !unpredictable !3 + %ret = select nnan i1 %cond, <2 x float> %op, <2 x float> %x, !prof !1, !unpredictable !3 ret <2 x float> %ret } diff --git a/llvm/test/Transforms/LoopVectorize/ARM/mve-selectandorcost.ll b/llvm/test/Transforms/LoopVectorize/ARM/mve-selectandorcost.ll index 938e1deab0b6..695383433566 100644 --- a/llvm/test/Transforms/LoopVectorize/ARM/mve-selectandorcost.ll +++ b/llvm/test/Transforms/LoopVectorize/ARM/mve-selectandorcost.ll @@ -45,8 +45,8 @@ define float @test(ptr nocapture readonly %pA, ptr nocapture readonly %pB, i32 % ; CHECK-NEXT: [[TMP9:%.*]] = fsub fast <4 x float> [[WIDE_LOAD]], [[WIDE_LOAD6]] ; CHECK-NEXT: [[TMP10:%.*]] = call fast <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP9]]) ; CHECK-NEXT: [[TMP11:%.*]] = fdiv fast <4 x float> [[TMP10]], [[TMP8]] -; CHECK-NEXT: [[TMP12:%.*]] = select <4 x i1> [[DOTNOT8]], <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, <4 x float> [[TMP11]] -; CHECK-NEXT: [[PREDPHI]] = fadd fast <4 x float> [[VEC_PHI]], [[TMP12]] +; CHECK-NEXT: [[TMP12:%.*]] = fadd fast <4 x float> [[TMP11]], [[VEC_PHI]] +; CHECK-NEXT: [[PREDPHI]] = select <4 x i1> [[DOTNOT8]], <4 x float> [[VEC_PHI]], <4 x float> [[TMP12]] ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4 ; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]] ; CHECK-NEXT: br i1 [[TMP13]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] diff --git a/llvm/test/Transforms/LoopVectorize/reduction-inloop-cond.ll b/llvm/test/Transforms/LoopVectorize/reduction-inloop-cond.ll index 3ba57821bc31..873f6364f828 100644 --- a/llvm/test/Transforms/LoopVectorize/reduction-inloop-cond.ll +++ b/llvm/test/Transforms/LoopVectorize/reduction-inloop-cond.ll @@ -850,8 +850,8 @@ define float @cond_cond(ptr noalias %src1, ptr noalias %src2, ptr noalias %cond, ; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE6]] ; CHECK: pred.load.continue6: ; CHECK-NEXT: [[TMP24:%.*]] = phi <4 x float> [ [[TMP19]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ] -; CHECK-NEXT: [[TMP25:%.*]] = select <4 x i1> [[TMP4]], <4 x float> [[TMP24]], <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00> -; CHECK-NEXT: [[PREDPHI:%.*]] = fadd fast <4 x float> [[VEC_PHI]], [[TMP25]] +; CHECK-NEXT: [[TMP25:%.*]] = fadd fast <4 x float> [[TMP24]], [[VEC_PHI]] +; CHECK-NEXT: [[PREDPHI:%.*]] = select <4 x i1> [[TMP4]], <4 x float> [[TMP25]], <4 x float> [[VEC_PHI]] ; CHECK-NEXT: [[TMP26:%.*]] = fcmp fast oeq <4 x float> [[WIDE_LOAD]], <float 7.000000e+00, float 7.000000e+00, float 7.000000e+00, float 7.000000e+00> ; CHECK-NEXT: [[TMP27:%.*]] = extractelement <4 x i1> [[TMP26]], i64 0 ; CHECK-NEXT: br i1 [[TMP27]], label [[PRED_LOAD_IF7:%.*]], label [[PRED_LOAD_CONTINUE8:%.*]] @@ -889,8 +889,8 @@ define float @cond_cond(ptr noalias %src1, ptr noalias %src2, ptr noalias %cond, ; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE14]] ; CHECK: pred.load.continue14: ; CHECK-NEXT: [[TMP46:%.*]] = phi <4 x float> [ [[TMP41]], [[PRED_LOAD_CONTINUE12]] ], [ [[TMP45]], [[PRED_LOAD_IF13]] ] -; CHECK-NEXT: [[TMP47:%.*]] = select <4 x i1> [[TMP26]], <4 x float> [[TMP46]], <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00> -; CHECK-NEXT: [[PREDPHI15]] = fadd fast <4 x float> [[PREDPHI]], [[TMP47]] +; CHECK-NEXT: [[TMP47:%.*]] = fadd fast <4 x float> [[TMP46]], [[PREDPHI]] +; CHECK-NEXT: [[PREDPHI15]] = select <4 x i1> [[TMP26]], <4 x float> [[TMP47]], <4 x float> [[PREDPHI]] ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 ; CHECK-NEXT: [[TMP48:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] ; CHECK-NEXT: br i1 [[TMP48]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]] diff --git a/llvm/test/Transforms/LoopVectorize/reduction-inloop-pred.ll b/llvm/test/Transforms/LoopVectorize/reduction-inloop-pred.ll index b1c5ccbead64..e79f0983a637 100644 --- a/llvm/test/Transforms/LoopVectorize/reduction-inloop-pred.ll +++ b/llvm/test/Transforms/LoopVectorize/reduction-inloop-pred.ll @@ -65,7 +65,7 @@ define i32 @reduction_sum_single(ptr noalias nocapture %A) { ; CHECK: scalar.ph: ; CHECK-NEXT: br label [[DOTLR_PH:%.*]] ; CHECK: .lr.ph: -; CHECK-NEXT: br i1 poison, label [[DOT_CRIT_EDGE]], label [[DOTLR_PH]], !llvm.loop [[LOOP2:![0-9]+]] +; CHECK-NEXT: br i1 poison, label [[DOT_CRIT_EDGE]], label [[DOTLR_PH]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK: ._crit_edge: ; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ poison, [[DOTLR_PH]] ], [ [[TMP26]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]] @@ -1173,7 +1173,7 @@ define i32 @reduction_min(ptr nocapture %A, ptr nocapture %B) { ; CHECK: vector.body: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ] ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_LOAD_CONTINUE6]] ] -; CHECK-NEXT: [[VEC_PHI:%.*]] = phi i32 [ 1000, [[VECTOR_PH]] ], [ [[TMP26:%.*]], [[PRED_LOAD_CONTINUE6]] ] +; CHECK-NEXT: [[VEC_PHI:%.*]] = phi i32 [ 1000, [[VECTOR_PH]] ], [ [[RDX_MINMAX:%.*]], [[PRED_LOAD_CONTINUE6]] ] ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult <4 x i64> [[VEC_IND]], <i64 257, i64 257, i64 257, i64 257> ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i1> [[TMP0]], i64 0 ; CHECK-NEXT: br i1 [[TMP1]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]] @@ -1216,11 +1216,11 @@ define i32 @reduction_min(ptr nocapture %A, ptr nocapture %B) { ; CHECK-NEXT: [[TMP23:%.*]] = phi <4 x i32> [ [[TMP17]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP22]], [[PRED_LOAD_IF5]] ] ; CHECK-NEXT: [[TMP24:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[TMP23]], <4 x i32> <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647> ; CHECK-NEXT: [[TMP25:%.*]] = call i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> [[TMP24]]) -; CHECK-NEXT: [[TMP26]] = call i32 @llvm.smin.i32(i32 [[TMP25]], i32 [[VEC_PHI]]) +; CHECK-NEXT: [[RDX_MINMAX]] = call i32 @llvm.smin.i32(i32 [[TMP25]], i32 [[VEC_PHI]]) ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 4 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], <i64 4, i64 4, i64 4, i64 4> -; CHECK-NEXT: [[TMP27:%.*]] = icmp eq i64 [[INDEX_NEXT]], 260 -; CHECK-NEXT: br i1 [[TMP27]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP24:![0-9]+]] +; CHECK-NEXT: [[TMP26:%.*]] = icmp eq i64 [[INDEX_NEXT]], 260 +; CHECK-NEXT: br i1 [[TMP26]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP24:![0-9]+]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: @@ -1228,7 +1228,7 @@ define i32 @reduction_min(ptr nocapture %A, ptr nocapture %B) { ; CHECK: for.body: ; CHECK-NEXT: br i1 poison, label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP25:![0-9]+]] ; CHECK: for.end: -; CHECK-NEXT: [[RESULT_0_LCSSA:%.*]] = phi i32 [ poison, [[FOR_BODY]] ], [ [[TMP26]], [[MIDDLE_BLOCK]] ] +; CHECK-NEXT: [[RESULT_0_LCSSA:%.*]] = phi i32 [ poison, [[FOR_BODY]] ], [ [[RDX_MINMAX]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i32 [[RESULT_0_LCSSA]] ; entry: @@ -1260,7 +1260,7 @@ define i32 @reduction_max(ptr nocapture %A, ptr nocapture %B) { ; CHECK: vector.body: ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ] ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_LOAD_CONTINUE6]] ] -; CHECK-NEXT: [[VEC_PHI:%.*]] = phi i32 [ 1000, [[VECTOR_PH]] ], [ [[TMP26:%.*]], [[PRED_LOAD_CONTINUE6]] ] +; CHECK-NEXT: [[VEC_PHI:%.*]] = phi i32 [ 1000, [[VECTOR_PH]] ], [ [[RDX_MINMAX:%.*]], [[PRED_LOAD_CONTINUE6]] ] ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult <4 x i64> [[VEC_IND]], <i64 257, i64 257, i64 257, i64 257> ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i1> [[TMP0]], i64 0 ; CHECK-NEXT: br i1 [[TMP1]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]] @@ -1303,11 +1303,11 @@ define i32 @reduction_max(ptr nocapture %A, ptr nocapture %B) { ; CHECK-NEXT: [[TMP23:%.*]] = phi <4 x i32> [ [[TMP17]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP22]], [[PRED_LOAD_IF5]] ] ; CHECK-NEXT: [[TMP24:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[TMP23]], <4 x i32> zeroinitializer ; CHECK-NEXT: [[TMP25:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[TMP24]]) -; CHECK-NEXT: [[TMP26]] = call i32 @llvm.umax.i32(i32 [[TMP25]], i32 [[VEC_PHI]]) +; CHECK-NEXT: [[RDX_MINMAX]] = call i32 @llvm.umax.i32(i32 [[TMP25]], i32 [[VEC_PHI]]) ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 4 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i64> [[VEC_IND]], <i64 4, i64 4, i64 4, i64 4> -; CHECK-NEXT: [[TMP27:%.*]] = icmp eq i64 [[INDEX_NEXT]], 260 -; CHECK-NEXT: br i1 [[TMP27]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP26:![0-9]+]] +; CHECK-NEXT: [[TMP26:%.*]] = icmp eq i64 [[INDEX_NEXT]], 260 +; CHECK-NEXT: br i1 [[TMP26]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP26:![0-9]+]] ; CHECK: middle.block: ; CHECK-NEXT: br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: @@ -1315,7 +1315,7 @@ define i32 @reduction_max(ptr nocapture %A, ptr nocapture %B) { ; CHECK: for.body: ; CHECK-NEXT: br i1 poison, label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP27:![0-9]+]] ; CHECK: for.end: -; CHECK-NEXT: [[RESULT_0_LCSSA:%.*]] = phi i32 [ poison, [[FOR_BODY]] ], [ [[TMP26]], [[MIDDLE_BLOCK]] ] +; CHECK-NEXT: [[RESULT_0_LCSSA:%.*]] = phi i32 [ poison, [[FOR_BODY]] ], [ [[RDX_MINMAX]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret i32 [[RESULT_0_LCSSA]] ; entry: @@ -1351,25 +1351,25 @@ define float @reduction_conditional(ptr %A, ptr %B, ptr %C, float %S) { ; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x float> [ [[TMP0]], [[VECTOR_PH]] ], [ [[PREDPHI3:%.*]], [[VECTOR_BODY]] ] ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds float, ptr [[A:%.*]], i64 [[INDEX]] ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x float>, ptr [[TMP1]], align 4 -; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds float, ptr [[B:%.*]], i64 [[INDEX]] -; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <4 x float>, ptr [[TMP3]], align 4 -; CHECK-NEXT: [[TMP5:%.*]] = fcmp ogt <4 x float> [[WIDE_LOAD]], [[WIDE_LOAD1]] -; CHECK-NEXT: [[TMP6:%.*]] = fcmp ule <4 x float> [[WIDE_LOAD1]], <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00> -; CHECK-NEXT: [[TMP8:%.*]] = and <4 x i1> [[TMP5]], [[TMP6]] -; CHECK-NEXT: [[TMP7:%.*]] = fcmp ogt <4 x float> [[WIDE_LOAD]], <float 2.000000e+00, float 2.000000e+00, float 2.000000e+00, float 2.000000e+00> -; CHECK-NEXT: [[TMP9:%.*]] = and <4 x i1> [[TMP8]], [[TMP7]] -; CHECK-NEXT: [[TMP10:%.*]] = xor <4 x i1> [[TMP7]], <i1 true, i1 true, i1 true, i1 true> -; CHECK-NEXT: [[TMP11:%.*]] = and <4 x i1> [[TMP8]], [[TMP10]] -; CHECK-NEXT: [[TMP12:%.*]] = xor <4 x i1> [[TMP5]], <i1 true, i1 true, i1 true, i1 true> -; CHECK-NEXT: [[PREDPHI_V:%.*]] = select <4 x i1> [[TMP9]], <4 x float> [[WIDE_LOAD1]], <4 x float> [[WIDE_LOAD]] -; CHECK-NEXT: [[TMP13:%.*]] = select <4 x i1> [[TMP12]], <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i1> [[TMP11]] -; CHECK-NEXT: [[PREDPHI2:%.*]] = select <4 x i1> [[TMP13]], <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, <4 x float> [[PREDPHI_V]] -; CHECK-NEXT: [[PREDPHI3]] = fadd fast <4 x float> [[VEC_PHI]], [[PREDPHI2]] +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds float, ptr [[B:%.*]], i64 [[INDEX]] +; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <4 x float>, ptr [[TMP2]], align 4 +; CHECK-NEXT: [[TMP3:%.*]] = fcmp ogt <4 x float> [[WIDE_LOAD]], [[WIDE_LOAD1]] +; CHECK-NEXT: [[TMP4:%.*]] = fcmp ule <4 x float> [[WIDE_LOAD1]], <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00> +; CHECK-NEXT: [[TMP5:%.*]] = and <4 x i1> [[TMP3]], [[TMP4]] +; CHECK-NEXT: [[TMP6:%.*]] = fcmp ogt <4 x float> [[WIDE_LOAD]], <float 2.000000e+00, float 2.000000e+00, float 2.000000e+00, float 2.000000e+00> +; CHECK-NEXT: [[TMP7:%.*]] = and <4 x i1> [[TMP5]], [[TMP6]] +; CHECK-NEXT: [[TMP8:%.*]] = xor <4 x i1> [[TMP6]], <i1 true, i1 true, i1 true, i1 true> +; CHECK-NEXT: [[TMP9:%.*]] = and <4 x i1> [[TMP5]], [[TMP8]] +; CHECK-NEXT: [[TMP10:%.*]] = xor <4 x i1> [[TMP3]], <i1 true, i1 true, i1 true, i1 true> +; CHECK-NEXT: [[PREDPHI_V:%.*]] = select <4 x i1> [[TMP7]], <4 x float> [[WIDE_LOAD1]], <4 x float> [[WIDE_LOAD]] +; CHECK-NEXT: [[PREDPHI:%.*]] = fadd fast <4 x float> [[VEC_PHI]], [[PREDPHI_V]] +; CHECK-NEXT: [[TMP11:%.*]] = select <4 x i1> [[TMP10]], <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i1> [[TMP9]] +; CHECK-NEXT: [[PREDPHI3]] = select <4 x i1> [[TMP11]], <4 x float> [[VEC_PHI]], <4 x float> [[PREDPHI]] ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 -; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[INDEX_NEXT]], 128 -; CHECK-NEXT: br i1 [[TMP14]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP28:![0-9]+]] +; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], 128 +; CHECK-NEXT: br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP28:![0-9]+]] ; CHECK: middle.block: -; CHECK-NEXT: [[TMP15:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float -0.000000e+00, <4 x float> [[PREDPHI3]]) +; CHECK-NEXT: [[TMP13:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float -0.000000e+00, <4 x float> [[PREDPHI3]]) ; CHECK-NEXT: br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]] ; CHECK: scalar.ph: ; CHECK-NEXT: br label [[FOR_BODY:%.*]] @@ -1386,7 +1386,7 @@ define float @reduction_conditional(ptr %A, ptr %B, ptr %C, float %S) { ; CHECK: for.inc: ; CHECK-NEXT: br i1 poison, label [[FOR_BODY]], label [[FOR_END]], !llvm.loop [[LOOP29:![0-9]+]] ; CHECK: for.end: -; CHECK-NEXT: [[SUM_1_LCSSA:%.*]] = phi float [ poison, [[FOR_INC]] ], [ [[TMP15]], [[MIDDLE_BLOCK]] ] +; CHECK-NEXT: [[SUM_1_LCSSA:%.*]] = phi float [ poison, [[FOR_INC]] ], [ [[TMP13]], [[MIDDLE_BLOCK]] ] ; CHECK-NEXT: ret float [[SUM_1_LCSSA]] ; entry: diff --git a/llvm/test/Transforms/LoopVectorize/reduction-inloop.ll b/llvm/test/Transforms/LoopVectorize/reduction-inloop.ll index d85241167d0c..e8d57c935144 100644 --- a/llvm/test/Transforms/LoopVectorize/reduction-inloop.ll +++ b/llvm/test/Transforms/LoopVectorize/reduction-inloop.ll @@ -690,16 +690,16 @@ define float @reduction_conditional(ptr %A, ptr %B, ptr %C, float %S) { ; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <4 x float>, ptr [[TMP2]], align 4 ; CHECK-NEXT: [[TMP3:%.*]] = fcmp ogt <4 x float> [[WIDE_LOAD]], [[WIDE_LOAD1]] ; CHECK-NEXT: [[TMP4:%.*]] = fcmp ule <4 x float> [[WIDE_LOAD1]], <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00> -; CHECK-NEXT: [[TMP6:%.*]] = and <4 x i1> [[TMP3]], [[TMP4]] -; CHECK-NEXT: [[TMP5:%.*]] = fcmp ogt <4 x float> [[WIDE_LOAD]], <float 2.000000e+00, float 2.000000e+00, float 2.000000e+00, float 2.000000e+00> -; CHECK-NEXT: [[TMP7:%.*]] = and <4 x i1> [[TMP6]], [[TMP5]] -; CHECK-NEXT: [[TMP8:%.*]] = xor <4 x i1> [[TMP5]], <i1 true, i1 true, i1 true, i1 true> -; CHECK-NEXT: [[TMP9:%.*]] = and <4 x i1> [[TMP6]], [[TMP8]] +; CHECK-NEXT: [[TMP5:%.*]] = and <4 x i1> [[TMP3]], [[TMP4]] +; CHECK-NEXT: [[TMP6:%.*]] = fcmp ogt <4 x float> [[WIDE_LOAD]], <float 2.000000e+00, float 2.000000e+00, float 2.000000e+00, float 2.000000e+00> +; CHECK-NEXT: [[TMP7:%.*]] = and <4 x i1> [[TMP5]], [[TMP6]] +; CHECK-NEXT: [[TMP8:%.*]] = xor <4 x i1> [[TMP6]], <i1 true, i1 true, i1 true, i1 true> +; CHECK-NEXT: [[TMP9:%.*]] = and <4 x i1> [[TMP5]], [[TMP8]] ; CHECK-NEXT: [[TMP10:%.*]] = xor <4 x i1> [[TMP3]], <i1 true, i1 true, i1 true, i1 true> ; CHECK-NEXT: [[PREDPHI_V:%.*]] = select <4 x i1> [[TMP7]], <4 x float> [[WIDE_LOAD1]], <4 x float> [[WIDE_LOAD]] +; CHECK-NEXT: [[PREDPHI:%.*]] = fadd fast <4 x float> [[VEC_PHI]], [[PREDPHI_V]] ; CHECK-NEXT: [[TMP11:%.*]] = select <4 x i1> [[TMP10]], <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i1> [[TMP9]] -; CHECK-NEXT: [[PREDPHI2:%.*]] = select <4 x i1> [[TMP11]], <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, <4 x float> [[PREDPHI_V]] -; CHECK-NEXT: [[PREDPHI3]] = fadd fast <4 x float> [[VEC_PHI]], [[PREDPHI2]] +; CHECK-NEXT: [[PREDPHI3]] = select <4 x i1> [[TMP11]], <4 x float> [[VEC_PHI]], <4 x float> [[PREDPHI]] ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 ; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], 128 ; CHECK-NEXT: br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP28:![0-9]+]] diff --git a/llvm/test/Transforms/LoopVectorize/reduction.ll b/llvm/test/Transforms/LoopVectorize/reduction.ll index ba82bac6fad2..a47a38510eee 100644 --- a/llvm/test/Transforms/LoopVectorize/reduction.ll +++ b/llvm/test/Transforms/LoopVectorize/reduction.ll @@ -761,16 +761,16 @@ define float @reduction_conditional(ptr %A, ptr %B, ptr %C, float %S) { ; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <4 x float>, ptr [[TMP2]], align 4 ; CHECK-NEXT: [[TMP3:%.*]] = fcmp ogt <4 x float> [[WIDE_LOAD]], [[WIDE_LOAD1]] ; CHECK-NEXT: [[TMP4:%.*]] = fcmp ule <4 x float> [[WIDE_LOAD1]], <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00> -; CHECK-NEXT: [[TMP6:%.*]] = and <4 x i1> [[TMP3]], [[TMP4]] -; CHECK-NEXT: [[TMP5:%.*]] = fcmp ogt <4 x float> [[WIDE_LOAD]], <float 2.000000e+00, float 2.000000e+00, float 2.000000e+00, float 2.000000e+00> -; CHECK-NEXT: [[TMP7:%.*]] = and <4 x i1> [[TMP6]], [[TMP5]] -; CHECK-NEXT: [[TMP8:%.*]] = xor <4 x i1> [[TMP5]], <i1 true, i1 true, i1 true, i1 true> -; CHECK-NEXT: [[TMP9:%.*]] = and <4 x i1> [[TMP6]], [[TMP8]] +; CHECK-NEXT: [[TMP5:%.*]] = and <4 x i1> [[TMP3]], [[TMP4]] +; CHECK-NEXT: [[TMP6:%.*]] = fcmp ogt <4 x float> [[WIDE_LOAD]], <float 2.000000e+00, float 2.000000e+00, float 2.000000e+00, float 2.000000e+00> +; CHECK-NEXT: [[TMP7:%.*]] = and <4 x i1> [[TMP5]], [[TMP6]] +; CHECK-NEXT: [[TMP8:%.*]] = xor <4 x i1> [[TMP6]], <i1 true, i1 true, i1 true, i1 true> +; CHECK-NEXT: [[TMP9:%.*]] = and <4 x i1> [[TMP5]], [[TMP8]] ; CHECK-NEXT: [[TMP10:%.*]] = xor <4 x i1> [[TMP3]], <i1 true, i1 true, i1 true, i1 true> ; CHECK-NEXT: [[PREDPHI_V:%.*]] = select <4 x i1> [[TMP7]], <4 x float> [[WIDE_LOAD1]], <4 x float> [[WIDE_LOAD]] +; CHECK-NEXT: [[PREDPHI:%.*]] = fadd fast <4 x float> [[VEC_PHI]], [[PREDPHI_V]] ; CHECK-NEXT: [[TMP11:%.*]] = select <4 x i1> [[TMP10]], <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i1> [[TMP9]] -; CHECK-NEXT: [[PREDPHI2:%.*]] = select <4 x i1> [[TMP11]], <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, <4 x float> [[PREDPHI_V]] -; CHECK-NEXT: [[PREDPHI3]] = fadd fast <4 x float> [[VEC_PHI]], [[PREDPHI2]] +; CHECK-NEXT: [[PREDPHI3]] = select <4 x i1> [[TMP11]], <4 x float> [[VEC_PHI]], <4 x float> [[PREDPHI]] ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 ; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], 128 ; CHECK-NEXT: br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP20:![0-9]+]] diff --git a/llvm/test/Transforms/PhaseOrdering/AArch64/hoisting-sinking-required-for-vectorization.ll b/llvm/test/Transforms/PhaseOrdering/AArch64/hoisting-sinking-required-for-vectorization.ll index 33cfd0aa8574..ad100c399c08 100644 --- a/llvm/test/Transforms/PhaseOrdering/AArch64/hoisting-sinking-required-for-vectorization.ll +++ b/llvm/test/Transforms/PhaseOrdering/AArch64/hoisting-sinking-required-for-vectorization.ll @@ -164,10 +164,10 @@ define void @loop2(ptr %A, ptr %B, ptr %C, float %x) { ; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP8]], i64 16 ; CHECK-NEXT: [[WIDE_LOAD10:%.*]] = load <4 x float>, ptr [[TMP8]], align 4, !alias.scope [[META9:![0-9]+]], !noalias [[META11:![0-9]+]] ; CHECK-NEXT: [[WIDE_LOAD11:%.*]] = load <4 x float>, ptr [[TMP9]], align 4, !alias.scope [[META9]], !noalias [[META11]] -; CHECK-NEXT: [[TMP10:%.*]] = select <4 x i1> [[TMP2]], <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, <4 x float> [[WIDE_LOAD10]] -; CHECK-NEXT: [[PREDPHI:%.*]] = fadd <4 x float> [[TMP6]], [[TMP10]] -; CHECK-NEXT: [[TMP11:%.*]] = select <4 x i1> [[TMP3]], <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, <4 x float> [[WIDE_LOAD11]] -; CHECK-NEXT: [[PREDPHI12:%.*]] = fadd <4 x float> [[TMP7]], [[TMP11]] +; CHECK-NEXT: [[TMP10:%.*]] = fadd <4 x float> [[TMP6]], [[WIDE_LOAD10]] +; CHECK-NEXT: [[TMP11:%.*]] = fadd <4 x float> [[TMP7]], [[WIDE_LOAD11]] +; CHECK-NEXT: [[PREDPHI:%.*]] = select <4 x i1> [[TMP2]], <4 x float> [[TMP6]], <4 x float> [[TMP10]] +; CHECK-NEXT: [[PREDPHI12:%.*]] = select <4 x i1> [[TMP3]], <4 x float> [[TMP7]], <4 x float> [[TMP11]] ; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i8, ptr [[TMP8]], i64 16 ; CHECK-NEXT: store <4 x float> [[PREDPHI]], ptr [[TMP8]], align 4, !alias.scope [[META9]], !noalias [[META11]] ; CHECK-NEXT: store <4 x float> [[PREDPHI12]], ptr [[TMP12]], align 4, !alias.scope [[META9]], !noalias [[META11]] -- GitLab From 9ed1aa36be654f6687c4f9000c973b722217881c Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aaron@aaronballman.com> Date: Tue, 19 Mar 2024 12:44:20 -0400 Subject: [PATCH 110/307] Fixing up an edit missed in #84014; NFC --- clang/lib/AST/DeclPrinter.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index ad45da6b8f56..edbcdfe4d55b 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -1037,12 +1037,9 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { : D->getName(); if (!Policy.SuppressTagKeyword && Policy.SuppressScope && - !Policy.SuppressUnwrittenScope) { + !Policy.SuppressUnwrittenScope) MaybePrintTagKeywordIfSupressingScopes(Policy, T, Out); - printDeclType(T, Name); - } else { - printDeclType(T, Name); - } + printDeclType(T, Name); // Print the attributes that should be placed right before the end of the // decl. -- GitLab From ab76052fa9331f418d7911cafefabd4dd0c1941e Mon Sep 17 00:00:00 2001 From: Changpeng Fang <changpeng.fang@amd.com> Date: Tue, 19 Mar 2024 09:58:09 -0700 Subject: [PATCH 111/307] AMDGPU: Treat SWMMAC the same as MFMA and other WMMA for sched_barrier (#85721) --- llvm/lib/Target/AMDGPU/SIInstrInfo.h | 2 +- .../llvm.amdgcn.sched.group.barrier.gfx12.ll | 333 ++++++++++++++++++ 2 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/AMDGPU/llvm.amdgcn.sched.group.barrier.gfx12.ll diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h index a62bf779fe2e..4c5978cdc666 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h @@ -815,7 +815,7 @@ public: } static bool isMFMAorWMMA(const MachineInstr &MI) { - return isMFMA(MI) || isWMMA(MI); + return isMFMA(MI) || isWMMA(MI) || isSWMMAC(MI); } static bool isSWMMAC(const MachineInstr &MI) { diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.sched.group.barrier.gfx12.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.sched.group.barrier.gfx12.ll new file mode 100644 index 000000000000..fdcb1773d0a3 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.sched.group.barrier.gfx12.ll @@ -0,0 +1,333 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=amdgcn -mcpu=gfx1200 -misched-cluster=0 < %s | FileCheck -check-prefix=GCN %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx1200 -misched-cluster=0 -amdgpu-igrouplp-exact-solver-max-branches=250000 < %s | FileCheck -check-prefix=EXACTCUTOFF %s + +declare <8 x half> @llvm.amdgcn.swmmac.f16.16x16x32.f16.v8f16.v8f16.v16f16..i16(<8 x half>, <16 x half>, <8 x half>, i16) + +define amdgpu_kernel void @test_sched_group_barrier_pipeline_SWMMAC_cluster(ptr addrspace(3) noalias %in, ptr addrspace(3) noalias %out) #0 { +; GCN-LABEL: test_sched_group_barrier_pipeline_SWMMAC_cluster: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: s_load_b64 s[0:1], s[0:1], 0x24 +; GCN-NEXT: v_lshlrev_b32_e32 v28, 4, v0 +; GCN-NEXT: v_mov_b32_e32 v48, 0 +; GCN-NEXT: s_wait_kmcnt 0x0 +; GCN-NEXT: s_delay_alu instid0(VALU_DEP_2) +; GCN-NEXT: v_add_nc_u32_e32 v0, s0, v28 +; GCN-NEXT: v_dual_mov_b32 v50, s1 :: v_dual_add_nc_u32 v49, s1, v28 +; GCN-NEXT: ds_load_b128 v[8:11], v0 +; GCN-NEXT: ds_load_b128 v[12:15], v0 offset:512 +; GCN-NEXT: ds_load_b128 v[16:19], v0 offset:1536 +; GCN-NEXT: ds_load_b128 v[20:23], v0 offset:3072 +; GCN-NEXT: ds_load_b128 v[24:27], v0 offset:5120 +; GCN-NEXT: ds_load_b128 v[4:7], v0 offset:11280 +; GCN-NEXT: ds_load_b128 v[0:3], v0 offset:11264 +; GCN-NEXT: ; sched_group_barrier mask(0x00000100) size(7) SyncID(0) +; GCN-NEXT: s_wait_dscnt 0x6 +; GCN-NEXT: v_mov_b32_e32 v31, v11 +; GCN-NEXT: s_wait_dscnt 0x5 +; GCN-NEXT: v_mov_b32_e32 v35, v15 +; GCN-NEXT: s_wait_dscnt 0x4 +; GCN-NEXT: v_mov_b32_e32 v39, v19 +; GCN-NEXT: s_wait_dscnt 0x3 +; GCN-NEXT: v_mov_b32_e32 v43, v23 +; GCN-NEXT: s_wait_dscnt 0x2 +; GCN-NEXT: v_dual_mov_b32 v47, v27 :: v_dual_mov_b32 v30, v10 +; GCN-NEXT: v_dual_mov_b32 v29, v9 :: v_dual_mov_b32 v28, v8 +; GCN-NEXT: v_dual_mov_b32 v34, v14 :: v_dual_mov_b32 v33, v13 +; GCN-NEXT: v_mov_b32_e32 v32, v12 +; GCN-NEXT: v_dual_mov_b32 v38, v18 :: v_dual_mov_b32 v37, v17 +; GCN-NEXT: v_mov_b32_e32 v36, v16 +; GCN-NEXT: v_dual_mov_b32 v42, v22 :: v_dual_mov_b32 v41, v21 +; GCN-NEXT: v_mov_b32_e32 v40, v20 +; GCN-NEXT: v_dual_mov_b32 v46, v26 :: v_dual_mov_b32 v45, v25 +; GCN-NEXT: v_mov_b32_e32 v44, v24 +; GCN-NEXT: s_wait_dscnt 0x0 +; GCN-NEXT: v_swmmac_f16_16x16x32_f16 v[28:31], v[8:11], v[0:7], v48 +; GCN-NEXT: v_swmmac_f16_16x16x32_f16 v[32:35], v[12:15], v[0:7], v48 +; GCN-NEXT: v_swmmac_f16_16x16x32_f16 v[36:39], v[16:19], v[0:7], v48 +; GCN-NEXT: v_swmmac_f16_16x16x32_f16 v[40:43], v[20:23], v[0:7], v48 +; GCN-NEXT: v_swmmac_f16_16x16x32_f16 v[44:47], v[24:27], v[0:7], v48 +; GCN-NEXT: ds_store_b128 v49, v[28:31] +; GCN-NEXT: ds_store_b128 v50, v[32:35] offset:512 +; GCN-NEXT: ds_store_b128 v50, v[36:39] offset:1024 +; GCN-NEXT: ds_store_b128 v50, v[40:43] offset:1536 +; GCN-NEXT: ds_store_b128 v50, v[44:47] offset:2048 +; GCN-NEXT: ; sched_group_barrier mask(0x00000008) size(5) SyncID(0) +; GCN-NEXT: ; sched_group_barrier mask(0x00000200) size(5) SyncID(0) +; GCN-NEXT: s_endpgm +; +; EXACTCUTOFF-LABEL: test_sched_group_barrier_pipeline_SWMMAC_cluster: +; EXACTCUTOFF: ; %bb.0: ; %entry +; EXACTCUTOFF-NEXT: s_load_b64 s[0:1], s[0:1], 0x24 +; EXACTCUTOFF-NEXT: v_lshlrev_b32_e32 v28, 4, v0 +; EXACTCUTOFF-NEXT: v_mov_b32_e32 v48, 0 +; EXACTCUTOFF-NEXT: s_wait_kmcnt 0x0 +; EXACTCUTOFF-NEXT: s_delay_alu instid0(VALU_DEP_2) +; EXACTCUTOFF-NEXT: v_add_nc_u32_e32 v0, s0, v28 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v50, s1 :: v_dual_add_nc_u32 v49, s1, v28 +; EXACTCUTOFF-NEXT: ds_load_b128 v[8:11], v0 +; EXACTCUTOFF-NEXT: ds_load_b128 v[12:15], v0 offset:512 +; EXACTCUTOFF-NEXT: ds_load_b128 v[16:19], v0 offset:1536 +; EXACTCUTOFF-NEXT: ds_load_b128 v[20:23], v0 offset:3072 +; EXACTCUTOFF-NEXT: ds_load_b128 v[24:27], v0 offset:5120 +; EXACTCUTOFF-NEXT: ds_load_b128 v[4:7], v0 offset:11280 +; EXACTCUTOFF-NEXT: ds_load_b128 v[0:3], v0 offset:11264 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000100) size(7) SyncID(0) +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x6 +; EXACTCUTOFF-NEXT: v_mov_b32_e32 v31, v11 +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x5 +; EXACTCUTOFF-NEXT: v_mov_b32_e32 v35, v15 +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x4 +; EXACTCUTOFF-NEXT: v_mov_b32_e32 v39, v19 +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x3 +; EXACTCUTOFF-NEXT: v_mov_b32_e32 v43, v23 +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x2 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v47, v27 :: v_dual_mov_b32 v30, v10 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v29, v9 :: v_dual_mov_b32 v28, v8 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v34, v14 :: v_dual_mov_b32 v33, v13 +; EXACTCUTOFF-NEXT: v_mov_b32_e32 v32, v12 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v38, v18 :: v_dual_mov_b32 v37, v17 +; EXACTCUTOFF-NEXT: v_mov_b32_e32 v36, v16 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v42, v22 :: v_dual_mov_b32 v41, v21 +; EXACTCUTOFF-NEXT: v_mov_b32_e32 v40, v20 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v46, v26 :: v_dual_mov_b32 v45, v25 +; EXACTCUTOFF-NEXT: v_mov_b32_e32 v44, v24 +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x0 +; EXACTCUTOFF-NEXT: v_swmmac_f16_16x16x32_f16 v[28:31], v[8:11], v[0:7], v48 +; EXACTCUTOFF-NEXT: v_swmmac_f16_16x16x32_f16 v[32:35], v[12:15], v[0:7], v48 +; EXACTCUTOFF-NEXT: v_swmmac_f16_16x16x32_f16 v[36:39], v[16:19], v[0:7], v48 +; EXACTCUTOFF-NEXT: v_swmmac_f16_16x16x32_f16 v[40:43], v[20:23], v[0:7], v48 +; EXACTCUTOFF-NEXT: v_swmmac_f16_16x16x32_f16 v[44:47], v[24:27], v[0:7], v48 +; EXACTCUTOFF-NEXT: ds_store_b128 v49, v[28:31] +; EXACTCUTOFF-NEXT: ds_store_b128 v50, v[32:35] offset:512 +; EXACTCUTOFF-NEXT: ds_store_b128 v50, v[36:39] offset:1024 +; EXACTCUTOFF-NEXT: ds_store_b128 v50, v[40:43] offset:1536 +; EXACTCUTOFF-NEXT: ds_store_b128 v50, v[44:47] offset:2048 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000008) size(5) SyncID(0) +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000200) size(5) SyncID(0) +; EXACTCUTOFF-NEXT: s_endpgm +entry: + %idx = call i32 @llvm.amdgcn.workitem.id.x() + %load.0.addr = getelementptr <8 x half>, ptr addrspace(3) %in, i32 %idx + %load.0 = load <8 x half>, ptr addrspace(3) %load.0.addr + %load.1.addr = getelementptr <8 x half>, ptr addrspace(3) %load.0.addr, i32 32 + %load.1 = load <8 x half>, ptr addrspace(3) %load.1.addr + %load.2.addr = getelementptr <8 x half>, ptr addrspace(3) %load.1.addr, i32 64 + %load.2 = load <8 x half>, ptr addrspace(3) %load.2.addr + %load.3.addr = getelementptr <8 x half>, ptr addrspace(3) %load.2.addr, i32 96 + %load.3 = load <8 x half>, ptr addrspace(3) %load.3.addr + %load.4.addr = getelementptr <8 x half>, ptr addrspace(3) %load.3.addr, i32 128 + %load.4 = load <8 x half>, ptr addrspace(3) %load.4.addr + %load.b.addr = getelementptr <16 x half>, ptr addrspace(3) %load.4.addr, i32 192 + %load.b = load <16 x half>, ptr addrspace(3) %load.b.addr + %mai.0 = call <8 x half> @llvm.amdgcn.swmmac.f16.16x16x32.f16.v8f16.v8f16.v16f16.i16(<8 x half> %load.0, <16 x half> %load.b, <8 x half> %load.0, i1 0) + %mai.1 = call <8 x half> @llvm.amdgcn.swmmac.f16.16x16x32.f16.v8f16.v8f16.v16f16.i16(<8 x half> %load.1, <16 x half> %load.b, <8 x half> %load.1, i1 0) + %mai.2 = call <8 x half> @llvm.amdgcn.swmmac.f16.16x16x32.f16.v8f16.v8f16.v16f16.i16(<8 x half> %load.2, <16 x half> %load.b, <8 x half> %load.2, i1 0) + %mai.3 = call <8 x half> @llvm.amdgcn.swmmac.f16.16x16x32.f16.v8f16.v8f16.v16f16.i16(<8 x half> %load.3, <16 x half> %load.b, <8 x half> %load.3, i1 0) + %mai.4 = call <8 x half> @llvm.amdgcn.swmmac.f16.16x16x32.f16.v8f16.v8f16.v16f16.i16(<8 x half> %load.4, <16 x half> %load.b, <8 x half> %load.4, i1 0) + %store.0.addr = getelementptr <8 x half>, ptr addrspace(3) %out, i32 %idx + store <8 x half> %mai.0, ptr addrspace(3) %store.0.addr + %store.1.addr = getelementptr <8 x half>, ptr addrspace(3) %out, i32 32 + store <8 x half> %mai.1, ptr addrspace(3) %store.1.addr + %store.2.addr = getelementptr <8 x half>, ptr addrspace(3) %out, i32 64 + store <8 x half> %mai.2, ptr addrspace(3) %store.2.addr + %store.3.addr = getelementptr <8 x half>, ptr addrspace(3) %out, i32 96 + store <8 x half> %mai.3, ptr addrspace(3) %store.3.addr + %store.4.addr = getelementptr <8 x half>, ptr addrspace(3) %out, i32 128 + store <8 x half> %mai.4, ptr addrspace(3) %store.4.addr + ; 7 DS read + call void @llvm.amdgcn.sched.group.barrier(i32 256, i32 7, i32 0) + ; 5 SWMMAC + call void @llvm.amdgcn.sched.group.barrier(i32 8, i32 5, i32 0) + ; 5 DS write + call void @llvm.amdgcn.sched.group.barrier(i32 512, i32 5, i32 0) + ret void +} + +define amdgpu_kernel void @test_sched_group_barrier_pipeline_SWMMAC_interleaved(ptr addrspace(3) noalias %in, ptr addrspace(3) noalias %out) #0 { +; GCN-LABEL: test_sched_group_barrier_pipeline_SWMMAC_interleaved: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: s_load_b64 s[0:1], s[0:1], 0x24 +; GCN-NEXT: v_mov_b32_e32 v18, 0 +; GCN-NEXT: s_wait_kmcnt 0x0 +; GCN-NEXT: v_lshl_add_u32 v17, v0, 5, s0 +; GCN-NEXT: v_lshl_add_u32 v0, v0, 4, s1 +; GCN-NEXT: ds_load_b128 v[9:12], v17 offset:1024 +; GCN-NEXT: ds_load_b128 v[1:4], v17 +; GCN-NEXT: ds_load_b128 v[5:8], v17 offset:16 +; GCN-NEXT: ; sched_group_barrier mask(0x00000100) size(3) SyncID(0) +; GCN-NEXT: s_wait_dscnt 0x2 +; GCN-NEXT: v_dual_mov_b32 v16, v12 :: v_dual_mov_b32 v15, v11 +; GCN-NEXT: v_dual_mov_b32 v14, v10 :: v_dual_mov_b32 v13, v9 +; GCN-NEXT: s_wait_dscnt 0x0 +; GCN-NEXT: s_delay_alu instid0(VALU_DEP_1) +; GCN-NEXT: v_swmmac_f16_16x16x32_f16 v[13:16], v[9:12], v[1:8], v18 +; GCN-NEXT: ; sched_group_barrier mask(0x00000008) size(1) SyncID(0) +; GCN-NEXT: ds_store_b128 v0, v[13:16] +; GCN-NEXT: ds_load_b128 v[9:12], v17 offset:2560 +; GCN-NEXT: v_mov_b32_e32 v0, s1 +; GCN-NEXT: ; sched_group_barrier mask(0x00000200) size(1) SyncID(0) +; GCN-NEXT: ; sched_group_barrier mask(0x00000100) size(1) SyncID(0) +; GCN-NEXT: s_wait_dscnt 0x0 +; GCN-NEXT: v_dual_mov_b32 v16, v12 :: v_dual_mov_b32 v15, v11 +; GCN-NEXT: v_dual_mov_b32 v14, v10 :: v_dual_mov_b32 v13, v9 +; GCN-NEXT: s_delay_alu instid0(VALU_DEP_1) +; GCN-NEXT: v_swmmac_f16_16x16x32_f16 v[13:16], v[9:12], v[1:8], v18 +; GCN-NEXT: ; sched_group_barrier mask(0x00000008) size(1) SyncID(0) +; GCN-NEXT: ds_store_b128 v0, v[13:16] offset:512 +; GCN-NEXT: ds_load_b128 v[9:12], v17 offset:4608 +; GCN-NEXT: ; sched_group_barrier mask(0x00000200) size(1) SyncID(0) +; GCN-NEXT: ; sched_group_barrier mask(0x00000100) size(1) SyncID(0) +; GCN-NEXT: s_wait_dscnt 0x0 +; GCN-NEXT: v_dual_mov_b32 v16, v12 :: v_dual_mov_b32 v15, v11 +; GCN-NEXT: v_dual_mov_b32 v14, v10 :: v_dual_mov_b32 v13, v9 +; GCN-NEXT: s_delay_alu instid0(VALU_DEP_1) +; GCN-NEXT: v_swmmac_f16_16x16x32_f16 v[13:16], v[9:12], v[1:8], v18 +; GCN-NEXT: ; sched_group_barrier mask(0x00000008) size(1) SyncID(0) +; GCN-NEXT: ds_store_b128 v0, v[13:16] offset:1024 +; GCN-NEXT: ds_load_b128 v[9:12], v17 offset:7168 +; GCN-NEXT: ; sched_group_barrier mask(0x00000200) size(1) SyncID(0) +; GCN-NEXT: ; sched_group_barrier mask(0x00000100) size(1) SyncID(0) +; GCN-NEXT: s_wait_dscnt 0x0 +; GCN-NEXT: v_dual_mov_b32 v16, v12 :: v_dual_mov_b32 v15, v11 +; GCN-NEXT: v_dual_mov_b32 v14, v10 :: v_dual_mov_b32 v13, v9 +; GCN-NEXT: s_delay_alu instid0(VALU_DEP_1) +; GCN-NEXT: v_swmmac_f16_16x16x32_f16 v[13:16], v[9:12], v[1:8], v18 +; GCN-NEXT: ; sched_group_barrier mask(0x00000008) size(1) SyncID(0) +; GCN-NEXT: ds_store_b128 v0, v[13:16] offset:1536 +; GCN-NEXT: ds_load_b128 v[9:12], v17 offset:10240 +; GCN-NEXT: ; sched_group_barrier mask(0x00000200) size(1) SyncID(0) +; GCN-NEXT: ; sched_group_barrier mask(0x00000100) size(1) SyncID(0) +; GCN-NEXT: s_wait_dscnt 0x0 +; GCN-NEXT: v_dual_mov_b32 v16, v12 :: v_dual_mov_b32 v15, v11 +; GCN-NEXT: v_dual_mov_b32 v14, v10 :: v_dual_mov_b32 v13, v9 +; GCN-NEXT: s_delay_alu instid0(VALU_DEP_1) +; GCN-NEXT: v_swmmac_f16_16x16x32_f16 v[13:16], v[9:12], v[1:8], v18 +; GCN-NEXT: ; sched_group_barrier mask(0x00000008) size(1) SyncID(0) +; GCN-NEXT: ds_store_b128 v0, v[13:16] offset:2048 +; GCN-NEXT: ; sched_group_barrier mask(0x00000200) size(1) SyncID(0) +; GCN-NEXT: s_endpgm +; +; EXACTCUTOFF-LABEL: test_sched_group_barrier_pipeline_SWMMAC_interleaved: +; EXACTCUTOFF: ; %bb.0: ; %entry +; EXACTCUTOFF-NEXT: s_load_b64 s[0:1], s[0:1], 0x24 +; EXACTCUTOFF-NEXT: v_mov_b32_e32 v18, 0 +; EXACTCUTOFF-NEXT: s_wait_kmcnt 0x0 +; EXACTCUTOFF-NEXT: v_lshl_add_u32 v17, v0, 5, s0 +; EXACTCUTOFF-NEXT: v_lshl_add_u32 v0, v0, 4, s1 +; EXACTCUTOFF-NEXT: ds_load_b128 v[9:12], v17 offset:1024 +; EXACTCUTOFF-NEXT: ds_load_b128 v[1:4], v17 +; EXACTCUTOFF-NEXT: ds_load_b128 v[5:8], v17 offset:16 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000100) size(3) SyncID(0) +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x2 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v16, v12 :: v_dual_mov_b32 v15, v11 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v14, v10 :: v_dual_mov_b32 v13, v9 +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x0 +; EXACTCUTOFF-NEXT: s_delay_alu instid0(VALU_DEP_1) +; EXACTCUTOFF-NEXT: v_swmmac_f16_16x16x32_f16 v[13:16], v[9:12], v[1:8], v18 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000008) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: ds_store_b128 v0, v[13:16] +; EXACTCUTOFF-NEXT: ds_load_b128 v[9:12], v17 offset:2560 +; EXACTCUTOFF-NEXT: v_mov_b32_e32 v0, s1 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000200) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000100) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x0 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v16, v12 :: v_dual_mov_b32 v15, v11 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v14, v10 :: v_dual_mov_b32 v13, v9 +; EXACTCUTOFF-NEXT: s_delay_alu instid0(VALU_DEP_1) +; EXACTCUTOFF-NEXT: v_swmmac_f16_16x16x32_f16 v[13:16], v[9:12], v[1:8], v18 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000008) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: ds_store_b128 v0, v[13:16] offset:512 +; EXACTCUTOFF-NEXT: ds_load_b128 v[9:12], v17 offset:4608 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000200) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000100) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x0 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v16, v12 :: v_dual_mov_b32 v15, v11 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v14, v10 :: v_dual_mov_b32 v13, v9 +; EXACTCUTOFF-NEXT: s_delay_alu instid0(VALU_DEP_1) +; EXACTCUTOFF-NEXT: v_swmmac_f16_16x16x32_f16 v[13:16], v[9:12], v[1:8], v18 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000008) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: ds_store_b128 v0, v[13:16] offset:1024 +; EXACTCUTOFF-NEXT: ds_load_b128 v[9:12], v17 offset:7168 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000200) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000100) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x0 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v16, v12 :: v_dual_mov_b32 v15, v11 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v14, v10 :: v_dual_mov_b32 v13, v9 +; EXACTCUTOFF-NEXT: s_delay_alu instid0(VALU_DEP_1) +; EXACTCUTOFF-NEXT: v_swmmac_f16_16x16x32_f16 v[13:16], v[9:12], v[1:8], v18 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000008) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: ds_store_b128 v0, v[13:16] offset:1536 +; EXACTCUTOFF-NEXT: ds_load_b128 v[9:12], v17 offset:10240 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000200) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000100) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: s_wait_dscnt 0x0 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v16, v12 :: v_dual_mov_b32 v15, v11 +; EXACTCUTOFF-NEXT: v_dual_mov_b32 v14, v10 :: v_dual_mov_b32 v13, v9 +; EXACTCUTOFF-NEXT: s_delay_alu instid0(VALU_DEP_1) +; EXACTCUTOFF-NEXT: v_swmmac_f16_16x16x32_f16 v[13:16], v[9:12], v[1:8], v18 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000008) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: ds_store_b128 v0, v[13:16] offset:2048 +; EXACTCUTOFF-NEXT: ; sched_group_barrier mask(0x00000200) size(1) SyncID(0) +; EXACTCUTOFF-NEXT: s_endpgm +entry: + %idx = call i32 @llvm.amdgcn.workitem.id.x() + %load.b.addr = getelementptr <16 x half>, ptr addrspace(3) %in, i32 %idx + %load.b = load <16 x half>, ptr addrspace(3) %load.b.addr + %load.0.addr = getelementptr <8 x half>, ptr addrspace(3) %load.b.addr, i32 64 + %load.0 = load <8 x half>, ptr addrspace(3) %load.0.addr + %load.1.addr = getelementptr <8 x half>, ptr addrspace(3) %load.0.addr, i32 96 + %load.1 = load <8 x half>, ptr addrspace(3) %load.1.addr + %load.2.addr = getelementptr <8 x half>, ptr addrspace(3) %load.1.addr, i32 128 + %load.2 = load <8 x half>, ptr addrspace(3) %load.2.addr + %load.3.addr = getelementptr <8 x half>, ptr addrspace(3) %load.2.addr, i32 160 + %load.3 = load <8 x half>, ptr addrspace(3) %load.3.addr + %load.4.addr = getelementptr <8 x half>, ptr addrspace(3) %load.3.addr, i32 192 + %load.4 = load <8 x half>, ptr addrspace(3) %load.4.addr + %mai.0 = call <8 x half> @llvm.amdgcn.swmmac.f16.16x16x32.f16.v8f16.v8f16.v16f16.i16(<8 x half> %load.0, <16 x half> %load.b, <8 x half> %load.0, i1 0) + %mai.1 = call <8 x half> @llvm.amdgcn.swmmac.f16.16x16x32.f16.v8f16.v8f16.v16f16.i16(<8 x half> %load.1, <16 x half> %load.b, <8 x half> %load.1, i1 0) + %mai.2 = call <8 x half> @llvm.amdgcn.swmmac.f16.16x16x32.f16.v8f16.v8f16.v16f16.i16(<8 x half> %load.2, <16 x half> %load.b, <8 x half> %load.2, i1 0) + %mai.3 = call <8 x half> @llvm.amdgcn.swmmac.f16.16x16x32.f16.v8f16.v8f16.v16f16.i16(<8 x half> %load.3, <16 x half> %load.b, <8 x half> %load.3, i1 0) + %mai.4 = call <8 x half> @llvm.amdgcn.swmmac.f16.16x16x32.f16.v8f16.v8f16.v16f16.i16(<8 x half> %load.4, <16 x half> %load.b, <8 x half> %load.4, i1 0) + %store.0.addr = getelementptr <8 x half>, ptr addrspace(3) %out, i32 %idx + store <8 x half> %mai.0, ptr addrspace(3) %store.0.addr + %store.1.addr = getelementptr <8 x half>, ptr addrspace(3) %out, i32 32 + store <8 x half> %mai.1, ptr addrspace(3) %store.1.addr + %store.2.addr = getelementptr <8 x half>, ptr addrspace(3) %out, i32 64 + store <8 x half> %mai.2, ptr addrspace(3) %store.2.addr + %store.3.addr = getelementptr <8 x half>, ptr addrspace(3) %out, i32 96 + store <8 x half> %mai.3, ptr addrspace(3) %store.3.addr + %store.4.addr = getelementptr <8 x half>, ptr addrspace(3) %out, i32 128 + store <8 x half> %mai.4, ptr addrspace(3) %store.4.addr + ; 3 DS read + call void @llvm.amdgcn.sched.group.barrier(i32 256, i32 3, i32 0) + ; 1 SWMMAC + call void @llvm.amdgcn.sched.group.barrier(i32 8, i32 1, i32 0) + ; 1 DS write + call void @llvm.amdgcn.sched.group.barrier(i32 512, i32 1, i32 0) + ; 1 DS read + call void @llvm.amdgcn.sched.group.barrier(i32 256, i32 1, i32 0) + ; 1 SWMMAC + call void @llvm.amdgcn.sched.group.barrier(i32 8, i32 1, i32 0) + ; 1 DS write + call void @llvm.amdgcn.sched.group.barrier(i32 512, i32 1, i32 0) + ; 1 DS read + call void @llvm.amdgcn.sched.group.barrier(i32 256, i32 1, i32 0) + ; 1 SWMMAC + call void @llvm.amdgcn.sched.group.barrier(i32 8, i32 1, i32 0) + ; 1 DS write + call void @llvm.amdgcn.sched.group.barrier(i32 512, i32 1, i32 0) + ; 1 DS read + call void @llvm.amdgcn.sched.group.barrier(i32 256, i32 1, i32 0) + ; 1 SWMMAC + call void @llvm.amdgcn.sched.group.barrier(i32 8, i32 1, i32 0) + ; 1 DS write + call void @llvm.amdgcn.sched.group.barrier(i32 512, i32 1, i32 0) + ; 1 DS read + call void @llvm.amdgcn.sched.group.barrier(i32 256, i32 1, i32 0) + ; 1 SWMMAC + call void @llvm.amdgcn.sched.group.barrier(i32 8, i32 1, i32 0) + ; 1 DS write + call void @llvm.amdgcn.sched.group.barrier(i32 512, i32 1, i32 0) + ret void +} -- GitLab From fe84369cc6759194e006f3f624a064bce13c84d4 Mon Sep 17 00:00:00 2001 From: Kojo Acquah <KoolJBlack@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:09:33 -0700 Subject: [PATCH 112/307] [mlir][ArmNeon] Implements unrolling patterns for LowerContractionToSMMLAPattern (#84848) This patch updates `LowerContractionToSMMLAPattern` to unroll larger vector contracts into multiple smmla instructions. Now accepts up to [8,8,8] tiles (previously only [2,2,8]). The N/M dimensions must be powers of 2. `vector.extract_strided_slice`/`vector.insert_strided_slice` divides the contract into tiles to be processed in a row. --- .../LowerContractionToSMMLAPattern.cpp | 112 +++++++++++++----- .../Dialect/ArmNeon/lower-to-arm-neon.mlir | 94 +++++++++++++++ 2 files changed, 174 insertions(+), 32 deletions(-) diff --git a/mlir/lib/Dialect/ArmNeon/Transforms/LowerContractionToSMMLAPattern.cpp b/mlir/lib/Dialect/ArmNeon/Transforms/LowerContractionToSMMLAPattern.cpp index 47c84708f3c3..1f48d27aa27b 100644 --- a/mlir/lib/Dialect/ArmNeon/Transforms/LowerContractionToSMMLAPattern.cpp +++ b/mlir/lib/Dialect/ArmNeon/Transforms/LowerContractionToSMMLAPattern.cpp @@ -16,7 +16,9 @@ #include "mlir/Dialect/ArmNeon/Transforms.h" #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/Dialect/Utils/IndexingUtils.h" #include "mlir/Dialect/Vector/IR/VectorOps.h" +#include "mlir/IR/AffineMap.h" #include "mlir/IR/PatternMatch.h" #include "mlir/Support/LogicalResult.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" @@ -36,8 +38,10 @@ static Type matchContainerType(Type element, Type container) { return element; } -/// Lowering from a single vector::contractOp directly to the arm neon smmla -/// intrinsic. The shapes of the contract and intrinsic must match. +/// Lowering from a vector::contractOp arm neon smmla intrinsic. This will tile +/// any vector.contract into multiple smmla instructions with unrolling so long +/// as [2,2,8] is a divisor of its shape. If no unrolling is necessary, a single +/// smmla instruction is emitted. class LowerContractionToSMMLAPattern : public OpRewritePattern<vector::ContractionOp> { public: @@ -45,10 +49,6 @@ public: LogicalResult matchAndRewrite(vector::ContractionOp op, PatternRewriter &rewriter) const override { Location loc = op.getLoc(); - Value lhs = op.getLhs(); - Value rhs = op.getRhs(); - Value res = op.getAcc(); - // Check index maps that represent M N K in contract. auto indexingMaps = op.getIndexingMapsArray(); if (llvm::any_of(indexingMaps, [](mlir::AffineMap affineMap) { @@ -57,7 +57,6 @@ public: })) { return failure(); } - // Check iterator types for contract. auto iteratorTypes = op.getIteratorTypesArray(); if (iteratorTypes.size() != 3 || @@ -66,22 +65,24 @@ public: iteratorTypes[2] != vector::IteratorType::reduction) { return failure(); } - - // Check the tile size by mapping the dimensions of the contract. + // Infer tile sizes from operands; Note: RHS is not transposed. mlir::VectorType lhsType = op.getLhsType(); mlir::VectorType rhsType = op.getRhsType(); auto dimM = lhsType.getDimSize(0); auto dimN = rhsType.getDimSize(0); auto dimK = lhsType.getDimSize(1); - if (rhsType.getDimSize(1) != dimK || dimM != 2 || dimN != 2 || dimK != 8) { + + // Unrolling patterns can handle any [2, 2, 8] shaped multiple of inputs for + // tiling. + if (dimM % 2 != 0 || dimN % 2 != 0 || dimK % 8 != 0) { return failure(); } // Check two extsi inputs Rhs Lhs for contract. arith::ExtSIOp origLhsExtOp = - dyn_cast_or_null<arith::ExtSIOp>(lhs.getDefiningOp()); + dyn_cast_or_null<arith::ExtSIOp>(op.getLhs().getDefiningOp()); arith::ExtSIOp origRhsExtOp = - dyn_cast_or_null<arith::ExtSIOp>(rhs.getDefiningOp()); + dyn_cast_or_null<arith::ExtSIOp>(op.getRhs().getDefiningOp()); if (!origLhsExtOp || !origRhsExtOp) { return failure(); } @@ -113,26 +114,73 @@ public: return failure(); } - // Collapse to 1D vectors required by smmla intrinsic - auto collapsedInputType = VectorType::get( - {16}, extsiLhs.getType().cast<ShapedType>().getElementType()); - auto collapsedOutputType = - VectorType::get({4}, res.getType().cast<ShapedType>().getElementType()); - auto collapsedLhs = rewriter.createOrFold<vector::ShapeCastOp>( - extsiLhs.getLoc(), collapsedInputType, extsiLhs); - auto collapsedRhs = rewriter.createOrFold<vector::ShapeCastOp>( - extsiRhs.getLoc(), collapsedInputType, extsiRhs); - auto collapsedRes = rewriter.createOrFold<vector::ShapeCastOp>( - res.getLoc(), collapsedOutputType, res); - - // Replace the contract with a neon op - auto smmlaOp = rewriter.createOrFold<arm_neon::SmmlaOp>( - op.getLoc(), collapsedRes.getType(), collapsedRes, collapsedLhs, - collapsedRhs); - - // Reshape output back to 2D - rewriter.replaceOpWithNewOp<vector::ShapeCastOp>(op, op.getResultType(), - smmlaOp); + // Initial accumulator for the final result. This is the un-tiled result if + // tiling is done. + Value result = rewriter.create<arith::ConstantOp>( + loc, op.getResultType(), rewriter.getZeroAttr(op.getResultType())); + + SmallVector<int64_t> unrolledSize = *op.getShapeForUnroll(); + SmallVector<int64_t> smmlaShape{2, 2, 8}; + SmallVector<int64_t> loopOrder{0, 1, 2}; + for (SmallVector<int64_t> offsets : + StaticTileOffsetRange(unrolledSize, smmlaShape, loopOrder)) { + + // Helper to compute the new shape of each operand and extract the slice. + auto extractOperand = [&](Value operand, AffineMap permutationMap, + ArrayRef<int64_t> operandOffsets) { + SmallVector<int64_t> operandShape = + applyPermutationMap(permutationMap, ArrayRef<int64_t>(smmlaShape)); + SmallVector<int64_t> operandStrides(operandOffsets.size(), 1); + return rewriter.createOrFold<vector::ExtractStridedSliceOp>( + loc, operand, operandOffsets, operandShape, operandStrides); + }; + + // Extract tiled lhs, rhs, and acc + AffineMap lhsPermutationMap = op.getIndexingMapsArray()[0]; + SmallVector<int64_t> lhsOffsets = + applyPermutationMap(lhsPermutationMap, ArrayRef<int64_t>(offsets)); + Value tiledLhs = extractOperand(extsiLhs, lhsPermutationMap, lhsOffsets); + AffineMap rhsPermutationMap = op.getIndexingMapsArray()[1]; + SmallVector<int64_t> rhsOffsets = + applyPermutationMap(rhsPermutationMap, ArrayRef<int64_t>(offsets)); + Value tiledRhs = extractOperand(extsiRhs, rhsPermutationMap, rhsOffsets); + AffineMap accPermutationMap = op.getIndexingMapsArray()[2]; + SmallVector<int64_t> accOffsets = + applyPermutationMap(accPermutationMap, ArrayRef<int64_t>(offsets)); + Value tiledAcc = + extractOperand(op.getAcc(), accPermutationMap, accOffsets); + + // Collapse tiled operands to 1D vectors required by smmla intrinsic + auto collapsedInputType = VectorType::get( + tiledLhs.getType().cast<ShapedType>().getNumElements(), + tiledLhs.getType().cast<ShapedType>().getElementType()); + auto collapsedOutputType = VectorType::get( + {4}, tiledAcc.getType().cast<ShapedType>().getElementType()); + auto collapsedLhs = rewriter.createOrFold<vector::ShapeCastOp>( + tiledLhs.getLoc(), collapsedInputType, tiledLhs); + auto collapsedRhs = rewriter.createOrFold<vector::ShapeCastOp>( + tiledRhs.getLoc(), collapsedInputType, tiledRhs); + auto collapsedRes = rewriter.createOrFold<vector::ShapeCastOp>( + tiledAcc.getLoc(), collapsedOutputType, tiledAcc); + + // Insert contract op + auto smmlaOp = rewriter.createOrFold<arm_neon::SmmlaOp>( + op.getLoc(), collapsedRes.getType(), collapsedRes, collapsedLhs, + collapsedRhs); + + // Reshape output back to 2D + Value tiledRes = rewriter.createOrFold<vector::ShapeCastOp>( + smmlaOp.getLoc(), tiledAcc.getType(), smmlaOp); + + // Insert the tiled result back into the non tiled result of the + // contract op. + SmallVector<int64_t> strides( + tiledRes.getType().cast<ShapedType>().getRank(), 1); + result = rewriter.createOrFold<vector::InsertStridedSliceOp>( + loc, tiledRes, result, accOffsets, strides); + } + + rewriter.replaceOp(op, result); return success(); } }; diff --git a/mlir/test/Dialect/ArmNeon/lower-to-arm-neon.mlir b/mlir/test/Dialect/ArmNeon/lower-to-arm-neon.mlir index cba7b00ba77a..e2be87453bf6 100644 --- a/mlir/test/Dialect/ArmNeon/lower-to-arm-neon.mlir +++ b/mlir/test/Dialect/ArmNeon/lower-to-arm-neon.mlir @@ -40,3 +40,97 @@ func.func @test_lower_vector_arm_neon_without_extsi(%lhs: vector<2x8xi32>, %rhs: %res = vector.contract {indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d2)>, affine_map<(d0, d1, d2) -> (d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1)>], iterator_types = ["parallel", "parallel", "reduction"], kind = #vector.kind<add>} %lhs, %rhs, %acc : vector<2x8xi32>, vector<2x8xi32> into vector<2x2xi32> return %res : vector<2x2xi32> } + +// ----- + +// CHECK-LABEL: test_lower_vector_arm_neon_unroll +// CHECK-SAME: %[[VAL_0:.*]]: vector<4x8xi8>, %[[VAL_1:.*]]: vector<4x8xi8>, %[[VAL_2:.*]]: vector<4x4xi32> +// CHECK-DAG: %[[VAL_3:.*]] = arith.constant dense<0> : vector<4x4xi32> +// CHECK-DAG: %[[VAL_4:.*]] = vector.extract_strided_slice %[[VAL_0]] {offsets = [0, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x8xi8> to vector<2x8xi8> +// CHECK-DAG: %[[VAL_5:.*]] = vector.extract_strided_slice %[[VAL_1]] {offsets = [0, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x8xi8> to vector<2x8xi8> +// CHECK-DAG: %[[VAL_6:.*]] = vector.extract_strided_slice %[[VAL_2]] {offsets = [0, 0], sizes = [2, 2], strides = [1, 1]} : vector<4x4xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_7:.*]] = vector.shape_cast %[[VAL_4]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_8:.*]] = vector.shape_cast %[[VAL_5]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_9:.*]] = vector.shape_cast %[[VAL_6]] : vector<2x2xi32> to vector<4xi32> +// CHECK-DAG: %[[VAL_10:.*]] = arm_neon.intr.smmla %[[VAL_9]], %[[VAL_7]], %[[VAL_8]] : vector<16xi8> to vector<4xi32> +// CHECK-DAG: %[[VAL_11:.*]] = vector.shape_cast %[[VAL_10]] : vector<4xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_12:.*]] = vector.insert_strided_slice %[[VAL_11]], %[[VAL_3]] {offsets = [0, 0], strides = [1, 1]} : vector<2x2xi32> into vector<4x4xi32> +// CHECK-DAG: %[[VAL_13:.*]] = vector.extract_strided_slice %[[VAL_0]] {offsets = [0, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x8xi8> to vector<2x8xi8> +// CHECK-DAG: %[[VAL_14:.*]] = vector.extract_strided_slice %[[VAL_1]] {offsets = [2, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x8xi8> to vector<2x8xi8> +// CHECK-DAG: %[[VAL_15:.*]] = vector.extract_strided_slice %[[VAL_2]] {offsets = [0, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x4xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_16:.*]] = vector.shape_cast %[[VAL_13]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_17:.*]] = vector.shape_cast %[[VAL_14]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_18:.*]] = vector.shape_cast %[[VAL_15]] : vector<2x2xi32> to vector<4xi32> +// CHECK-DAG: %[[VAL_19:.*]] = arm_neon.intr.smmla %[[VAL_18]], %[[VAL_16]], %[[VAL_17]] : vector<16xi8> to vector<4xi32> +// CHECK-DAG: %[[VAL_20:.*]] = vector.shape_cast %[[VAL_19]] : vector<4xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_21:.*]] = vector.insert_strided_slice %[[VAL_20]], %[[VAL_12]] {offsets = [0, 2], strides = [1, 1]} : vector<2x2xi32> into vector<4x4xi32> +// CHECK-DAG: %[[VAL_22:.*]] = vector.extract_strided_slice %[[VAL_0]] {offsets = [2, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x8xi8> to vector<2x8xi8> +// CHECK-DAG: %[[VAL_23:.*]] = vector.extract_strided_slice %[[VAL_1]] {offsets = [0, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x8xi8> to vector<2x8xi8> +// CHECK-DAG: %[[VAL_24:.*]] = vector.extract_strided_slice %[[VAL_2]] {offsets = [2, 0], sizes = [2, 2], strides = [1, 1]} : vector<4x4xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_25:.*]] = vector.shape_cast %[[VAL_22]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_26:.*]] = vector.shape_cast %[[VAL_23]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_27:.*]] = vector.shape_cast %[[VAL_24]] : vector<2x2xi32> to vector<4xi32> +// CHECK-DAG: %[[VAL_28:.*]] = arm_neon.intr.smmla %[[VAL_27]], %[[VAL_25]], %[[VAL_26]] : vector<16xi8> to vector<4xi32> +// CHECK-DAG: %[[VAL_29:.*]] = vector.shape_cast %[[VAL_28]] : vector<4xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_30:.*]] = vector.insert_strided_slice %[[VAL_29]], %[[VAL_21]] {offsets = [2, 0], strides = [1, 1]} : vector<2x2xi32> into vector<4x4xi32> +// CHECK-DAG: %[[VAL_31:.*]] = vector.extract_strided_slice %[[VAL_0]] {offsets = [2, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x8xi8> to vector<2x8xi8> +// CHECK-DAG: %[[VAL_32:.*]] = vector.extract_strided_slice %[[VAL_1]] {offsets = [2, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x8xi8> to vector<2x8xi8> +// CHECK-DAG: %[[VAL_33:.*]] = vector.extract_strided_slice %[[VAL_2]] {offsets = [2, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x4xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_34:.*]] = vector.shape_cast %[[VAL_31]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_35:.*]] = vector.shape_cast %[[VAL_32]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_36:.*]] = vector.shape_cast %[[VAL_33]] : vector<2x2xi32> to vector<4xi32> +// CHECK-DAG: %[[VAL_37:.*]] = arm_neon.intr.smmla %[[VAL_36]], %[[VAL_34]], %[[VAL_35]] : vector<16xi8> to vector<4xi32> +// CHECK-DAG: %[[VAL_38:.*]] = vector.shape_cast %[[VAL_37]] : vector<4xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_39:.*]] = vector.insert_strided_slice %[[VAL_38]], %[[VAL_30]] {offsets = [2, 2], strides = [1, 1]} : vector<2x2xi32> into vector<4x4xi32> +// CHECK-DAG: return %[[VAL_39]] : vector<4x4xi32> +// CHECK-DAG: } +func.func @test_lower_vector_arm_neon_unroll(%lhs: vector<4x8xi8>, %rhs: vector<4x8xi8>, %acc : vector<4x4xi32>) -> vector<4x4xi32> { + %lhs_extsi = arith.extsi %lhs : vector<4x8xi8> to vector<4x8xi32> + %rhs_extsi = arith.extsi %rhs : vector<4x8xi8> to vector<4x8xi32> + %res = vector.contract {indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d2)>, affine_map<(d0, d1, d2) -> (d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1)>], iterator_types = ["parallel", "parallel", "reduction"], kind = #vector.kind<add>} %lhs_extsi, %rhs_extsi, %acc : vector<4x8xi32>, vector<4x8xi32> into vector<4x4xi32> + return %res : vector<4x4xi32> +} + +// ----- + +// CHECK-LABEL: func.func @test_lower_vector_arm_neon_mixed_unroll( +// CHECK-SAME: %[[VAL_0:.*]]: vector<4x8xi8>, +// CHECK-SAME: %[[VAL_1:.*]]: vector<2x8xi4>, +// CHECK-SAME: %[[VAL_2:.*]]: vector<4x2xi32>) -> vector<4x2xi32> { +// CHECK-DAG: %[[VAL_3:.*]] = arith.constant dense<0> : vector<4x2xi32> +// CHECK-DAG: %[[VAL_4:.*]] = arith.extsi %[[VAL_1]] : vector<2x8xi4> to vector<2x8xi8> +// CHECK-DAG: %[[VAL_5:.*]] = vector.extract_strided_slice %[[VAL_0]] {offsets = [0, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x8xi8> to vector<2x8xi8> +// CHECK-DAG: %[[VAL_6:.*]] = vector.extract_strided_slice %[[VAL_2]] {offsets = [0, 0], sizes = [2, 2], strides = [1, 1]} : vector<4x2xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_7:.*]] = vector.shape_cast %[[VAL_5]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_8:.*]] = vector.shape_cast %[[VAL_4]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_9:.*]] = vector.shape_cast %[[VAL_6]] : vector<2x2xi32> to vector<4xi32> +// CHECK-DAG: %[[VAL_10:.*]] = arm_neon.intr.smmla %[[VAL_9]], %[[VAL_7]], %[[VAL_8]] : vector<16xi8> to vector<4xi32> +// CHECK-DAG: %[[VAL_11:.*]] = vector.shape_cast %[[VAL_10]] : vector<4xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_12:.*]] = vector.insert_strided_slice %[[VAL_11]], %[[VAL_3]] {offsets = [0, 0], strides = [1, 1]} : vector<2x2xi32> into vector<4x2xi32> +// CHECK-DAG: %[[VAL_13:.*]] = vector.extract_strided_slice %[[VAL_0]] {offsets = [2, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x8xi8> to vector<2x8xi8> +// CHECK-DAG: %[[VAL_14:.*]] = vector.extract_strided_slice %[[VAL_2]] {offsets = [2, 0], sizes = [2, 2], strides = [1, 1]} : vector<4x2xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_15:.*]] = vector.shape_cast %[[VAL_13]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_16:.*]] = vector.shape_cast %[[VAL_4]] : vector<2x8xi8> to vector<16xi8> +// CHECK-DAG: %[[VAL_17:.*]] = vector.shape_cast %[[VAL_14]] : vector<2x2xi32> to vector<4xi32> +// CHECK-DAG: %[[VAL_18:.*]] = arm_neon.intr.smmla %[[VAL_17]], %[[VAL_15]], %[[VAL_16]] : vector<16xi8> to vector<4xi32> +// CHECK-DAG: %[[VAL_19:.*]] = vector.shape_cast %[[VAL_18]] : vector<4xi32> to vector<2x2xi32> +// CHECK-DAG: %[[VAL_20:.*]] = vector.insert_strided_slice %[[VAL_19]], %[[VAL_12]] {offsets = [2, 0], strides = [1, 1]} : vector<2x2xi32> into vector<4x2xi32> +// CHECK-DAG: return %[[VAL_20]] : vector<4x2xi32> +// CHECK-DAG: } +func.func @test_lower_vector_arm_neon_mixed_unroll(%lhs: vector<4x8xi8>, %rhs: vector<2x8xi4>, %acc : vector<4x2xi32>) -> vector<4x2xi32> { + %lhs_extsi = arith.extsi %lhs : vector<4x8xi8> to vector<4x8xi32> + %rhs_extsi = arith.extsi %rhs : vector<2x8xi4> to vector<2x8xi32> + %res = vector.contract {indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d2)>, affine_map<(d0, d1, d2) -> (d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1)>], iterator_types = ["parallel", "parallel", "reduction"], kind = #vector.kind<add>} %lhs_extsi, %rhs_extsi, %acc : vector<4x8xi32>, vector<2x8xi32> into vector<4x2xi32> + return %res : vector<4x2xi32> +} + +// ----- + +// CHECK-LABEL: func.func @test_lower_vector_arm_neon_unroll_incompatible_shape( +// CHECK-DAG: %[[result:.*]] = vector.contract +func.func @test_lower_vector_arm_neon_unroll_incompatible_shape(%lhs: vector<4x12xi8>, %rhs: vector<4x12xi8>, %acc : vector<4x4xi32>) -> vector<4x4xi32> { + %lhs_extsi = arith.extsi %lhs : vector<4x12xi8> to vector<4x12xi32> + %rhs_extsi = arith.extsi %rhs : vector<4x12xi8> to vector<4x12xi32> + %res = vector.contract {indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d2)>, affine_map<(d0, d1, d2) -> (d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1)>], iterator_types = ["parallel", "parallel", "reduction"], kind = #vector.kind<add>} %lhs_extsi, %rhs_extsi, %acc : vector<4x12xi32>, vector<4x12xi32> into vector<4x4xi32> + return %res : vector<4x4xi32> +} -- GitLab From a7eaae4ec686ddfb8f91868fc8d053b2163f7ec7 Mon Sep 17 00:00:00 2001 From: harishch4 <harishcse44@gmail.com> Date: Tue, 19 Mar 2024 22:46:57 +0530 Subject: [PATCH 113/307] =?UTF-8?q?[Flang]=20Fix=20to=20the=20module=20pro?= =?UTF-8?q?cedure=20interface=20block=20ignoring=20implicit=E2=80=A6=20(#8?= =?UTF-8?q?5735)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … of host scoping unit. Fix as proposed by @thtsikas [here ](https://github.com/llvm/llvm-project/commit/11d07d9ef618497b825badee8b4f06a48575606b#commitcomment-139798026). --- flang/lib/Semantics/resolve-names.cpp | 2 +- flang/test/Semantics/separate-mp05.f90 | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index b13674573fe0..f89323f3e54a 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -4432,7 +4432,7 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name, CHECK(context().HasError(genericSymbol)); } } - set_inheritFromParent(false); + set_inheritFromParent(hasModulePrefix); } if (Symbol * found{FindSymbol(name)}; found && found->has<HostAssocDetails>()) { diff --git a/flang/test/Semantics/separate-mp05.f90 b/flang/test/Semantics/separate-mp05.f90 index 5b7e2523a228..ad002142fd28 100644 --- a/flang/test/Semantics/separate-mp05.f90 +++ b/flang/test/Semantics/separate-mp05.f90 @@ -7,8 +7,10 @@ module m !DEF: /m/smp MODULE, PUBLIC, PURE (Function) Subprogram REAL(4) !DEF: /m/smp/f EXTERNAL, PURE (Function) Subprogram REAL(4) !DEF: /m/smp/x INTENT(IN) ObjectEntity REAL(4) - !DEF: /m/smp/res (Implicit) ObjectEntity REAL(4) + !DEF: /m/smp/res ObjectEntity REAL(4) pure module function smp(f, x) result(res) + !REF: /m/smp/res + real res interface !REF: /m/smp/f !DEF: /m/smp/f/x INTENT(IN) ObjectEntity REAL(4) @@ -32,7 +34,7 @@ submodule (m)sm contains !DEF: /m/sm/smp MODULE, PUBLIC, PURE (Function) Subprogram REAL(4) module procedure smp - !DEF: /m/sm/smp/res (Implicit) ObjectEntity REAL(4) + !DEF: /m/sm/smp/res ObjectEntity REAL(4) !DEF: /m/sm/smp/f EXTERNAL, PURE (Function) Subprogram REAL(4) !DEF: /m/sm/smp/x INTENT(IN) ObjectEntity REAL(4) res = f(x) -- GitLab From c7de4a39d5673b91189395f85ca6f71b1eeb115c Mon Sep 17 00:00:00 2001 From: Brad Smith <brad@comstyle.com> Date: Tue, 19 Mar 2024 13:29:19 -0400 Subject: [PATCH 114/307] [OpenMP] Enable the affinity tests on FreeBSD, NetBSD and DragonFly (#85500) FreeBSD, NetBSD and DragonFly also have affinity support. So enable the tests there as well. --- openmp/runtime/test/lit.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmp/runtime/test/lit.cfg b/openmp/runtime/test/lit.cfg index 4a457f4cc41f..a3456063c10f 100644 --- a/openmp/runtime/test/lit.cfg +++ b/openmp/runtime/test/lit.cfg @@ -129,7 +129,7 @@ if config.operating_system == 'NetBSD': if config.operating_system == 'Darwin': config.available_features.add("darwin") -if config.operating_system in ['Linux', 'Windows']: +if config.operating_system in ['Windows', 'Linux', 'FreeBSD', 'NetBSD', 'DragonFly']: config.available_features.add('affinity') if config.operating_system in ['Linux']: -- GitLab From b9a41b9e9b1441a7b0ca0fb95b9184f73bbfd4b5 Mon Sep 17 00:00:00 2001 From: Dominik Adamski <dominik.adamski@amd.com> Date: Tue, 19 Mar 2024 18:29:35 +0100 Subject: [PATCH 115/307] [NFC][OpenMP] Add test checking clang offload chunking policy (#83261) Verify how clang handles `dist_schedule(static, block_chunk)` and `schedule(static, thread_chunk)` clauses for OpenMP offload loop workshare pragmas. --- .../test/offloading/workshare_chunk.c | 252 ++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 openmp/libomptarget/test/offloading/workshare_chunk.c diff --git a/openmp/libomptarget/test/offloading/workshare_chunk.c b/openmp/libomptarget/test/offloading/workshare_chunk.c new file mode 100644 index 000000000000..c2248547605b --- /dev/null +++ b/openmp/libomptarget/test/offloading/workshare_chunk.c @@ -0,0 +1,252 @@ +// RUN: %libomptarget-compile-run-and-check-generic +// RUN: %libomptarget-compileopt-run-and-check-generic + +// UNSUPPORTED: aarch64-unknown-linux-gnu +// UNSUPPORTED: aarch64-unknown-linux-gnu-LTO +// UNSUPPORTED: x86_64-pc-linux-gnu +// UNSUPPORTED: x86_64-pc-linux-gnu-LTO + +// clang-format off + +#include <omp.h> +#include <stdio.h> + +#define N 100 +#define BLOCK_SHIFT 8 + +void print(int *A, int size) { + for (int i = 0; i < size; ++i) { + printf("B%dT%d ", A[i] >> BLOCK_SHIFT, A[i] % (1 << BLOCK_SHIFT)); + } + printf("\n"); +} + +int main() { + int A[N]; + +#pragma omp target parallel for map(from:A) num_threads(10) schedule(static, 2) + for (int i = 0; i < N; ++i) { + A[i] = (omp_get_team_num() << BLOCK_SHIFT) + omp_get_thread_num(); + } + printf("omp target parallel for thread chunk size %d\n", 2); + print(A, N); + +#pragma omp target teams distribute map(from:A) num_teams(10) \ + dist_schedule(static, 2) + for (int i = 0; i < N; ++i) { + A[i] = (omp_get_team_num() << BLOCK_SHIFT) + omp_get_thread_num(); + } + printf("omp target teams distribute block chunk size %d\n", 2); + print(A, N); + +#pragma omp target teams distribute parallel for map(from:A) \ + num_teams(10) dist_schedule(static, 2) + for (int i = 0; i < N; ++i) { + A[i] = (omp_get_team_num() << BLOCK_SHIFT) + omp_get_thread_num(); + } + printf("omp target teams distribute parallel for block chunk size %d ", 2); + printf("thread chunk size default\n"); + print(A, N); + +#pragma omp target teams distribute parallel for map(from:A) \ + num_teams(10) dist_schedule(static, 2) schedule(static, 3) + for (int i = 0; i < N; ++i) { + A[i] = (omp_get_team_num() << BLOCK_SHIFT) + omp_get_thread_num(); + } + printf("omp target teams distribute parallel for block chunk size %d ", 2); + printf("thread chunk size %d\n", 3); + print(A, N); + +#pragma omp target teams distribute parallel for map(from:A) \ + num_teams(10) dist_schedule(static, 3) schedule(static, 2) + for (int i = 0; i < N; ++i) { + A[i] = (omp_get_team_num() << BLOCK_SHIFT) + omp_get_thread_num(); + } + printf("omp target teams distribute parallel for block chunk size %d ", 3); + printf("thread chunk size %d\n", 2); + print(A, N); + +#pragma omp target teams distribute parallel for map(from:A) \ + num_teams(10) dist_schedule(static, 5) schedule(static, 2) + for (int i = 0; i < N; ++i) { + A[i] = (omp_get_team_num() << BLOCK_SHIFT) + omp_get_thread_num(); + } + printf("omp target teams distribute parallel for block chunk size %d ", 5); + printf("thread chunk size %d\n", 2); + print(A, N); + +#pragma omp target teams distribute parallel for map(from:A) num_teams(10) \ + dist_schedule(static, 49) schedule(static, 2) + for (int i = 0; i < N; ++i) { + A[i] = (omp_get_team_num() << BLOCK_SHIFT) + omp_get_thread_num(); + } + printf("omp target teams distribute parallel for block chunk size %d ", 49); + printf("thread chunk size %d\n", 2); + print(A, N); + +#pragma omp target teams distribute parallel for map(from:A) \ + num_teams(10) num_threads(10) dist_schedule(static, 29) + for (int i = 0; i < N; ++i) { + A[i] = (omp_get_team_num() << BLOCK_SHIFT) + omp_get_thread_num(); + } + printf("omp target teams distribute parallel for block chunk size %d ", 29); + printf("thread chunk size default\n"); + print(A, N); + +#pragma omp target teams distribute parallel for map(from:A) \ + num_teams(10) num_threads(10) dist_schedule(static, 101) + for (int i = 0; i < N; ++i) { + A[i] = (omp_get_team_num() << BLOCK_SHIFT) + omp_get_thread_num(); + } + printf("omp target teams distribute parallel for block chunk size %d ", 101); + printf("thread chunk size default\n"); + print(A, N); + +#pragma omp target teams distribute parallel for map(from:A) \ + num_teams(9) num_threads(10) schedule(static, 101) + for (int i = 0; i < N; ++i) { + A[i] = (omp_get_team_num() << BLOCK_SHIFT) + omp_get_thread_num(); + } + printf("omp target teams distribute parallel for default block chunk size "); + printf("thread chunk size %d\n", 101); + print(A, N); + return 0; +} +//CHECK: omp target parallel for thread chunk size 2 + +//CHECK-NEXT: B0T0 B0T0 B0T1 B0T1 B0T2 B0T2 B0T3 B0T3 B0T4 B0T4 +//CHECK-SAME: B0T5 B0T5 B0T6 B0T6 B0T7 B0T7 B0T8 B0T8 B0T9 B0T9 +//CHECK-SAME: B0T0 B0T0 B0T1 B0T1 B0T2 B0T2 B0T3 B0T3 B0T4 B0T4 +//CHECK-SAME: B0T5 B0T5 B0T6 B0T6 B0T7 B0T7 B0T8 B0T8 B0T9 B0T9 +//CHECK-SAME: B0T0 B0T0 B0T1 B0T1 B0T2 B0T2 B0T3 B0T3 B0T4 B0T4 +//CHECK-SAME: B0T5 B0T5 B0T6 B0T6 B0T7 B0T7 B0T8 B0T8 B0T9 B0T9 +//CHECK-SAME: B0T0 B0T0 B0T1 B0T1 B0T2 B0T2 B0T3 B0T3 B0T4 B0T4 +//CHECK-SAME: B0T5 B0T5 B0T6 B0T6 B0T7 B0T7 B0T8 B0T8 B0T9 B0T9 +//CHECK-SAME: B0T0 B0T0 B0T1 B0T1 B0T2 B0T2 B0T3 B0T3 B0T4 B0T4 +//CHECK-SAME: B0T5 B0T5 B0T6 B0T6 B0T7 B0T7 B0T8 B0T8 B0T9 B0T9 + +//CHECK: omp target teams distribute block chunk size 2 + +//CHECK-NEXT: B0T0 B0T0 B1T0 B1T0 B2T0 B2T0 B3T0 B3T0 B4T0 B4T0 +//CHECK-SAME: B5T0 B5T0 B6T0 B6T0 B7T0 B7T0 B8T0 B8T0 B9T0 B9T0 +//CHECK-SAME: B0T0 B0T0 B1T0 B1T0 B2T0 B2T0 B3T0 B3T0 B4T0 B4T0 +//CHECK-SAME: B5T0 B5T0 B6T0 B6T0 B7T0 B7T0 B8T0 B8T0 B9T0 B9T0 +//CHECK-SAME: B0T0 B0T0 B1T0 B1T0 B2T0 B2T0 B3T0 B3T0 B4T0 B4T0 +//CHECK-SAME: B5T0 B5T0 B6T0 B6T0 B7T0 B7T0 B8T0 B8T0 B9T0 B9T0 +//CHECK-SAME: B0T0 B0T0 B1T0 B1T0 B2T0 B2T0 B3T0 B3T0 B4T0 B4T0 +//CHECK-SAME: B5T0 B5T0 B6T0 B6T0 B7T0 B7T0 B8T0 B8T0 B9T0 B9T0 +//CHECK-SAME: B0T0 B0T0 B1T0 B1T0 B2T0 B2T0 B3T0 B3T0 B4T0 B4T0 +//CHECK-SAME: B5T0 B5T0 B6T0 B6T0 B7T0 B7T0 B8T0 B8T0 B9T0 B9T0 + +//CHECK: omp target teams distribute parallel for +//CHECK-SAME: block chunk size 2 thread chunk size default + +//CHECK-NEXT: B0T0 B0T1 B1T0 B1T1 B2T0 B2T1 B3T0 B3T1 B4T0 B4T1 +//CHECK-SAME: B5T0 B5T1 B6T0 B6T1 B7T0 B7T1 B8T0 B8T1 B9T0 B9T1 +//CHECK-SAME: B0T0 B0T1 B1T0 B1T1 B2T0 B2T1 B3T0 B3T1 B4T0 B4T1 +//CHECK-SAME: B5T0 B5T1 B6T0 B6T1 B7T0 B7T1 B8T0 B8T1 B9T0 B9T1 +//CHECK-SAME: B0T0 B0T1 B1T0 B1T1 B2T0 B2T1 B3T0 B3T1 B4T0 B4T1 +//CHECK-SAME: B5T0 B5T1 B6T0 B6T1 B7T0 B7T1 B8T0 B8T1 B9T0 B9T1 + +//CHECK: omp target teams distribute parallel for +//CHECK-SAME block chunk size 2 thread chunk size 3 + +//CHECK-NEXT: B0T0 B0T0 B1T0 B1T0 B2T0 B2T0 B3T0 B3T0 B4T0 B4T0 +//CHECK-SAME: B5T0 B5T0 B6T0 B6T0 B7T0 B7T0 B8T0 B8T0 B9T0 B9T0 +//CHECK-SAME: B0T0 B0T0 B1T0 B1T0 B2T0 B2T0 B3T0 B3T0 B4T0 B4T0 +//CHECK-SAME: B5T0 B5T0 B6T0 B6T0 B7T0 B7T0 B8T0 B8T0 B9T0 B9T0 +//CHECK-SAME: B0T0 B0T0 B1T0 B1T0 B2T0 B2T0 B3T0 B3T0 B4T0 B4T0 +//CHECK-SAME: B5T0 B5T0 B6T0 B6T0 B7T0 B7T0 B8T0 B8T0 B9T0 B9T0 +//CHECK-SAME: B0T0 B0T0 B1T0 B1T0 B2T0 B2T0 B3T0 B3T0 B4T0 B4T0 +//CHECK-SAME: B5T0 B5T0 B6T0 B6T0 B7T0 B7T0 B8T0 B8T0 B9T0 B9T0 +//CHECK-SAME: B0T0 B0T0 B1T0 B1T0 B2T0 B2T0 B3T0 B3T0 B4T0 B4T0 +//CHECK-SAME: B5T0 B5T0 B6T0 B6T0 B7T0 B7T0 B8T0 B8T0 B9T0 B9T0 + +//CHECK: omp target teams distribute parallel for +//CHECK-SAME: block chunk size 3 thread chunk size 2 + +//CHECK-NEXT: B0T0 B0T0 B0T1 B1T0 B1T0 B1T1 B2T0 B2T0 B2T1 +//CHECK-SAME: B3T0 B3T0 B3T1 B4T0 B4T0 B4T1 +//CHECK-SAME: B5T0 B5T0 B5T1 B6T0 B6T0 B6T1 B7T0 B7T0 B7T1 +//CHECK-SAME: B8T0 B8T0 B8T1 B9T0 B9T0 B9T1 +//CHECK-SAME: B0T0 B0T0 B0T1 B1T0 B1T0 B1T1 B2T0 B2T0 B2T1 +//CHECK-SAME: B3T0 B3T0 B3T1 B4T0 B4T0 B4T1 +//CHECK-SAME: B5T0 B5T0 B5T1 B6T0 B6T0 B6T1 B7T0 B7T0 B7T1 +//CHECK-SAME: B8T0 B8T0 B8T1 B9T0 B9T0 B9T1 +//CHECK-SAME: B0T0 B0T0 B0T1 B1T0 B1T0 B1T1 B2T0 B2T0 B2T1 +//CHECK-SAME: B3T0 B3T0 B3T1 B4T0 B4T0 B4T1 +//CHECK-SAME: B5T0 B5T0 B5T1 B6T0 B6T0 B6T1 B7T0 B7T0 B7T1 +//CHECK-SAME: B8T0 B8T0 B8T1 B9T0 B9T0 B9T1 +//CHECK-SAME: B0T0 B0T0 B0T1 B1T0 B1T0 B1T1 B2T0 B2T0 B2T1 B3T0 + +//CHECK: omp target teams distribute parallel for +//CHECK-SAME: block chunk size 5 thread chunk size 2 + +//CHECK-NEXT: B0T0 B0T0 B0T1 B0T1 B0T2 B1T0 B1T0 B1T1 B1T1 B1T2 +//CHECK-SAME: B2T0 B2T0 B2T1 B2T1 B2T2 B3T0 B3T0 B3T1 B3T1 B3T2 +//CHECK-SAME: B4T0 B4T0 B4T1 B4T1 B4T2 B5T0 B5T0 B5T1 B5T1 B5T2 +//CHECK-SAME: B6T0 B6T0 B6T1 B6T1 B6T2 B7T0 B7T0 B7T1 B7T1 B7T2 +//CHECK-SAME: B8T0 B8T0 B8T1 B8T1 B8T2 B9T0 B9T0 B9T1 B9T1 B9T2 +//CHECK-SAME: B0T0 B0T0 B0T1 B0T1 B0T2 B1T0 B1T0 B1T1 B1T1 B1T2 +//CHECK-SAME: B2T0 B2T0 B2T1 B2T1 B2T2 B3T0 B3T0 B3T1 B3T1 B3T2 +//CHECK-SAME: B4T0 B4T0 B4T1 B4T1 B4T2 B5T0 B5T0 B5T1 B5T1 B5T2 +//CHECK-SAME: B6T0 B6T0 B6T1 B6T1 B6T2 B7T0 B7T0 B7T1 B7T1 B7T2 +//CHECK-SAME: B8T0 B8T0 B8T1 B8T1 B8T2 B9T0 B9T0 B9T1 B9T1 B9T2 + +//CHECK: omp target teams distribute parallel for +//CHECK-SAME: block chunk size 49 thread chunk size 2 + +//CHECK-NEXT: B0T0 B0T0 B0T1 B0T1 B0T2 B0T2 B0T3 B0T3 B0T4 B0T4 B0T5 B0T5 +//CHECK-SAME: B0T6 B0T6 B0T7 B0T7 B0T8 B0T8 B0T9 B0T9 B0T10 B0T10 B0T11 B0T11 +//CHECK-SAME: B0T12 B0T12 B0T13 B0T13 B0T14 B0T14 B0T15 B0T15 B0T16 B0T16 +//CHECK-SAME: B0T17 B0T17 B0T18 B0T18 B0T19 B0T19 B0T20 B0T20 B0T21 B0T21 +//CHECK-SAME: B0T22 B0T22 B0T23 B0T23 B0T24 +//CHECK-SAME: B1T0 B1T0 B1T1 B1T1 B1T2 B1T2 B1T3 B1T3 B1T4 B1T4 B1T5 B1T5 +//CHECK-SAME: B1T6 B1T6 B1T7 B1T7 B1T8 B1T8 B1T9 B1T9 B1T10 B1T10 B1T11 B1T11 +//CHECK-SAME: B1T12 B1T12 B1T13 B1T13 B1T14 B1T14 B1T15 B1T15 B1T16 B1T16 +//CHECK-SAME: B1T17 B1T17 B1T18 B1T18 B1T19 B1T19 B1T20 B1T20 B1T21 B1T21 +//CHECK-SAME: B1T22 B1T22 B1T23 B1T23 B1T24 +//CHECK-SAME: B2T0 B2T0 + +//CHECK: omp target teams distribute parallel for +//CHECK-SAME: block chunk size 29 thread chunk size default + +//CHECK-NEXT: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 +//CHECK-SAME: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 +//CHECK-SAME: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 +//CHECK-SAME: B1T0 B1T1 B1T2 B1T3 B1T4 B1T5 B1T6 B1T7 B1T8 B1T9 +//CHECK-SAME: B1T0 B1T1 B1T2 B1T3 B1T4 B1T5 B1T6 B1T7 B1T8 B1T9 +//CHECK-SAME: B1T0 B1T1 B1T2 B1T3 B1T4 B1T5 B1T6 B1T7 B1T8 +//CHECK-SAME: B2T0 B2T1 B2T2 B2T3 B2T4 B2T5 B2T6 B2T7 B2T8 B2T9 +//CHECK-SAME: B2T0 B2T1 B2T2 B2T3 B2T4 B2T5 B2T6 B2T7 B2T8 B2T9 +//CHECK-SAME: B2T0 B2T1 B2T2 B2T3 B2T4 B2T5 B2T6 B2T7 B2T8 +//CHECK-SAME: B3T0 B3T1 B3T2 B3T3 B3T4 B3T5 B3T6 B3T7 B3T8 B3T9 +//CHECK-SAME: B3T0 B3T1 B3T2 + +//CHECK: omp target teams distribute parallel for +//CHECK-SAME: block chunk size 101 thread chunk size default + +//CHECK-NEXT: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 +//CHECK-SAME: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 +//CHECK-SAME: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 +//CHECK-SAME: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 +//CHECK-SAME: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 +//CHECK-SAME: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 +//CHECK-SAME: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 +//CHECK-SAME: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 +//CHECK-SAME: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 +//CHECK-SAME: B0T0 B0T1 B0T2 B0T3 B0T4 B0T5 B0T6 B0T7 B0T8 B0T9 + +//CHECK: omp target teams distribute parallel for +//CHECK-SAME: default block chunk size thread chunk size 101 + +//CHECK-NEXT: B0T0 B0T0 B0T0 B0T0 B0T0 B0T0 B0T0 B0T0 B0T0 B0T0 +//CHECK-SAME: B1T0 B1T0 B1T0 B1T0 B1T0 B1T0 B1T0 B1T0 B1T0 B1T0 +//CHECK-SAME: B2T0 B2T0 B2T0 B2T0 B2T0 B2T0 B2T0 B2T0 B2T0 B2T0 +//CHECK-SAME: B3T0 B3T0 B3T0 B3T0 B3T0 B3T0 B3T0 B3T0 B3T0 B3T0 +//CHECK-SAME: B4T0 B4T0 B4T0 B4T0 B4T0 B4T0 B4T0 B4T0 B4T0 B4T0 +//CHECK-SAME: B5T0 B5T0 B5T0 B5T0 B5T0 B5T0 B5T0 B5T0 B5T0 B5T0 +//CHECK-SAME: B6T0 B6T0 B6T0 B6T0 B6T0 B6T0 B6T0 B6T0 B6T0 B6T0 +//CHECK-SAME: B7T0 B7T0 B7T0 B7T0 B7T0 B7T0 B7T0 B7T0 B7T0 B7T0 +//CHECK-SAME: B8T0 B8T0 B8T0 B8T0 B8T0 B8T0 B8T0 B8T0 B8T0 B8T0 +//CHECK-SAME: B0T0 B0T0 B0T0 B0T0 B0T0 B0T0 B0T0 B0T0 B0T0 B0T0 -- GitLab From 5f38436d34360d17b58f643650f3605bb9609a34 Mon Sep 17 00:00:00 2001 From: Fangrui Song <i@maskray.me> Date: Tue, 19 Mar 2024 10:37:51 -0700 Subject: [PATCH 116/307] [Driver] -fsanitize=undefined: don't expand to signed-integer-overflow if -fwrapv (#85501) Linux kernel uses -fwrapv to change signed integer overflows from undefined behaviors to defined behaviors. However, the security folks still want -fsanitize=signed-integer-overflow diagnostics. Their intention can be expressed with -fwrapv -fsanitize=signed-integer-overflow (#80089). This mode by default reports recoverable errors while still making signed integer overflows defined (most UBSan checks are recoverable by default: you get errors in stderr, but the program is not halted). -fsanitize=undefined -fwrapv users likely want to suppress signed-integer-overflow, unless signed-integer-overflow is explicitly enabled. Implement this suppression. --- clang/lib/Driver/SanitizerArgs.cpp | 8 ++++++ .../fsanitize-signed-integer-overflow.c | 28 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 clang/test/Driver/fsanitize-signed-integer-overflow.c diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 56d497eb4c32..8bfe9f02a091 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -487,6 +487,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, Add &= ~NotAllowedWithExecuteOnly; if (CfiCrossDso) Add &= ~SanitizerKind::CFIMFCall; + // -fsanitize=undefined does not expand to signed-integer-overflow in + // -fwrapv (implied by -fno-strict-overflow) mode. + if (Add & SanitizerKind::UndefinedGroup) { + bool S = Args.hasFlagNoClaim(options::OPT_fno_strict_overflow, + options::OPT_fstrict_overflow, false); + if (Args.hasFlagNoClaim(options::OPT_fwrapv, options::OPT_fno_wrapv, S)) + Add &= ~SanitizerKind::SignedIntegerOverflow; + } Add &= Supported; if (Add & SanitizerKind::Fuzzer) diff --git a/clang/test/Driver/fsanitize-signed-integer-overflow.c b/clang/test/Driver/fsanitize-signed-integer-overflow.c new file mode 100644 index 000000000000..4a9345493b6a --- /dev/null +++ b/clang/test/Driver/fsanitize-signed-integer-overflow.c @@ -0,0 +1,28 @@ +/// When -fwrapv (implied by -fno-strict-overflow) is enabled, +/// -fsanitize=undefined does not expand to signed-integer-overflow. +/// -fsanitize=signed-integer-overflow is unaffected by -fwrapv. + +// RUN: %clang -### --target=x86_64-linux -fwrapv -fsanitize=signed-integer-overflow %s 2>&1 | FileCheck %s +// CHECK: -fsanitize=signed-integer-overflow +// CHECK: -fsanitize-recover=signed-integer-overflow + +// RUN: %clang -### --target=x86_64-linux -fno-strict-overflow -fsanitize=undefined %s 2>&1 | FileCheck %s --check-prefix=EXCLUDE +// RUN: %clang -### --target=x86_64-linux -fstrict-overflow -fwrapv -fsanitize=undefined %s 2>&1 | FileCheck %s --check-prefix=EXCLUDE +// EXCLUDE: -fsanitize=alignment,array-bounds, +// EXCLUDE-NOT: signed-integer-overflow, +// EXCLUDE: -fsanitize-recover=alignment,array-bounds, +// EXCLUDE-SAME: signed-integer-overflow + +// RUN: %clang -### --target=x86_64-linux -fwrapv -fsanitize=undefined -fsanitize=signed-integer-overflow %s 2>&1 | FileCheck %s --check-prefix=INCLUDE +// RUN: %clang -### --target=x86_64-linux -fno-strict-overflow -fno-sanitize=signed-integer-overflow -fsanitize=undefined -fsanitize=signed-integer-overflow %s 2>&1 | FileCheck %s --check-prefix=INCLUDE +// INCLUDE: -fsanitize=alignment,array-bounds, +// INCLUDE-SAME: signed-integer-overflow +// INCLUDE: -fsanitize-recover=alignment,array-bounds, +// INCLUDE-SAME: signed-integer-overflow + +/// -fsanitize-trap=undefined expands to signed-integer-overflow regardless of -fwrapv. +// RUN: %clang -### --target=x86_64-linux -fwrapv -fsanitize=undefined -fsanitize=signed-integer-overflow -fsanitize-trap=undefined %s 2>&1 | FileCheck %s --check-prefix=INCLUDE-TRAP +// INCLUDE-TRAP: -fsanitize=alignment,array-bounds, +// INCLUDE-TRAP-SAME: signed-integer-overflow +// INCLUDE-TRAP: -fsanitize-trap=alignment,array-bounds, +// INCLUDE-TRAP-SAME: signed-integer-overflow -- GitLab From 4bade55cc65db8b7f977dba4f13bf335e93317a8 Mon Sep 17 00:00:00 2001 From: Fangrui Song <i@maskray.me> Date: Tue, 19 Mar 2024 10:44:36 -0700 Subject: [PATCH 117/307] [test] Fix aarch64-tlsdesc-zrel.s --- lld/test/ELF/aarch64-tlsdesc-zrel.s | 1 + 1 file changed, 1 insertion(+) diff --git a/lld/test/ELF/aarch64-tlsdesc-zrel.s b/lld/test/ELF/aarch64-tlsdesc-zrel.s index e2e560bd13f5..83e6894ddb3b 100644 --- a/lld/test/ELF/aarch64-tlsdesc-zrel.s +++ b/lld/test/ELF/aarch64-tlsdesc-zrel.s @@ -29,6 +29,7 @@ // REL-NEXT: 0x[[#ADDR+16]] R_AARCH64_TLSDESC -{{$}} // REL-NEXT: } // REL-NEXT: ] +// REL-EMPTY: // REL-NEXT: Hex dump of section '.got': // REL-NEXT: 0x000[[#ADDR]] 00000000 00000000 00000000 00000000 // REL-NEXT: 0x000[[#ADDR+16]] 00000000 00000000 04000000 00000000 -- GitLab From 3176c157190c80b4279dec86c4b9b84472d8ccac Mon Sep 17 00:00:00 2001 From: Andres Villegas <andresvi@google.com> Date: Tue, 19 Mar 2024 10:58:31 -0700 Subject: [PATCH 118/307] Revert "[dsymutil] Remove support for obfuscated bitcode" (#85826) Reverts llvm/llvm-project#85713 Since it is breaking Linux x64 builds. --- llvm/docs/CommandGuide/dsymutil.rst | 4 + .../llvm/CodeGen/NonRelocatableStringpool.h | 6 +- .../llvm/DWARFLinker/Classic/DWARFStreamer.h | 8 +- .../llvm/DWARFLinker/DWARFLinkerBase.h | 1 + .../llvm/DWARFLinker/Parallel/DWARFLinker.h | 3 +- llvm/lib/CodeGen/NonRelocatableStringpool.cpp | 5 + llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 4 +- .../lib/DWARFLinker/Classic/DWARFStreamer.cpp | 12 +- llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp | 6 +- .../Parallel/DWARFLinkerGlobalData.h | 15 ++ .../DWARFLinker/Parallel/DWARFLinkerImpl.cpp | 4 +- .../DWARFLinker/Parallel/DWARFLinkerImpl.h | 3 +- .../lib/DWARFLinker/Parallel/OutputSections.h | 2 +- .../StringEntryToDwarfStringPoolEntryMap.h | 2 +- llvm/test/tools/dsymutil/ARM/obfuscated.test | 200 ++++++++++++++++++ .../tools/dsymutil/Inputs/obfuscated.2.arm64 | Bin 0 -> 10339 bytes .../tools/dsymutil/Inputs/obfuscated.2.map | 22 ++ .../tools/dsymutil/Inputs/obfuscated.arm64 | Bin 0 -> 10434 bytes .../test/tools/dsymutil/Inputs/obfuscated.map | 17 ++ llvm/test/tools/dsymutil/cmdline.test | 1 + llvm/tools/dsymutil/CMakeLists.txt | 1 + llvm/tools/dsymutil/DwarfLinkerForBinary.cpp | 14 +- llvm/tools/dsymutil/LinkUtils.h | 5 + llvm/tools/dsymutil/MachOUtils.cpp | 7 +- llvm/tools/dsymutil/MachOUtils.h | 4 +- llvm/tools/dsymutil/Options.td | 6 + llvm/tools/dsymutil/SymbolMap.cpp | 157 ++++++++++++++ llvm/tools/dsymutil/SymbolMap.h | 53 +++++ llvm/tools/dsymutil/dsymutil.cpp | 15 +- llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp | 6 +- 30 files changed, 555 insertions(+), 28 deletions(-) create mode 100644 llvm/test/tools/dsymutil/ARM/obfuscated.test create mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.2.arm64 create mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.2.map create mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.arm64 create mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.map create mode 100644 llvm/tools/dsymutil/SymbolMap.cpp create mode 100644 llvm/tools/dsymutil/SymbolMap.h diff --git a/llvm/docs/CommandGuide/dsymutil.rst b/llvm/docs/CommandGuide/dsymutil.rst index e3f2f33224b0..af9d7f16b361 100644 --- a/llvm/docs/CommandGuide/dsymutil.rst +++ b/llvm/docs/CommandGuide/dsymutil.rst @@ -140,6 +140,10 @@ OPTIONS (in bytes) to the linked dSYM. The table is sorted by the output size listing the object files with the largest contribution first. +.. option:: --symbol-map <bcsymbolmap> + + Update the existing dSYMs inplace using symbol map specified. + .. option:: -s, --symtab Dumps the symbol table found in *executable* or object file(s) and exits. diff --git a/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h b/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h index 4b8eed7bdb1b..3dc0731f5a04 100644 --- a/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h +++ b/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h @@ -27,7 +27,10 @@ public: /// order. using MapTy = StringMap<DwarfStringPoolEntry, BumpPtrAllocator>; - NonRelocatableStringpool(bool PutEmptyString = false) { + NonRelocatableStringpool( + std::function<StringRef(StringRef Input)> Translator = nullptr, + bool PutEmptyString = false) + : Translator(Translator) { if (PutEmptyString) getEntry(""); } @@ -56,6 +59,7 @@ private: MapTy Strings; uint64_t CurrentEndOffset = 0; unsigned NumEntries = 0; + std::function<StringRef(StringRef Input)> Translator; }; /// Helper for making strong types. diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h index e7a1a3cd838c..bebdfd5e6025 100644 --- a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h +++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h @@ -45,13 +45,16 @@ class DwarfStreamer : public DwarfEmitter { public: DwarfStreamer(DWARFLinkerBase::OutputFileType OutFileType, raw_pwrite_stream &OutFile, + DWARFLinkerBase::TranslatorFuncTy Translator, DWARFLinkerBase::MessageHandlerTy Warning) - : OutFile(OutFile), OutFileType(OutFileType), WarningHandler(Warning) {} + : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator), + WarningHandler(Warning) {} virtual ~DwarfStreamer() = default; static Expected<std::unique_ptr<DwarfStreamer>> createStreamer( const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType, - raw_pwrite_stream &OutFile, DWARFLinkerBase::MessageHandlerTy Warning); + raw_pwrite_stream &OutFile, DWARFLinkerBase::TranslatorFuncTy Translator, + DWARFLinkerBase::MessageHandlerTy Warning); Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName); @@ -292,6 +295,7 @@ private: /// The output file we stream the linked Dwarf to. raw_pwrite_stream &OutFile; DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object; + std::function<StringRef(StringRef Input)> Translator; uint64_t RangesSectionSize = 0; uint64_t RngListsSectionSize = 0; diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h index 70b25cf02df7..5c811b668f0a 100644 --- a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h +++ b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h @@ -82,6 +82,7 @@ public: std::function<void(const DWARFFile &File, llvm::StringRef Output)>; using ObjectPrefixMapTy = std::map<std::string, std::string>; using CompileUnitHandlerTy = function_ref<void(const DWARFUnit &Unit)>; + using TranslatorFuncTy = std::function<StringRef(StringRef)>; using SwiftInterfacesMapTy = std::map<std::string, std::string>; /// Type of output file. enum class OutputFileType : uint8_t { diff --git a/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h index 8acc046d0724..5312712a4a5b 100644 --- a/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h @@ -123,7 +123,8 @@ public: /// Creates dwarf linker instance. static std::unique_ptr<DWARFLinker> - createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler); + createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler, + TranslatorFuncTy StringsTranslator = nullptr); /// Set output DWARF handler. Result of linking DWARF is set of sections /// containing final debug info. DWARFLinkerBase::link() pass generated diff --git a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp index 26857c6a4088..e8391afb8e3f 100644 --- a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp +++ b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp @@ -12,6 +12,8 @@ namespace llvm { DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) { + if (Translator) + S = Translator(S); auto I = Strings.insert({S, DwarfStringPoolEntry()}); auto &Entry = I.first->second; if (I.second || !Entry.isIndexed()) { @@ -26,6 +28,9 @@ DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) { StringRef NonRelocatableStringpool::internString(StringRef S) { DwarfStringPoolEntry Entry{nullptr, 0, DwarfStringPoolEntry::NotIndexed}; + if (Translator) + S = Translator(S); + auto InsertResult = Strings.insert({S, Entry}); return InsertResult.first->getKey(); } diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp index 60f664ece7ee..9b581a6c9ab7 100644 --- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp @@ -2701,8 +2701,8 @@ Error DWARFLinker::link() { // This Dwarf string pool which is used for emission. It must be used // serially as the order of calling getStringOffset matters for // reproducibility. - OffsetsStringPool DebugStrPool(true); - OffsetsStringPool DebugLineStrPool(false); + OffsetsStringPool DebugStrPool(StringsTranslator, true); + OffsetsStringPool DebugLineStrPool(StringsTranslator, false); DebugDieValuePool StringOffsetPool; // ODR Contexts for the optimize. diff --git a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp index 8b31b5ead29a..6d522370e440 100644 --- a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp +++ b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp @@ -32,9 +32,10 @@ using namespace dwarf_linker::classic; Expected<std::unique_ptr<DwarfStreamer>> DwarfStreamer::createStreamer( const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType, - raw_pwrite_stream &OutFile, DWARFLinkerBase::MessageHandlerTy Warning) { + raw_pwrite_stream &OutFile, DWARFLinkerBase::TranslatorFuncTy Translator, + DWARFLinkerBase::MessageHandlerTy Warning) { std::unique_ptr<DwarfStreamer> Streamer = - std::make_unique<DwarfStreamer>(FileType, OutFile, Warning); + std::make_unique<DwarfStreamer>(FileType, OutFile, Translator, Warning); if (Error Err = Streamer->init(TheTriple, "__DWARF")) return std::move(Err); @@ -976,10 +977,11 @@ void DwarfStreamer::emitLineTableString(const DWARFDebugLine::Prologue &P, switch (String.getForm()) { case dwarf::DW_FORM_string: { - StringRef Str = *StringVal; - Asm->OutStreamer->emitBytes(Str.data()); + StringRef TranslatedString = + (Translator) ? Translator(*StringVal) : *StringVal; + Asm->OutStreamer->emitBytes(TranslatedString.data()); Asm->emitInt8(0); - LineSectionSize += Str.size() + 1; + LineSectionSize += TranslatedString.size() + 1; } break; case dwarf::DW_FORM_strp: case dwarf::DW_FORM_line_strp: { diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp index 31c7e867767a..ad8d28a64317 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp @@ -15,6 +15,8 @@ using namespace dwarf_linker::parallel; std::unique_ptr<DWARFLinker> DWARFLinker::createLinker(MessageHandlerTy ErrorHandler, - MessageHandlerTy WarningHandler) { - return std::make_unique<DWARFLinkerImpl>(ErrorHandler, WarningHandler); + MessageHandlerTy WarningHandler, + TranslatorFuncTy StringsTranslator) { + return std::make_unique<DWARFLinkerImpl>(ErrorHandler, WarningHandler, + StringsTranslator); } diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h index 7ca81eb34f00..38c261a8106f 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h @@ -21,6 +21,7 @@ class DWARFDie; namespace dwarf_linker { namespace parallel { +using TranslatorFuncTy = std::function<StringRef(StringRef)>; using MessageHandlerTy = std::function<void( const Twine &Warning, StringRef Context, const DWARFDie *DIE)>; @@ -94,6 +95,19 @@ public: /// Returns global string pool. StringPool &getStringPool() { return Strings; } + /// Set translation function. + void setTranslator(TranslatorFuncTy Translator) { + this->Translator = Translator; + } + + /// Translate specified string. + StringRef translateString(StringRef String) { + if (Translator) + return Translator(String); + + return String; + } + /// Returns linking options. const DWARFLinkerOptions &getOptions() const { return Options; } @@ -147,6 +161,7 @@ public: protected: llvm::parallel::PerThreadBumpPtrAllocator Allocator; StringPool Strings; + TranslatorFuncTy Translator; DWARFLinkerOptions Options; MessageHandlerTy WarningHandler; MessageHandlerTy ErrorHandler; diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp index e68bf0c227a0..49b08997eb9c 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp @@ -20,9 +20,11 @@ using namespace dwarf_linker; using namespace dwarf_linker::parallel; DWARFLinkerImpl::DWARFLinkerImpl(MessageHandlerTy ErrorHandler, - MessageHandlerTy WarningHandler) + MessageHandlerTy WarningHandler, + TranslatorFuncTy StringsTranslator) : UniqueUnitID(0), DebugStrStrings(GlobalData), DebugLineStrStrings(GlobalData), CommonSections(GlobalData) { + GlobalData.setTranslator(StringsTranslator); GlobalData.setErrorHandler(ErrorHandler); GlobalData.setWarningHandler(WarningHandler); } diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h index 597bb1b4da59..7c17c5b79c7c 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h @@ -26,7 +26,8 @@ namespace parallel { class DWARFLinkerImpl : public DWARFLinker { public: DWARFLinkerImpl(MessageHandlerTy ErrorHandler, - MessageHandlerTy WarningHandler); + MessageHandlerTy WarningHandler, + TranslatorFuncTy StringsTranslator); /// Add object file to be linked. Pre-load compile unit die. Call /// \p OnCUDieLoaded for each compile unit die. If specified \p File diff --git a/llvm/lib/DWARFLinker/Parallel/OutputSections.h b/llvm/lib/DWARFLinker/Parallel/OutputSections.h index 0e1f2dae54bc..a21e4b2b75a5 100644 --- a/llvm/lib/DWARFLinker/Parallel/OutputSections.h +++ b/llvm/lib/DWARFLinker/Parallel/OutputSections.h @@ -253,7 +253,7 @@ struct SectionDescriptor : SectionDescriptorBase { /// Emit specified inplace string value into the current section contents. void emitInplaceString(StringRef String) { - OS << String; + OS << GlobalData.translateString(String); emitIntVal(0, 1); } diff --git a/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h b/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h index f67536ef7a1a..858f224777db 100644 --- a/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h +++ b/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h @@ -33,7 +33,7 @@ public: DwarfStringPoolEntryWithExtString *DataPtr = GlobalData.getAllocator() .Allocate<DwarfStringPoolEntryWithExtString>(); - DataPtr->String = String->getKey(); + DataPtr->String = GlobalData.translateString(String->getKey()); DataPtr->Index = DwarfStringPoolEntry::NotIndexed; DataPtr->Offset = 0; DataPtr->Symbol = nullptr; diff --git a/llvm/test/tools/dsymutil/ARM/obfuscated.test b/llvm/test/tools/dsymutil/ARM/obfuscated.test new file mode 100644 index 000000000000..3443b8e63469 --- /dev/null +++ b/llvm/test/tools/dsymutil/ARM/obfuscated.test @@ -0,0 +1,200 @@ +REQUIRES: system-darwin + +RUN: dsymutil --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck %s + +RUN: dsymutil --accelerator=Pub --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck --check-prefix=PUB %s + +RUN: dsymutil --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck --check-prefix=NOHIDDEN %s + +RUN: dsymutil --symbol-map %p/../Inputs/obfuscated.2.map %p/../Inputs/obfuscated.2.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck --check-prefix=NOHIDDEN %s + +// Run with plist and make sure dsymutil finds it. +RUN: mkdir -p %t.dSYM/Contents/Resources/DWARF/ +RUN: mkdir -p %t.mapdir +RUN: cp %p/../Inputs/obfuscated.arm64 %t.dSYM/Contents/Resources/DWARF/ +RUN: cp %p/../Inputs/E828A486-8433-3A5E-B6DB-A6294D28133D.plist %t.dSYM/Contents/Resources/ +RUN: cp %p/../Inputs/obfuscated.map %t.mapdir/506AA50A-6B26-3B37-86D2-DC6EBD57B720.bcsymbolmap +RUN: dsymutil --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=OBFUSCATING %s + +// Run without plist and make sure dsymutil doesn't crash. +RUN: rm %t.dSYM/Contents/Resources/E828A486-8433-3A5E-B6DB-A6294D28133D.plist +RUN: dsymutil --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=NOTOBFUSCATING %s + +// ---------------------------------------- +// Repeat the same steps for --linker parallel. +RUN: dsymutil --linker parallel --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck %s + +RUN: dsymutil --linker parallel --accelerator=Pub --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck --check-prefix=PUB %s + +RUN: dsymutil --linker parallel --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck --check-prefix=NOHIDDEN %s + +RUN: dsymutil --linker parallel --symbol-map %p/../Inputs/obfuscated.2.map %p/../Inputs/obfuscated.2.arm64 -f -o - \ +RUN: | llvm-dwarfdump -v - \ +RUN: | FileCheck --check-prefix=NOHIDDEN %s + +// Run with plist and make sure dsymutil finds it. +RUN: mkdir -p %t.dSYM/Contents/Resources/DWARF/ +RUN: mkdir -p %t.mapdir +RUN: cp %p/../Inputs/obfuscated.arm64 %t.dSYM/Contents/Resources/DWARF/ +RUN: cp %p/../Inputs/E828A486-8433-3A5E-B6DB-A6294D28133D.plist %t.dSYM/Contents/Resources/ +RUN: cp %p/../Inputs/obfuscated.map %t.mapdir/506AA50A-6B26-3B37-86D2-DC6EBD57B720.bcsymbolmap +RUN: dsymutil --linker parallel --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=OBFUSCATING %s + +// Run without plist and make sure dsymutil doesn't crash. +RUN: rm %t.dSYM/Contents/Resources/E828A486-8433-3A5E-B6DB-A6294D28133D.plist +RUN: dsymutil --linker parallel --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=NOTOBFUSCATING %s + +OBFUSCATING-NOT: not unobfuscating + +NOTOBFUSCATING: not unobfuscating + +NOHIDDEN-NOT: __hidden# + +CHECK: .debug_info contents: + +CHECK: DW_TAG_compile_unit [1] * +CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "main.c") +CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") +CHECK: DW_TAG_subprogram [2] +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "main") + +CHECK: DW_TAG_compile_unit [1] * +CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "one.c") +CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") +CHECK: DW_TAG_subprogram [2] +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "one") + +CHECK: DW_TAG_compile_unit [1] * +CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "two.c") +CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") +CHECK: DW_TAG_subprogram [2] +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "two") + +CHECK: DW_TAG_compile_unit [1] * +CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "three.c") +CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") +CHECK: DW_TAG_subprogram [2] +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "three") + +CHECK: DW_TAG_compile_unit [1] * +CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "four.c") +CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x0000011e) +CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") +CHECK: DW_TAG_subprogram [2] +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "four") + +CHECK: DW_TAG_compile_unit [1] * +CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "five.c") +CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") +CHECK: DW_TAG_subprogram [2] +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "five") + +CHECK: DW_TAG_compile_unit [1] * +CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "six.c") +CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") +CHECK: DW_TAG_subprogram [2] +CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "six") + +CHECK: .debug_line contents: +CHECK: file_names[ 1]: +CHECK: name: "main.c" +CHECK: dir_index: 0 +CHECK: mod_time: 0x00000000 +CHECK: file_names[ 1]: +CHECK: name: "one.c" +CHECK: dir_index: 0 +CHECK: mod_time: 0x00000000 +CHECK: length: 0x00000000 +CHECK: file_names[ 1]: +CHECK: name: "two.c" +CHECK: dir_index: 0 +CHECK: mod_time: 0x00000000 +CHECK: length: 0x00000000 +CHECK: file_names[ 1]: +CHECK: name: "three.c" +CHECK: dir_index: 0 +CHECK: mod_time: 0x00000000 +CHECK: length: 0x00000000 +CHECK: file_names[ 1]: +CHECK: name: "four.c" +CHECK: dir_index: 0 +CHECK: mod_time: 0x00000000 +CHECK: length: 0x00000000 +CHECK: file_names[ 1]: +CHECK: name: "five.c" +CHECK: dir_index: 0 +CHECK: mod_time: 0x00000000 +CHECK: length: 0x00000000 +CHECK: file_names[ 1]: +CHECK: name: "six.c" +CHECK: dir_index: 0 +CHECK: mod_time: 0x00000000 +CHECK: length: 0x00000000 + +PUB: .debug_pubnames contents: +PUB: length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000000, unit_size = 0x00000044 +PUB: 0x0000002e "main" +PUB: length = 0x00000016, format = DWARF32, version = 0x0002, unit_offset = 0x00000044, unit_size = 0x00000044 +PUB: 0x0000002e "one" +PUB: length = 0x00000016, format = DWARF32, version = 0x0002, unit_offset = 0x00000088, unit_size = 0x00000044 +PUB: 0x0000002e "two" +PUB: length = 0x00000018, format = DWARF32, version = 0x0002, unit_offset = 0x000000cc, unit_size = 0x00000044 +PUB: 0x0000002e "three" +PUB: length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000110, unit_size = 0x00000044 +PUB: 0x0000002e "four" +PUB: length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000154, unit_size = 0x00000044 +PUB: 0x0000002e "five" +PUB: length = 0x00000016, format = DWARF32, version = 0x0002, unit_offset = 0x00000198, unit_size = 0x00000044 +PUB: 0x0000002e "six" + +CHECK: .apple_names contents: + +CHECK: String: 0x00000091 "five" +CHECK-NEXT: Data 0 [ +CHECK-NEXT: Atom[0]: 0x00000182 +CHECK-NEXT: ] +CHECK: String: 0x0000009c "six" +CHECK-NEXT: Data 0 [ +CHECK-NEXT: Atom[0]: 0x000001c6 +CHECK-NEXT: ] +CHECK: String: 0x00000078 "three" +CHECK-NEXT: Data 0 [ +CHECK-NEXT: Atom[0]: 0x000000fa +CHECK-NEXT: ] +CHECK: String: 0x0000006c "two" +CHECK-NEXT: Data 0 [ +CHECK-NEXT: Atom[0]: 0x000000b6 +CHECK-NEXT: ] +CHECK: String: 0x00000057 "main" +CHECK-NEXT: Data 0 [ +CHECK-NEXT: Atom[0]: 0x0000002e +CHECK-NEXT: ] +CHECK: String: 0x00000085 "four" +CHECK-NEXT: Data 0 [ +CHECK-NEXT: Atom[0]: 0x0000013e +CHECK-NEXT: ] +CHECK: String: 0x00000062 "one" +CHECK-NEXT: Data 0 [ +CHECK-NEXT: Atom[0]: 0x00000072 +CHECK-NEXT: ] diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.2.arm64 b/llvm/test/tools/dsymutil/Inputs/obfuscated.2.arm64 new file mode 100644 index 0000000000000000000000000000000000000000..b40e023eb4916cca1fe38388ce12b030c1a51eda GIT binary patch literal 10339 zcmeHNO>A355Pr|jbJ8?*5>i!-f<mAz6jY#YY4{1ESZN@6<tGY(0s^i4^GIAdwy_;Z zq^hw{4hSwtRDxcRkjjA*qUxdT1rCS{pk6q@k)K1Qs1nFGkODJrXV%aAY$v(Gjx>Hd zv$NmM&dzSK``(SeZf*8imTdv`0(S%7jG-iH1Rnc=cYk|r@Y9)zKR<l-yUomzmu^K! zZw**h50q>0Ov7^+cp6xU+2qqxuTIT94}wO1XPQnI5$7i`6k>kr<@x4XzkRJ)$C3jD zX4DB$^;W7}8^-(Nyd3<6hKYq^Q`BYER2d3FRI1DAic;zRt*=Quh^eCBczXzs>m{C8 z^ztRI3@voL4+!s|LbJB;FH@<ObA<)6*YU0pURMAwSZo?QR0y$Lcsp0fid^B1qAxek z$5q0^IcL%_SdUMf*PFmXoJ!6oQA1RtBz%$;&Ce)^$c!z-LNPF{ZSf#26=8cOO!45n z2$4^T%IZ?Om=~pLIfOS*llGYFOhG(cH$l0v4xX8L?)22DnR#mUwKh(2@K>rvpMriN z&LRLqyv`)&o+2xJ*wT&%I3}wy<RJTlYZ^(2te0M15cyoelX7dkI(I&XR_%%LQsq=( z!K;M)tJ~7QS;DK|*&YjP7_YRPE~J*ciay@SsKl!i%;bUX;ZfR#{2T9*c)yW<<G}^i z0-F6xrPF2at?+yd$0Xie)OPsp79ar?<H2I}wfcA`2=9ApGqELJs#MB*!Vey_(eb*w zrGLK@UiUpzX!8&vfLBUobi571<FIXP6R)~jf@}%<*WV-kJ4*iaA8z9qsoB3``fLVO zx_>7LkNrEj1zzXgOs$E4iGYcKiGYcKiGYc~e<uQXo*K2~Ap-vu-sj7f#pmMNNq&va zdH0f>C3&3WJjs(JS4o~F`5eiwgWL}t&6AA(xh*XUZ^g?jS3Nifr?PMk7E7sI0cylz zE}QiV2abw>kO&ILg2M5j@DK<^dDwwI4Veg-2$%?%2$%?%2$%?%2$%?%2$%?%2$%@` zpCf=TPa+n+wX*HM<9py2UflVwAZ<8u)A9RZAw#q)!q)=PUfUVytvmZ;?>PHhXUug* zUFSa6IqW*eT_@o>kGsxet`m)&u1EF)=o5Z7_|C3FHwifA`?M><*8@XNw09`dvuy;p z4j=@+u-GXATpJJqUvcadVO$~brN~YZ9#IH<jj}_8V~t4i#Y+R>2#gP}edLE5jjNul zuM7W3`zdA5a}#_O9&9D;-&6KH6P@jED0_~3XZyX7rqY6=+}ZvWWzR9~Z2yU}=Loj5 z9|g~4JTXQO0;`2XsUR(|He~Uroa#G#42)UGA_4bZNYVtu6gGj2uZ9UmCTwydXoA5A zo6s_s9pU)HCgg4sdZQHbw~Ib&kMDr|zQg8Sf-^;J8>~2l)?ttYXcvI-qX(O9IepZg zzzW<`T7bBq{T$c_VO!3rh^{!(8U)wE27_>8PPB-wc(XOgc~IXEVe~!W#?>`{ceNtA z;{DbjAA`EcAl&#IgXoIST7z5$^_L97jn^4OSA2ya_Mm+z4x2`NAT|>JWvy?}z6}5( z4_H`;#?eHj`3bytZTziJW!T458J2=7<3_IpNGVlL_}96Fgo)p%!RuV^BjI24vRM;y z(3M26{{&>W0>J%I2?_9E`i0~)4A1}k4L_af!|?&3&bIJlA(`+|cy<9h!2bYYP50av z2VY#dc>OFqM^-Oh{|L%Mz&``yCrazU7l1DTUjhCG_(xz|1c;A21`=iw%9|(vVSb~G z7)UrRDF1*zK$tLCoFo}j8H?9|kuVofewXTbj3kD}h~v?1@Y6pe95cot3L|%{-B618 L<Jax=xFP1h4!zc3 literal 0 HcmV?d00001 diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.2.map b/llvm/test/tools/dsymutil/Inputs/obfuscated.2.map new file mode 100644 index 000000000000..6efca5960311 --- /dev/null +++ b/llvm/test/tools/dsymutil/Inputs/obfuscated.2.map @@ -0,0 +1,22 @@ +BCSymbolMap Version: 2.0 +_two +_three +_four +_five +_six +LLVM version 3.9.0 (ssh://git@stash.sd.apple.com/devtools/clang.git c74ae34bd917b77f9c848bd599dfde2813fb509f) +main +main.c +/Volumes/Data/dev/BitcodeBuildTests/unit +one +one.c +two +two.c +three +three.c +four +four.c +five +five.c +six +six.c diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.arm64 b/llvm/test/tools/dsymutil/Inputs/obfuscated.arm64 new file mode 100644 index 0000000000000000000000000000000000000000..8395798be17ff1aaea4397cd38c2b0f26f465cb0 GIT binary patch literal 10434 zcmeHNO>7%Q6y9BDoiv0rZ4nA8Y649lMW~7i2~a^5LqhWdC4@*Igc#ZJCUNE1R_s7p zA&5+bdV>Q8Bv4Ng;({twRaJ4K2sjmS;edc6sv;z~lv6>J@9n&|S&uhq(j)AXo@d^h zZ@!&*GduP^@Ao%;|EJBeYzxu~ZH8_n$<lHVMJIHlZ~eWsfn%><`uWo%&-Wd8%3;6N zVOcGxucADK@*e0IRH>=-iP2X_r(b|!h<`D|XPU(GBY;ZHjJ`5c-|F{Yt@nxLq9RH@ zrK;XaRazVQF2AiOe{~aL(cA)QvQ~pSDoRzV%h^icGRL>}j^;y50}0Q!h54ji^Qi@| zQ1+J4!{qyb`Fa92>lWjityGut#d*e?d>5IoDa049*3BIaN-Y=P%olSiUz{uXcKv!> zW<FYT5tBpwRMNU`K$RLv&!ox2vdWuqSRD0b0w$?&D>YvVE$fzi*p`7%e-YZ^;dN1} zkWrP>i`h~^m8(k)d>yMAPkUV?%t!Z4*xtMko*O?oIXW^fd-zLZo;<+cn3Tp89vAT} zfEe+5IX(R>qo}YoPA1r`o4(=!%6RCWCQ&NqWtZnwCYxRI-q@P2OT#UzTPo3Iz_*ks z&U=-H@pbX|rg$=4JLKbS*1%V?^?ZL}zS4cs;}WlouaGZ#<TK+pnb3THGvDN4=^0%L zUwJuO%q)5plkbG9`TpSUCwilK#4CKbS$&tuH<;9XDIVY81JX0PR4P+07d+(;4iJ-X zu37W_%H8K4jOG!q@KsNjvAT_X6D^vrpF2$SNzdp~`26veGqdLS&M=>xb7ywQSIVB6 zr7N0z=M27cx8RE&b?l8J5Jw=6KpcTM0&xW52>kaVK+jWq@f&l7pX2tj{Tkc%vYli5 z2-^j=huE&N{S4c0u|4J6`XPmW%I3ITp1bLnn_9@{a$fOpzX}<tu<=OP7zi7WhK)fo z78jJa;>|8sJv>!sa(Jp%i<x{8*Nr8PKpcTM0&xW52*eSHBM?U*jzAoNI0A75;t2d- zBVg~dd)p7ViS~}<!S;RjemtW)M=h!(+7Xk7q53aZ{lB6-wtuokyfl6Utr{<B1#LBU z()hChUeXTR<F5vINlR>x@4&1yLedu7<7WcAq&2q3e-z*)?XeYp7$fI+;tx&BYO|ik zC&@{uL|3Bbn2z@eISj4m_!yotlsKfXMA9)Gp8*uXaS`4NP~woj5?#l1TmdM8<2!i& zgc67Jm54j0<0pV3IIh7vgwPO&^p#a`Ovm+Tj+=0=Fo*P&m2pf*8?D1I)PZ83@Va!u z{RMMK-!)EZIi{nRI0{h5x*wmm{a5>)`1GmJWFsxbIj$!Z+97*_wN13zZb$2Nw=+56 z-d%IMYwn?%`%um8tGNR;H&t_=thvW(Zgb7upPY0P$%$mk=gwVVKMoqlqW`V8xn2r+ zG+*`v8v%EF>!j1PV+JJOm_fF|ZW)lVV+Pp-yJbL{j~QeO?3Q6LV2};4TZW;4L6(1$ z;Sffr_Ya+YN1?%rKd!rJ1hqCGkoP3fh_g`$UPO(c)31Sp7fB=NylX)4B4`Aia196! zvPRIE)_{;829tXX+1uNY&FJ8M2*^_Xw?U;s1PJvenV&!oXO_91@{`G8gnRgjWp1bg z`AKGO2!m3HM{vO~D22TeGypXAQhE&W^xv+dH*?ycB;>QLq;(S_Hf^IOD80o-Zz;X| z;`yFy&@6O(`h3qfDAUk&Xcg^i&<~;OP&&lFhW-Gh^Og8-KuPF~BKuqVfLwu6^%5Bn z`feecHZKXCi)7d6147>$RMqdRSQeeVWFO~tnIoJ2TZ3r!=R$K#U`DQW2Woo0CO#@A HJHh-5T*?4# literal 0 HcmV?d00001 diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.map b/llvm/test/tools/dsymutil/Inputs/obfuscated.map new file mode 100644 index 000000000000..30fed8bf9b5a --- /dev/null +++ b/llvm/test/tools/dsymutil/Inputs/obfuscated.map @@ -0,0 +1,17 @@ +one +two +three +four +five +six +.str +Apple LLVM version 7.0.0 (clang-700.2.38.2) +main +main.c +/Users/steven/dev/alpena/tests/src +one.c +two.c +three.c +four.c +five.c +six.c diff --git a/llvm/test/tools/dsymutil/cmdline.test b/llvm/test/tools/dsymutil/cmdline.test index 814252b6e230..36cf3f542695 100644 --- a/llvm/test/tools/dsymutil/cmdline.test +++ b/llvm/test/tools/dsymutil/cmdline.test @@ -28,6 +28,7 @@ CHECK: -remarks-output-format <format> CHECK: -remarks-prepend-path <path> CHECK: -reproducer <mode> CHECK: -statistics +CHECK: -symbol-map CHECK: -symtab CHECK: {{-S}} CHECK: -toolchain diff --git a/llvm/tools/dsymutil/CMakeLists.txt b/llvm/tools/dsymutil/CMakeLists.txt index efe28bda68eb..53f882e90b4e 100644 --- a/llvm/tools/dsymutil/CMakeLists.txt +++ b/llvm/tools/dsymutil/CMakeLists.txt @@ -32,6 +32,7 @@ add_llvm_tool(dsymutil MachOUtils.cpp Reproducer.cpp RelocationMap.cpp + SymbolMap.cpp DEPENDS intrinsics_gen diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp index 677dfc44c54a..5ae5ecd556ad 100644 --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -634,19 +634,25 @@ bool DwarfLinkerForBinary::linkImpl( DebugMap DebugMap(Map.getTriple(), Map.getBinaryPath()); + std::function<StringRef(StringRef)> TranslationLambda = [&](StringRef Input) { + assert(Options.Translator); + return Options.Translator(Input); + }; + std::unique_ptr<Linker> GeneralLinker = Linker::createLinker( [&](const Twine &Error, StringRef Context, const DWARFDie *DIE) { reportError(Error, Context, DIE); }, [&](const Twine &Warning, StringRef Context, const DWARFDie *DIE) { reportWarning(Warning, Context, DIE); - }); + }, + Options.Translator ? TranslationLambda : nullptr); std::unique_ptr<classic::DwarfStreamer> Streamer; if (!Options.NoOutput) { if (Expected<std::unique_ptr<classic::DwarfStreamer>> StreamerOrErr = classic::DwarfStreamer::createStreamer( - Map.getTriple(), ObjectType, OutFile, + Map.getTriple(), ObjectType, OutFile, Options.Translator, [&](const Twine &Warning, StringRef Context, const DWARFDie *DIE) { reportWarning(Warning, Context, DIE); @@ -860,8 +866,8 @@ bool DwarfLinkerForBinary::linkImpl( if (Map.getTriple().isOSDarwin() && !Map.getBinaryPath().empty() && ObjectType == Linker::OutputFileType::Object) return MachOUtils::generateDsymCompanion( - Options.VFS, Map, *Streamer->getAsmPrinter().OutStreamer, OutFile, - RelocationsToApply); + Options.VFS, Map, Options.Translator, + *Streamer->getAsmPrinter().OutStreamer, OutFile, RelocationsToApply); Streamer->finish(); return true; diff --git a/llvm/tools/dsymutil/LinkUtils.h b/llvm/tools/dsymutil/LinkUtils.h index 6aa0b847eebd..fd9d985097d6 100644 --- a/llvm/tools/dsymutil/LinkUtils.h +++ b/llvm/tools/dsymutil/LinkUtils.h @@ -9,6 +9,8 @@ #ifndef LLVM_TOOLS_DSYMUTIL_LINKOPTIONS_H #define LLVM_TOOLS_DSYMUTIL_LINKOPTIONS_H +#include "SymbolMap.h" + #include "llvm/ADT/Twine.h" #include "llvm/Remarks/RemarkFormat.h" #include "llvm/Support/VirtualFileSystem.h" @@ -85,6 +87,9 @@ struct LinkOptions { /// The Resources directory in the .dSYM bundle. std::optional<std::string> ResourceDir; + /// Symbol map translator. + SymbolMapTranslator Translator; + /// Virtual File System. llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = vfs::getRealFileSystem(); diff --git a/llvm/tools/dsymutil/MachOUtils.cpp b/llvm/tools/dsymutil/MachOUtils.cpp index 8e144d640ed0..3efc1aff8237 100644 --- a/llvm/tools/dsymutil/MachOUtils.cpp +++ b/llvm/tools/dsymutil/MachOUtils.cpp @@ -373,7 +373,7 @@ static unsigned segmentLoadCommandSize(bool Is64Bit, unsigned NumSections) { // \a OutFile and it must be using a MachObjectWriter object to do so. bool generateDsymCompanion( llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, const DebugMap &DM, - MCStreamer &MS, raw_fd_ostream &OutFile, + SymbolMapTranslator &Translator, MCStreamer &MS, raw_fd_ostream &OutFile, const std::vector<MachOUtils::DwarfRelocationApplicationInfo> &RelocationsToApply) { auto &ObjectStreamer = static_cast<MCObjectStreamer &>(MS); @@ -509,9 +509,12 @@ bool generateDsymCompanion( } SmallString<0> NewSymtab; + std::function<StringRef(StringRef)> TranslationLambda = + Translator ? [&](StringRef Input) { return Translator(Input); } + : static_cast<std::function<StringRef(StringRef)>>(nullptr); // Legacy dsymutil puts an empty string at the start of the line table. // thus we set NonRelocatableStringpool(,PutEmptyString=true) - NonRelocatableStringpool NewStrings(true); + NonRelocatableStringpool NewStrings(TranslationLambda, true); unsigned NListSize = Is64Bit ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); unsigned NumSyms = 0; uint64_t NewStringsSize = 0; diff --git a/llvm/tools/dsymutil/MachOUtils.h b/llvm/tools/dsymutil/MachOUtils.h index 0229647b00f8..059d9fdd788a 100644 --- a/llvm/tools/dsymutil/MachOUtils.h +++ b/llvm/tools/dsymutil/MachOUtils.h @@ -8,6 +8,8 @@ #ifndef LLVM_TOOLS_DSYMUTIL_MACHOUTILS_H #define LLVM_TOOLS_DSYMUTIL_MACHOUTILS_H +#include "SymbolMap.h" + #include "llvm/ADT/StringRef.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/VirtualFileSystem.h" @@ -57,7 +59,7 @@ bool generateUniversalBinary(SmallVectorImpl<ArchAndFile> &ArchFiles, StringRef SDKPath, bool Fat64 = false); bool generateDsymCompanion( llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, const DebugMap &DM, - MCStreamer &MS, raw_fd_ostream &OutFile, + SymbolMapTranslator &Translator, MCStreamer &MS, raw_fd_ostream &OutFile, const std::vector<MachOUtils::DwarfRelocationApplicationInfo> &RelocationsToApply); diff --git a/llvm/tools/dsymutil/Options.td b/llvm/tools/dsymutil/Options.td index d8cec0cb2c41..a4e4c6c4cdb9 100644 --- a/llvm/tools/dsymutil/Options.td +++ b/llvm/tools/dsymutil/Options.td @@ -128,6 +128,12 @@ def object_prefix_map: Separate<["--", "-"], "object-prefix-map">, Group<grp_general>; def: Joined<["--", "-"], "object-prefix-map=">, Alias<object_prefix_map>; +def symbolmap: Separate<["--", "-"], "symbol-map">, + MetaVarName<"<bcsymbolmap>">, + HelpText<"Updates the existing dSYMs inplace using symbol map specified.">, + Group<grp_general>; +def: Joined<["--", "-"], "symbol-map=">, Alias<symbolmap>; + def arch: Separate<["--", "-"], "arch">, MetaVarName<"<arch>">, HelpText<"Link DWARF debug information only for specified CPU architecture" diff --git a/llvm/tools/dsymutil/SymbolMap.cpp b/llvm/tools/dsymutil/SymbolMap.cpp new file mode 100644 index 000000000000..c55362e5f775 --- /dev/null +++ b/llvm/tools/dsymutil/SymbolMap.cpp @@ -0,0 +1,157 @@ +//===- tools/dsymutil/SymbolMap.cpp ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "SymbolMap.h" +#include "DebugMap.h" +#include "MachOUtils.h" + +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/WithColor.h" + +#ifdef __APPLE__ +#include <CoreFoundation/CoreFoundation.h> +#include <uuid/uuid.h> +#endif + +namespace llvm { +namespace dsymutil { + +StringRef SymbolMapTranslator::operator()(StringRef Input) { + if (!Input.starts_with("__hidden#") && !Input.starts_with("___hidden#")) + return Input; + + StringRef Line = Input.drop_front(sizeof("__hidden#") - 1); + bool MightNeedUnderscore = Line.consume_front("#"); + + std::size_t LineNumber = std::numeric_limits<std::size_t>::max(); + Line.split('_').first.getAsInteger(10, LineNumber); + if (LineNumber >= UnobfuscatedStrings.size()) { + WithColor::warning() << "reference to a unexisting unobfuscated string " + << Input << ": symbol map mismatch?\n" + << Line << '\n'; + return Input; + } + + const std::string &Translation = UnobfuscatedStrings[LineNumber]; + if (!MightNeedUnderscore || !MangleNames) + return Translation; + + // Objective-C symbols for the MachO symbol table start with a \1. Please see + // `MangleContext::mangleObjCMethodName` in clang. + if (Translation[0] == 1) + return StringRef(Translation).drop_front(); + + // We need permanent storage for the string we are about to create. Just + // append it to the vector containing translations. This should only happen + // during MachO symbol table translation, thus there should be no risk on + // exponential growth. + UnobfuscatedStrings.emplace_back("_" + Translation); + return UnobfuscatedStrings.back(); +} + +SymbolMapTranslator SymbolMapLoader::Load(StringRef InputFile, + const DebugMap &Map) const { + if (SymbolMap.empty()) + return {}; + + std::string SymbolMapPath = SymbolMap; + +#if __APPLE__ + // Look through the UUID Map. + if (sys::fs::is_directory(SymbolMapPath) && !Map.getUUID().empty()) { + uuid_string_t UUIDString; + uuid_unparse_upper((const uint8_t *)Map.getUUID().data(), UUIDString); + + SmallString<256> PlistPath( + sys::path::parent_path(sys::path::parent_path(InputFile))); + sys::path::append(PlistPath, StringRef(UUIDString).str() + ".plist"); + + CFStringRef plistFile = CFStringCreateWithCString( + kCFAllocatorDefault, PlistPath.c_str(), kCFStringEncodingUTF8); + CFURLRef fileURL = CFURLCreateWithFileSystemPath( + kCFAllocatorDefault, plistFile, kCFURLPOSIXPathStyle, false); + CFReadStreamRef resourceData = + CFReadStreamCreateWithFile(kCFAllocatorDefault, fileURL); + if (resourceData) { + CFReadStreamOpen(resourceData); + CFDictionaryRef plist = (CFDictionaryRef)CFPropertyListCreateWithStream( + kCFAllocatorDefault, resourceData, 0, kCFPropertyListImmutable, + nullptr, nullptr); + + if (plist) { + if (CFDictionaryContainsKey(plist, CFSTR("DBGOriginalUUID"))) { + CFStringRef OldUUID = (CFStringRef)CFDictionaryGetValue( + plist, CFSTR("DBGOriginalUUID")); + + StringRef UUID(CFStringGetCStringPtr(OldUUID, kCFStringEncodingUTF8)); + SmallString<256> BCSymbolMapPath(SymbolMapPath); + sys::path::append(BCSymbolMapPath, UUID.str() + ".bcsymbolmap"); + SymbolMapPath = std::string(BCSymbolMapPath); + } + CFRelease(plist); + } + CFReadStreamClose(resourceData); + CFRelease(resourceData); + } + CFRelease(fileURL); + CFRelease(plistFile); + } +#endif + + if (sys::fs::is_directory(SymbolMapPath)) { + SymbolMapPath += (Twine("/") + sys::path::filename(InputFile) + "-" + + MachOUtils::getArchName(Map.getTriple().getArchName()) + + ".bcsymbolmap") + .str(); + } + + auto ErrOrMemBuffer = MemoryBuffer::getFile(SymbolMapPath); + if (auto EC = ErrOrMemBuffer.getError()) { + WithColor::warning() << SymbolMapPath << ": " << EC.message() + << ": not unobfuscating.\n"; + return {}; + } + + std::vector<std::string> UnobfuscatedStrings; + auto &MemBuf = **ErrOrMemBuffer; + StringRef Data(MemBuf.getBufferStart(), + MemBuf.getBufferEnd() - MemBuf.getBufferStart()); + StringRef LHS; + std::tie(LHS, Data) = Data.split('\n'); + bool MangleNames = false; + + // Check version string first. + if (!LHS.starts_with("BCSymbolMap Version:")) { + // Version string not present, warns but try to parse it. + WithColor::warning() << SymbolMapPath + << " is missing version string: assuming 1.0.\n"; + UnobfuscatedStrings.emplace_back(LHS); + } else if (LHS.equals("BCSymbolMap Version: 1.0")) { + MangleNames = true; + } else if (LHS.equals("BCSymbolMap Version: 2.0")) { + MangleNames = false; + } else { + StringRef VersionNum; + std::tie(LHS, VersionNum) = LHS.split(':'); + WithColor::warning() << SymbolMapPath + << " has unsupported symbol map version" << VersionNum + << ": not unobfuscating.\n"; + return {}; + } + + while (!Data.empty()) { + std::tie(LHS, Data) = Data.split('\n'); + UnobfuscatedStrings.emplace_back(LHS); + } + + return SymbolMapTranslator(std::move(UnobfuscatedStrings), MangleNames); +} + +} // namespace dsymutil +} // namespace llvm diff --git a/llvm/tools/dsymutil/SymbolMap.h b/llvm/tools/dsymutil/SymbolMap.h new file mode 100644 index 000000000000..977de31a5a17 --- /dev/null +++ b/llvm/tools/dsymutil/SymbolMap.h @@ -0,0 +1,53 @@ +//=- tools/dsymutil/SymbolMap.h -----------------------------------*- C++ -*-=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_DSYMUTIL_SYMBOLMAP_H +#define LLVM_TOOLS_DSYMUTIL_SYMBOLMAP_H + +#include "llvm/ADT/StringRef.h" + +#include <string> +#include <vector> + +namespace llvm { +namespace dsymutil { +class DebugMap; + +/// Callable class to unobfuscate strings based on a BCSymbolMap. +class SymbolMapTranslator { +public: + SymbolMapTranslator() : MangleNames(false) {} + + SymbolMapTranslator(std::vector<std::string> UnobfuscatedStrings, + bool MangleNames) + : UnobfuscatedStrings(std::move(UnobfuscatedStrings)), + MangleNames(MangleNames) {} + + StringRef operator()(StringRef Input); + + operator bool() const { return !UnobfuscatedStrings.empty(); } + +private: + std::vector<std::string> UnobfuscatedStrings; + bool MangleNames; +}; + +/// Class to initialize SymbolMapTranslators from a BCSymbolMap. +class SymbolMapLoader { +public: + SymbolMapLoader(std::string SymbolMap) : SymbolMap(std::move(SymbolMap)) {} + + SymbolMapTranslator Load(StringRef InputFile, const DebugMap &Map) const; + +private: + const std::string SymbolMap; +}; +} // namespace dsymutil +} // namespace llvm + +#endif // LLVM_TOOLS_DSYMUTIL_SYMBOLMAP_H diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp index bc968b6387b6..25e281c415e7 100644 --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/tools/dsymutil/dsymutil.cpp @@ -108,6 +108,7 @@ struct DsymutilOptions { bool Flat = false; bool InputIsYAMLDebugMap = false; bool ForceKeepFunctionForStatic = false; + std::string SymbolMap; std::string OutputFile; std::string Toolchain; std::string ReproducerPath; @@ -340,6 +341,12 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) { return DWARFLinkerType.takeError(); } + if (opt::Arg *SymbolMap = Args.getLastArg(OPT_symbolmap)) + Options.SymbolMap = SymbolMap->getValue(); + + if (Args.hasArg(OPT_symbolmap)) + Options.LinkOpts.Update = true; + if (Expected<std::vector<std::string>> InputFiles = getInputs(Args, Options.LinkOpts.Update)) { Options.InputFiles = std::move(*InputFiles); @@ -553,7 +560,8 @@ getOutputFileName(StringRef InputFile, const DsymutilOptions &Options) { return OutputLocation(Options.OutputFile); // When updating, do in place replacement. - if (Options.OutputFile.empty() && Options.LinkOpts.Update) + if (Options.OutputFile.empty() && + (Options.LinkOpts.Update || !Options.SymbolMap.empty())) return OutputLocation(std::string(InputFile)); // When dumping the debug map, just return an empty output location. This @@ -660,6 +668,8 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) { return EXIT_FAILURE; } + SymbolMapLoader SymMapLoader(Options.SymbolMap); + for (auto &InputFile : Options.InputFiles) { // Dump the symbol table for each input file and requested arch if (Options.DumpStab) { @@ -750,6 +760,9 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) { if (Options.DumpDebugMap) continue; + if (!Options.SymbolMap.empty()) + Options.LinkOpts.Translator = SymMapLoader.Load(InputFile, *Map); + if (Map->begin() == Map->end()) { std::lock_guard<std::mutex> Guard(ErrorHandlerMutex); WithColor::warning() diff --git a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp index 285dcf75ecd9..bd17f3c4a659 100644 --- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp +++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp @@ -338,9 +338,9 @@ Error linkDebugInfoImpl(object::ObjectFile &File, const Options &Options, Triple TargetTriple = File.makeTriple(); std::unique_ptr<classic::DwarfStreamer> Streamer; if (Expected<std::unique_ptr<classic::DwarfStreamer>> StreamerOrErr = - classic::DwarfStreamer::createStreamer(TargetTriple, - Linker::OutputFileType::Object, - OutStream, ReportWarn)) + classic::DwarfStreamer::createStreamer( + TargetTriple, Linker::OutputFileType::Object, OutStream, nullptr, + ReportWarn)) Streamer = std::move(*StreamerOrErr); else return StreamerOrErr.takeError(); -- GitLab From 71b69dd21becdfbf8922674ce6ca4129926660ab Mon Sep 17 00:00:00 2001 From: Heejin Ahn <aheejin@gmail.com> Date: Tue, 19 Mar 2024 11:00:33 -0700 Subject: [PATCH 119/307] [WebAssembly] Pass ArrayRef by value (NFC) (#85732) `ArrayRef` is supposed to be passed by value: https://github.com/llvm/llvm-project/blob/bda05140fb758156ae35f3919e6283d94bfa3905/llvm/include/llvm/ADT/ArrayRef.h#L38-L39 --- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp | 2 +- llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h | 2 +- llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp | 2 +- llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h | 3 +-- llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp index 86fb99cc98a9..fac2e0d935f5 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp @@ -63,7 +63,7 @@ wasm::ValType WebAssembly::toValType(MVT Type) { } void WebAssembly::wasmSymbolSetType(MCSymbolWasm *Sym, const Type *GlobalVT, - const ArrayRef<MVT> &VTs) { + ArrayRef<MVT> VTs) { assert(!Sym->getType()); // Tables are represented as Arrays in LLVM IR therefore diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h index a184ecb9a465..87660947e7de 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h @@ -60,7 +60,7 @@ wasm::ValType toValType(MVT Type); /// Sets a Wasm Symbol Type. void wasmSymbolSetType(MCSymbolWasm *Sym, const Type *GlobalVT, - const ArrayRef<MVT> &VTs); + ArrayRef<MVT> VTs); } // end namespace WebAssembly } // end namespace llvm diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp index 1e959111a4db..d17394eede77 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp @@ -105,7 +105,7 @@ void llvm::computeSignatureVTs(const FunctionType *Ty, } } -void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In, +void llvm::valTypesFromMVTs(ArrayRef<MVT> In, SmallVectorImpl<wasm::ValType> &Out) { for (MVT Ty : In) Out.push_back(WebAssembly::toValType(Ty)); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h index fe18347ad8c1..37059188a761 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h @@ -169,8 +169,7 @@ void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results); -void valTypesFromMVTs(const ArrayRef<MVT> &In, - SmallVectorImpl<wasm::ValType> &Out); +void valTypesFromMVTs(ArrayRef<MVT> In, SmallVectorImpl<wasm::ValType> &Out); std::unique_ptr<wasm::WasmSignature> signatureFromMVTs(const SmallVectorImpl<MVT> &Results, diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp index c9ef17f92814..acd984f2f8f8 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp @@ -129,7 +129,7 @@ buildVRegToDbgValueMap(MachineFunction &MF, const LiveIntervals *Liveness) { // changes. static void undefInvalidDbgValues( const LiveIntervals *Liveness, - const ArrayRef<SmallVector<LiveInterval *, 4>> &Assignments, + ArrayRef<SmallVector<LiveInterval *, 4>> Assignments, DenseMap<Register, std::vector<std::pair<SlotIndex, MachineInstr *>>> &DbgVRegToValues) { #ifndef NDEBUG -- GitLab From e61922d327c39805a7303586f4b0accf3398c774 Mon Sep 17 00:00:00 2001 From: Takuto Ikuta <tikuta@google.com> Date: Wed, 20 Mar 2024 03:03:18 +0900 Subject: [PATCH 120/307] Expose TimeTraceProfiler for Async Events (#83778) To avoid issue like https://github.com/llvm/llvm-project/issues/56554 and https://github.com/llvm/llvm-project/issues/83236 due to no guarantees for nested relationships between file level span and syntax tree level span, I'd like to have a `timeTraceAsyncProfilerBegin` specific to trace handling only `Source` spans around https://github.com/llvm/llvm-project/blob/8715f256911786520bb727ce067098d7082ac45c/clang/lib/Sema/Sema.cpp#L153-L170. This is a preparation PR to do that in [following PR](https://github.com/llvm/llvm-project/pull/83961). --- llvm/include/llvm/Support/TimeProfiler.h | 34 +++++-- llvm/lib/Support/TimeProfiler.cpp | 101 ++++++++++++++------ llvm/unittests/Support/TimeProfilerTest.cpp | 11 +++ 3 files changed, 107 insertions(+), 39 deletions(-) diff --git a/llvm/include/llvm/Support/TimeProfiler.h b/llvm/include/llvm/Support/TimeProfiler.h index 454a65f70231..31f7df10916d 100644 --- a/llvm/include/llvm/Support/TimeProfiler.h +++ b/llvm/include/llvm/Support/TimeProfiler.h @@ -86,6 +86,8 @@ class raw_pwrite_stream; struct TimeTraceProfiler; TimeTraceProfiler *getTimeTraceProfilerInstance(); +struct TimeTraceProfilerEntry; + /// Initialize the time trace profiler. /// This sets up the global \p TimeTraceProfilerInstance /// variable to be the profiler instance. @@ -120,19 +122,30 @@ Error timeTraceProfilerWrite(StringRef PreferredFileName, /// Profiler copies the string data, so the pointers can be given into /// temporaries. Time sections can be hierarchical; every Begin must have a /// matching End pair but they can nest. -void timeTraceProfilerBegin(StringRef Name, StringRef Detail); -void timeTraceProfilerBegin(StringRef Name, - llvm::function_ref<std::string()> Detail); +TimeTraceProfilerEntry *timeTraceProfilerBegin(StringRef Name, + StringRef Detail); +TimeTraceProfilerEntry * +timeTraceProfilerBegin(StringRef Name, + llvm::function_ref<std::string()> Detail); + +/// Manually begin a time section, with the given \p Name and \p Detail. +/// This starts Async Events having \p Name as a category which is shown +/// separately from other traces. See +/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview#heading=h.jh64i9l3vwa1 +/// for more details. +TimeTraceProfilerEntry *timeTraceAsyncProfilerBegin(StringRef Name, + StringRef Detail); /// Manually end the last time section. void timeTraceProfilerEnd(); +void timeTraceProfilerEnd(TimeTraceProfilerEntry *E); /// The TimeTraceScope is a helper class to call the begin and end functions /// of the time trace profiler. When the object is constructed, it begins /// the section; and when it is destroyed, it stops it. If the time profiler /// is not initialized, the overhead is a single branch. -struct TimeTraceScope { - +class TimeTraceScope { +public: TimeTraceScope() = delete; TimeTraceScope(const TimeTraceScope &) = delete; TimeTraceScope &operator=(const TimeTraceScope &) = delete; @@ -141,20 +154,23 @@ struct TimeTraceScope { TimeTraceScope(StringRef Name) { if (getTimeTraceProfilerInstance() != nullptr) - timeTraceProfilerBegin(Name, StringRef("")); + Entry = timeTraceProfilerBegin(Name, StringRef("")); } TimeTraceScope(StringRef Name, StringRef Detail) { if (getTimeTraceProfilerInstance() != nullptr) - timeTraceProfilerBegin(Name, Detail); + Entry = timeTraceProfilerBegin(Name, Detail); } TimeTraceScope(StringRef Name, llvm::function_ref<std::string()> Detail) { if (getTimeTraceProfilerInstance() != nullptr) - timeTraceProfilerBegin(Name, Detail); + Entry = timeTraceProfilerBegin(Name, Detail); } ~TimeTraceScope() { if (getTimeTraceProfilerInstance() != nullptr) - timeTraceProfilerEnd(); + timeTraceProfilerEnd(Entry); } + +private: + TimeTraceProfilerEntry *Entry = nullptr; }; } // end namespace llvm diff --git a/llvm/lib/Support/TimeProfiler.cpp b/llvm/lib/Support/TimeProfiler.cpp index 4d625b3eb5b1..092028dd2a5b 100644 --- a/llvm/lib/Support/TimeProfiler.cpp +++ b/llvm/lib/Support/TimeProfiler.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/TimeProfiler.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/JSON.h" @@ -20,6 +21,7 @@ #include <algorithm> #include <cassert> #include <chrono> +#include <memory> #include <mutex> #include <string> #include <vector> @@ -64,17 +66,19 @@ using CountAndDurationType = std::pair<size_t, DurationType>; using NameAndCountAndDurationType = std::pair<std::string, CountAndDurationType>; +} // anonymous namespace + /// Represents an open or completed time section entry to be captured. -struct TimeTraceProfilerEntry { +struct llvm::TimeTraceProfilerEntry { const TimePointType Start; TimePointType End; const std::string Name; const std::string Detail; - + const bool AsyncEvent = false; TimeTraceProfilerEntry(TimePointType &&S, TimePointType &&E, std::string &&N, - std::string &&Dt) + std::string &&Dt, bool Ae) : Start(std::move(S)), End(std::move(E)), Name(std::move(N)), - Detail(std::move(Dt)) {} + Detail(std::move(Dt)), AsyncEvent(Ae) {} // Calculate timings for FlameGraph. Cast time points to microsecond precision // rather than casting duration. This avoids truncation issues causing inner @@ -92,8 +96,6 @@ struct TimeTraceProfilerEntry { } }; -} // anonymous namespace - struct llvm::TimeTraceProfiler { TimeTraceProfiler(unsigned TimeTraceGranularity = 0, StringRef ProcName = "") : BeginningOfTime(system_clock::now()), StartTime(ClockType::now()), @@ -102,22 +104,23 @@ struct llvm::TimeTraceProfiler { llvm::get_thread_name(ThreadName); } - void begin(std::string Name, llvm::function_ref<std::string()> Detail) { - Stack.emplace_back(ClockType::now(), TimePointType(), std::move(Name), - Detail()); + TimeTraceProfilerEntry *begin(std::string Name, + llvm::function_ref<std::string()> Detail, + bool AsyncEvent = false) { + Stack.emplace_back(std::make_unique<TimeTraceProfilerEntry>( + ClockType::now(), TimePointType(), std::move(Name), Detail(), + AsyncEvent)); + return Stack.back().get(); } void end() { assert(!Stack.empty() && "Must call begin() first"); - TimeTraceProfilerEntry &E = Stack.back(); - E.End = ClockType::now(); + end(*Stack.back().get()); + } - // Check that end times monotonically increase. - assert((Entries.empty() || - (E.getFlameGraphStartUs(StartTime) + E.getFlameGraphDurUs() >= - Entries.back().getFlameGraphStartUs(StartTime) + - Entries.back().getFlameGraphDurUs())) && - "TimeProfiler scope ended earlier than previous scope"); + void end(TimeTraceProfilerEntry &E) { + assert(!Stack.empty() && "Must call begin() first"); + E.End = ClockType::now(); // Calculate duration at full precision for overall counts. DurationType Duration = E.End - E.Start; @@ -132,15 +135,18 @@ struct llvm::TimeTraceProfiler { // happens to be the ones that don't have any currently open entries above // itself. if (llvm::none_of(llvm::drop_begin(llvm::reverse(Stack)), - [&](const TimeTraceProfilerEntry &Val) { - return Val.Name == E.Name; + [&](const std::unique_ptr<TimeTraceProfilerEntry> &Val) { + return Val->Name == E.Name; })) { auto &CountAndTotal = CountAndTotalPerName[E.Name]; CountAndTotal.first++; CountAndTotal.second += Duration; - } + }; - Stack.pop_back(); + llvm::erase_if(Stack, + [&](const std::unique_ptr<TimeTraceProfilerEntry> &Val) { + return Val.get() == &E; + }); } // Write events from this TimeTraceProfilerInstance and @@ -168,14 +174,32 @@ struct llvm::TimeTraceProfiler { J.object([&] { J.attribute("pid", Pid); J.attribute("tid", int64_t(Tid)); - J.attribute("ph", "X"); J.attribute("ts", StartUs); - J.attribute("dur", DurUs); + if (E.AsyncEvent) { + J.attribute("cat", E.Name); + J.attribute("ph", "b"); + J.attribute("id", 0); + } else { + J.attribute("ph", "X"); + J.attribute("dur", DurUs); + } J.attribute("name", E.Name); if (!E.Detail.empty()) { J.attributeObject("args", [&] { J.attribute("detail", E.Detail); }); } }); + + if (E.AsyncEvent) { + J.object([&] { + J.attribute("pid", Pid); + J.attribute("tid", int64_t(Tid)); + J.attribute("ts", StartUs + DurUs); + J.attribute("cat", E.Name); + J.attribute("ph", "e"); + J.attribute("id", 0); + J.attribute("name", E.Name); + }); + } }; for (const TimeTraceProfilerEntry &E : Entries) writeEvent(E, this->Tid); @@ -269,7 +293,7 @@ struct llvm::TimeTraceProfiler { J.objectEnd(); } - SmallVector<TimeTraceProfilerEntry, 16> Stack; + SmallVector<std::unique_ptr<TimeTraceProfilerEntry>, 16> Stack; SmallVector<TimeTraceProfilerEntry, 128> Entries; StringMap<CountAndDurationType> CountAndTotalPerName; // System clock time when the session was begun. @@ -341,19 +365,36 @@ Error llvm::timeTraceProfilerWrite(StringRef PreferredFileName, return Error::success(); } -void llvm::timeTraceProfilerBegin(StringRef Name, StringRef Detail) { +TimeTraceProfilerEntry *llvm::timeTraceProfilerBegin(StringRef Name, + StringRef Detail) { if (TimeTraceProfilerInstance != nullptr) - TimeTraceProfilerInstance->begin(std::string(Name), - [&]() { return std::string(Detail); }); + return TimeTraceProfilerInstance->begin( + std::string(Name), [&]() { return std::string(Detail); }, false); + return nullptr; } -void llvm::timeTraceProfilerBegin(StringRef Name, - llvm::function_ref<std::string()> Detail) { +TimeTraceProfilerEntry * +llvm::timeTraceProfilerBegin(StringRef Name, + llvm::function_ref<std::string()> Detail) { if (TimeTraceProfilerInstance != nullptr) - TimeTraceProfilerInstance->begin(std::string(Name), Detail); + return TimeTraceProfilerInstance->begin(std::string(Name), Detail, false); + return nullptr; +} + +TimeTraceProfilerEntry *llvm::timeTraceAsyncProfilerBegin(StringRef Name, + StringRef Detail) { + if (TimeTraceProfilerInstance != nullptr) + return TimeTraceProfilerInstance->begin( + std::string(Name), [&]() { return std::string(Detail); }, true); + return nullptr; } void llvm::timeTraceProfilerEnd() { if (TimeTraceProfilerInstance != nullptr) TimeTraceProfilerInstance->end(); } + +void llvm::timeTraceProfilerEnd(TimeTraceProfilerEntry *E) { + if (TimeTraceProfilerInstance != nullptr) + TimeTraceProfilerInstance->end(*E); +} diff --git a/llvm/unittests/Support/TimeProfilerTest.cpp b/llvm/unittests/Support/TimeProfilerTest.cpp index 6be716bae6b3..bb820ec99a39 100644 --- a/llvm/unittests/Support/TimeProfilerTest.cpp +++ b/llvm/unittests/Support/TimeProfilerTest.cpp @@ -54,6 +54,17 @@ TEST(TimeProfiler, Begin_End_Smoke) { ASSERT_TRUE(json.find(R"("detail":"detail")") != std::string::npos); } +TEST(TimeProfiler, Async_Begin_End_Smoke) { + setupProfiler(); + + auto *Profiler = timeTraceAsyncProfilerBegin("event", "detail"); + timeTraceProfilerEnd(Profiler); + + std::string json = teardownProfiler(); + ASSERT_TRUE(json.find(R"("name":"event")") != std::string::npos); + ASSERT_TRUE(json.find(R"("detail":"detail")") != std::string::npos); +} + TEST(TimeProfiler, Begin_End_Disabled) { // Nothing should be observable here. The test is really just making sure // we've not got a stray nullptr deref. -- GitLab From 1d296ec226903a09de0215e05d852b2b80712855 Mon Sep 17 00:00:00 2001 From: Michael Jones <michaelrj@google.com> Date: Tue, 19 Mar 2024 11:31:23 -0700 Subject: [PATCH 121/307] [libc][bazel] fix missing iterator inclusion (#85840) Patch #85702 added a new iterator header for array to use, but didn't add it as a dependency in the bazel build. This patch fixes the issue. --- utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 77fb8c16507b..4766e168daad 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -161,10 +161,20 @@ libc_support_library( ], ) +libc_support_library( + name = "__support_cpp_iterator", + hdrs = ["src/__support/CPP/iterator.h"], + deps = [ + ":__support_cpp_type_traits", + ":__support_macros_attributes", + ], +) + libc_support_library( name = "__support_cpp_array", hdrs = ["src/__support/CPP/array.h"], deps = [ + ":__support_cpp_iterator", ":__support_macros_attributes", ], ) -- GitLab From a0394f16912c49a6760fbc22ab9d29c6cac6fb0a Mon Sep 17 00:00:00 2001 From: Paul T Robinson <paul.robinson@sony.com> Date: Tue, 19 Mar 2024 14:49:05 -0400 Subject: [PATCH 122/307] [Headers][X86] Add rounding and exception notes to conversions (#83447) Consistently describe rounding/truncating on convert intrinsics. Add notes where an out-of-range result can raise an exception. --- clang/lib/Headers/avxintrin.h | 31 +++++++++++----- clang/lib/Headers/emmintrin.h | 62 ++++++++++++++++++++++++-------- clang/lib/Headers/xmmintrin.h | 67 +++++++++++++++++++++++++++-------- 3 files changed, 123 insertions(+), 37 deletions(-) diff --git a/clang/lib/Headers/avxintrin.h b/clang/lib/Headers/avxintrin.h index ecd9bf18a41c..a8882e82e171 100644 --- a/clang/lib/Headers/avxintrin.h +++ b/clang/lib/Headers/avxintrin.h @@ -2201,6 +2201,10 @@ _mm256_cvtpd_ps(__m256d __a) /// Converts a vector of [8 x float] into a vector of [8 x i32]. /// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. +/// /// \headerfile <x86intrin.h> /// /// This intrinsic corresponds to the <c> VCVTPS2DQ </c> instruction. @@ -2230,9 +2234,13 @@ _mm256_cvtps_pd(__m128 __a) return (__m256d)__builtin_convertvector((__v4sf)__a, __v4df); } -/// Converts a 256-bit vector of [4 x double] into a 128-bit vector of [4 -/// x i32], truncating the result by rounding towards zero when it is -/// inexact. +/// Converts a 256-bit vector of [4 x double] into four signed truncated +/// (rounded toward zero) 32-bit integers returned in a 128-bit vector of +/// [4 x i32]. +/// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// @@ -2247,9 +2255,12 @@ _mm256_cvttpd_epi32(__m256d __a) return (__m128i)__builtin_ia32_cvttpd2dq256((__v4df) __a); } -/// Converts a 256-bit vector of [4 x double] into a 128-bit vector of [4 -/// x i32]. When a conversion is inexact, the value returned is rounded -/// according to the rounding control bits in the MXCSR register. +/// Converts a 256-bit vector of [4 x double] into a 128-bit vector of +/// [4 x i32]. +/// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// @@ -2264,8 +2275,12 @@ _mm256_cvtpd_epi32(__m256d __a) return (__m128i)__builtin_ia32_cvtpd2dq256((__v4df) __a); } -/// Converts a vector of [8 x float] into a vector of [8 x i32], -/// truncating the result by rounding towards zero when it is inexact. +/// Converts a vector of [8 x float] into eight signed truncated (rounded +/// toward zero) 32-bit integers returned in a vector of [8 x i32]. +/// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// diff --git a/clang/lib/Headers/emmintrin.h b/clang/lib/Headers/emmintrin.h index 984f0cf917e9..f0c2db752195 100644 --- a/clang/lib/Headers/emmintrin.h +++ b/clang/lib/Headers/emmintrin.h @@ -1294,6 +1294,10 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_cvtepi32_pd(__m128i __a) { /// returned in the lower 64 bits of a 128-bit vector of [4 x i32]. The upper /// 64 bits of the result vector are set to zero. /// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. +/// /// \headerfile <x86intrin.h> /// /// This intrinsic corresponds to the <c> VCVTPD2DQ / CVTPD2DQ </c> instruction. @@ -1309,6 +1313,10 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvtpd_epi32(__m128d __a) { /// Converts the low-order element of a 128-bit vector of [2 x double] /// into a 32-bit signed integer value. /// +/// If the converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. +/// /// \headerfile <x86intrin.h> /// /// This intrinsic corresponds to the <c> VCVTSD2SI / CVTSD2SI </c> instruction. @@ -1394,12 +1402,13 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_cvtss_sd(__m128d __a, } /// Converts the two double-precision floating-point elements of a -/// 128-bit vector of [2 x double] into two signed 32-bit integer values, -/// returned in the lower 64 bits of a 128-bit vector of [4 x i32]. +/// 128-bit vector of [2 x double] into two signed truncated (rounded +/// toward zero) 32-bit integer values, returned in the lower 64 bits +/// of a 128-bit vector of [4 x i32]. /// -/// If the result of either conversion is inexact, the result is truncated -/// (rounded towards zero) regardless of the current MXCSR setting. The upper -/// 64 bits of the result vector are set to zero. +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// @@ -1415,7 +1424,11 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvttpd_epi32(__m128d __a) { } /// Converts the low-order element of a [2 x double] vector into a 32-bit -/// signed integer value, truncating the result when it is inexact. +/// signed truncated (rounded toward zero) integer value. +/// +/// If the converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// @@ -1434,6 +1447,10 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_cvttsd_si32(__m128d __a) { /// 128-bit vector of [2 x double] into two signed 32-bit integer values, /// returned in a 64-bit vector of [2 x i32]. /// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. +/// /// \headerfile <x86intrin.h> /// /// This intrinsic corresponds to the <c> CVTPD2PI </c> instruction. @@ -1446,11 +1463,12 @@ static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_cvtpd_pi32(__m128d __a) { } /// Converts the two double-precision floating-point elements of a -/// 128-bit vector of [2 x double] into two signed 32-bit integer values, -/// returned in a 64-bit vector of [2 x i32]. +/// 128-bit vector of [2 x double] into two signed truncated (rounded toward +/// zero) 32-bit integer values, returned in a 64-bit vector of [2 x i32]. /// -/// If the result of either conversion is inexact, the result is truncated -/// (rounded towards zero) regardless of the current MXCSR setting. +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// @@ -3216,7 +3234,11 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_cvtsi64_sd(__m128d __a, } /// Converts the first (lower) element of a vector of [2 x double] into a -/// 64-bit signed integer value, according to the current rounding mode. +/// 64-bit signed integer value. +/// +/// If the converted value does not fit in a 64-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// @@ -3231,7 +3253,11 @@ static __inline__ long long __DEFAULT_FN_ATTRS _mm_cvtsd_si64(__m128d __a) { } /// Converts the first (lower) element of a vector of [2 x double] into a -/// 64-bit signed integer value, truncating the result when it is inexact. +/// 64-bit signed truncated (rounded toward zero) integer value. +/// +/// If a converted value does not fit in a 64-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// @@ -3262,6 +3288,10 @@ static __inline__ __m128 __DEFAULT_FN_ATTRS _mm_cvtepi32_ps(__m128i __a) { /// Converts a vector of [4 x float] into a vector of [4 x i32]. /// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. +/// /// \headerfile <x86intrin.h> /// /// This intrinsic corresponds to the <c> VCVTPS2DQ / CVTPS2DQ </c> instruction. @@ -3274,8 +3304,12 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvtps_epi32(__m128 __a) { return (__m128i)__builtin_ia32_cvtps2dq((__v4sf)__a); } -/// Converts a vector of [4 x float] into a vector of [4 x i32], -/// truncating the result when it is inexact. +/// Converts a vector of [4 x float] into four signed truncated (rounded toward +/// zero) 32-bit integers, returned in a vector of [4 x i32]. +/// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// diff --git a/clang/lib/Headers/xmmintrin.h b/clang/lib/Headers/xmmintrin.h index 8e386a72cde7..b2c68c3b7be9 100644 --- a/clang/lib/Headers/xmmintrin.h +++ b/clang/lib/Headers/xmmintrin.h @@ -1333,6 +1333,10 @@ _mm_ucomineq_ss(__m128 __a, __m128 __b) /// Converts a float value contained in the lower 32 bits of a vector of /// [4 x float] into a 32-bit integer. /// +/// If the converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. +/// /// \headerfile <x86intrin.h> /// /// This intrinsic corresponds to the <c> VCVTSS2SI / CVTSS2SI </c> @@ -1351,6 +1355,10 @@ _mm_cvtss_si32(__m128 __a) /// Converts a float value contained in the lower 32 bits of a vector of /// [4 x float] into a 32-bit integer. /// +/// If the converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. +/// /// \headerfile <x86intrin.h> /// /// This intrinsic corresponds to the <c> VCVTSS2SI / CVTSS2SI </c> @@ -1371,6 +1379,10 @@ _mm_cvt_ss2si(__m128 __a) /// Converts a float value contained in the lower 32 bits of a vector of /// [4 x float] into a 64-bit integer. /// +/// If the converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. +/// /// \headerfile <x86intrin.h> /// /// This intrinsic corresponds to the <c> VCVTSS2SI / CVTSS2SI </c> @@ -1391,6 +1403,10 @@ _mm_cvtss_si64(__m128 __a) /// Converts two low-order float values in a 128-bit vector of /// [4 x float] into a 64-bit vector of [2 x i32]. /// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. +/// /// \headerfile <x86intrin.h> /// /// This intrinsic corresponds to the <c> CVTPS2PI </c> instruction. @@ -1407,6 +1423,10 @@ _mm_cvtps_pi32(__m128 __a) /// Converts two low-order float values in a 128-bit vector of /// [4 x float] into a 64-bit vector of [2 x i32]. /// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. +/// /// \headerfile <x86intrin.h> /// /// This intrinsic corresponds to the <c> CVTPS2PI </c> instruction. @@ -1420,9 +1440,12 @@ _mm_cvt_ps2pi(__m128 __a) return _mm_cvtps_pi32(__a); } -/// Converts a float value contained in the lower 32 bits of a vector of -/// [4 x float] into a 32-bit integer, truncating the result when it is -/// inexact. +/// Converts the lower (first) element of a vector of [4 x float] into a signed +/// truncated (rounded toward zero) 32-bit integer. +/// +/// If the converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// @@ -1439,9 +1462,12 @@ _mm_cvttss_si32(__m128 __a) return __builtin_ia32_cvttss2si((__v4sf)__a); } -/// Converts a float value contained in the lower 32 bits of a vector of -/// [4 x float] into a 32-bit integer, truncating the result when it is -/// inexact. +/// Converts the lower (first) element of a vector of [4 x float] into a signed +/// truncated (rounded toward zero) 32-bit integer. +/// +/// If the converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// @@ -1459,9 +1485,12 @@ _mm_cvtt_ss2si(__m128 __a) } #ifdef __x86_64__ -/// Converts a float value contained in the lower 32 bits of a vector of -/// [4 x float] into a 64-bit integer, truncating the result when it is -/// inexact. +/// Converts the lower (first) element of a vector of [4 x float] into a signed +/// truncated (rounded toward zero) 64-bit integer. +/// +/// If the converted value does not fit in a 64-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// @@ -1479,9 +1508,13 @@ _mm_cvttss_si64(__m128 __a) } #endif -/// Converts two low-order float values in a 128-bit vector of -/// [4 x float] into a 64-bit vector of [2 x i32], truncating the result -/// when it is inexact. +/// Converts the lower (first) two elements of a 128-bit vector of [4 x float] +/// into two signed truncated (rounded toward zero) 32-bit integers, +/// returned in a 64-bit vector of [2 x i32]. +/// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// @@ -1497,9 +1530,13 @@ _mm_cvttps_pi32(__m128 __a) return (__m64)__builtin_ia32_cvttps2pi((__v4sf)__a); } -/// Converts two low-order float values in a 128-bit vector of [4 x -/// float] into a 64-bit vector of [2 x i32], truncating the result when it -/// is inexact. +/// Converts the lower (first) two elements of a 128-bit vector of [4 x float] +/// into two signed truncated (rounded toward zero) 64-bit integers, +/// returned in a 64-bit vector of [2 x i32]. +/// +/// If a converted value does not fit in a 32-bit integer, raises a +/// floating-point invalid exception. If the exception is masked, returns +/// the most negative integer. /// /// \headerfile <x86intrin.h> /// -- GitLab From 3ff67d8c8069b9f42efcbe90ad7edeb6d8117a31 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi <1802579+farzonl@users.noreply.github.com> Date: Tue, 19 Mar 2024 15:04:12 -0400 Subject: [PATCH 123/307] [HLSL] Fix for build break introduced by #85662 (#85839) This change fixes a test case failure caused by pr #85662 --- clang/include/clang/AST/Type.h | 5 +++++ clang/lib/Sema/SemaChecking.cpp | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 10916053cdfb..be18535e3e4c 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2245,6 +2245,7 @@ public: bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 bool isFloat32Type() const; + bool isDoubleType() const; bool isBFloat16Type() const; bool isFloat128Type() const; bool isIbm128Type() const; @@ -7457,6 +7458,10 @@ inline bool Type::isFloat32Type() const { return isSpecificBuiltinType(BuiltinType::Float); } +inline bool Type::isDoubleType() const { + return isSpecificBuiltinType(BuiltinType::Double); +} + inline bool Type::isBFloat16Type() const { return isSpecificBuiltinType(BuiltinType::BFloat16); } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index f9112a29027a..ef3ab16ba29b 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5486,10 +5486,8 @@ bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) { bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) { auto checkDoubleVector = [](clang::QualType PassedType) -> bool { - if (const auto *VecTy = dyn_cast<VectorType>(PassedType)) { - clang::QualType BaseType = VecTy->getElementType(); - return !BaseType->isHalfType() && !BaseType->isFloat32Type(); - } + if (const auto *VecTy = PassedType->getAs<VectorType>()) + return VecTy->getElementType()->isDoubleType(); return false; }; return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy, -- GitLab From 0a40f5d1a05a4108b5d9febf3ea8df4c1244a340 Mon Sep 17 00:00:00 2001 From: Piotr Zegar <me@piotrzegar.pl> Date: Tue, 19 Mar 2024 20:13:20 +0100 Subject: [PATCH 124/307] [clang-tidy] Add support for lambdas in cppcoreguidelines-owning-memory (#77246) Implement proper support for lambdas and sub-functions/classes. Moved from https://reviews.llvm.org/D157285 Fixes: #59389 --- .../cppcoreguidelines/OwningMemoryCheck.cpp | 66 +++++++++-- clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../cppcoreguidelines/owning-memory.cpp | 106 ++++++++++++++++++ 3 files changed, 169 insertions(+), 7 deletions(-) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp index 9215b833573a..9b4d2ef99e5b 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp @@ -19,6 +19,17 @@ using namespace clang::ast_matchers::internal; namespace clang::tidy::cppcoreguidelines { +namespace { +AST_MATCHER_P(LambdaExpr, hasCallOperator, Matcher<CXXMethodDecl>, + InnerMatcher) { + return InnerMatcher.matches(*Node.getCallOperator(), Finder, Builder); +} + +AST_MATCHER_P(LambdaExpr, hasLambdaBody, Matcher<Stmt>, InnerMatcher) { + return InnerMatcher.matches(*Node.getBody(), Finder, Builder); +} +} // namespace + void OwningMemoryCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "LegacyResourceProducers", LegacyResourceProducers); Options.store(Opts, "LegacyResourceConsumers", LegacyResourceConsumers); @@ -55,6 +66,8 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) { CreatesLegacyOwner, LegacyOwnerCast); const auto ConsideredOwner = eachOf(IsOwnerType, CreatesOwner); + const auto ScopeDeclaration = anyOf(translationUnitDecl(), namespaceDecl(), + recordDecl(), functionDecl()); // Find delete expressions that delete non-owners. Finder->addMatcher( @@ -144,13 +157,51 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) { .bind("bad_owner_creation_parameter"))), this); + auto IsNotInSubLambda = stmt( + hasAncestor( + stmt(anyOf(equalsBoundNode("body"), lambdaExpr())).bind("scope")), + hasAncestor(stmt(equalsBoundNode("scope"), equalsBoundNode("body")))); + // Matching on functions, that return an owner/resource, but don't declare // their return type as owner. Finder->addMatcher( - functionDecl(hasDescendant(returnStmt(hasReturnValue(ConsideredOwner)) - .bind("bad_owner_return")), - unless(returns(qualType(hasDeclaration(OwnerDecl))))) - .bind("function_decl"), + functionDecl( + decl().bind("function_decl"), + hasBody( + stmt(stmt().bind("body"), + hasDescendant( + returnStmt(hasReturnValue(ConsideredOwner), + // Ignore sub-lambda expressions + IsNotInSubLambda, + // Ignore sub-functions + hasAncestor(functionDecl().bind("context")), + hasAncestor(functionDecl( + equalsBoundNode("context"), + equalsBoundNode("function_decl")))) + .bind("bad_owner_return")))), + returns(qualType(unless(hasDeclaration(OwnerDecl))).bind("result"))), + this); + + // Matching on lambdas, that return an owner/resource, but don't declare + // their return type as owner. + Finder->addMatcher( + lambdaExpr( + hasAncestor(decl(ScopeDeclaration).bind("scope-decl")), + hasLambdaBody( + stmt(stmt().bind("body"), + hasDescendant( + returnStmt( + hasReturnValue(ConsideredOwner), + // Ignore sub-lambdas + IsNotInSubLambda, + // Ignore sub-functions + hasAncestor(decl(ScopeDeclaration).bind("context")), + hasAncestor(decl(equalsBoundNode("context"), + equalsBoundNode("scope-decl")))) + .bind("bad_owner_return")))), + hasCallOperator(returns( + qualType(unless(hasDeclaration(OwnerDecl))).bind("result")))) + .bind("lambda"), this); // Match on classes that have an owner as member, but don't declare a @@ -329,7 +380,7 @@ bool OwningMemoryCheck::handleReturnValues(const BoundNodes &Nodes) { // Function return statements, that are owners/resources, but the function // declaration does not declare its return value as owner. const auto *BadReturnType = Nodes.getNodeAs<ReturnStmt>("bad_owner_return"); - const auto *Function = Nodes.getNodeAs<FunctionDecl>("function_decl"); + const auto *ResultType = Nodes.getNodeAs<QualType>("result"); // Function return values, that should be owners but aren't. if (BadReturnType) { @@ -338,8 +389,9 @@ bool OwningMemoryCheck::handleReturnValues(const BoundNodes &Nodes) { diag(BadReturnType->getBeginLoc(), "returning a newly created resource of " "type %0 or 'gsl::owner<>' from a " - "function whose return type is not 'gsl::owner<>'") - << Function->getReturnType() << BadReturnType->getSourceRange(); + "%select{function|lambda}1 whose return type is not 'gsl::owner<>'") + << *ResultType << (Nodes.getNodeAs<Expr>("lambda") != nullptr) + << BadReturnType->getSourceRange(); // FIXME: Rewrite the return type as 'gsl::owner<OriginalType>' return true; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 44680f79de6f..3e69d2eec942 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -165,6 +165,10 @@ Changes in existing checks giving false positives for deleted functions and fix false negative when some parameters are forwarded, but other aren't. +- Improved :doc:`cppcoreguidelines-owning-memory + <clang-tidy/checks/cppcoreguidelines/owning-memory>` check to properly handle + return type in lambdas and in nested functions. + - Cleaned up :doc:`cppcoreguidelines-prefer-member-initializer <clang-tidy/checks/cppcoreguidelines/prefer-member-initializer>` by removing enforcement of rule `C.48 diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/owning-memory.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/owning-memory.cpp index eb8ad1b8b879..574efe7bd914 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/owning-memory.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/owning-memory.cpp @@ -395,3 +395,109 @@ namespace PR63994 { // CHECK-NOTES: [[@LINE-1]]:5: warning: returning a newly created resource of type 'A *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>' } } + +namespace PR59389 { + struct S { + S(); + S(int); + + int value = 1; + }; + + void testLambdaInFunctionNegative() { + const auto MakeS = []() -> ::gsl::owner<S*> { + return ::gsl::owner<S*>{new S{}}; + }; + } + + void testLambdaInFunctionPositive() { + const auto MakeS = []() -> S* { + return ::gsl::owner<S*>{new S{}}; + // CHECK-NOTES: [[@LINE-1]]:7: warning: returning a newly created resource of type 'S *' or 'gsl::owner<>' from a lambda whose return type is not 'gsl::owner<>' + }; + } + + void testFunctionInFunctionNegative() { + struct C { + ::gsl::owner<S*> test() { + return ::gsl::owner<S*>{new S{}}; + } + }; + } + + void testFunctionInFunctionPositive() { + struct C { + S* test() { + return ::gsl::owner<S*>{new S{}}; + // CHECK-NOTES: [[@LINE-1]]:9: warning: returning a newly created resource of type 'S *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>' + } + }; + } + + ::gsl::owner<S*> testReverseLambdaNegative() { + const auto MakeI = [] -> int { return 5; }; + return ::gsl::owner<S*>{new S(MakeI())}; + } + + S* testReverseLambdaPositive() { + const auto MakeI = [] -> int { return 5; }; + return ::gsl::owner<S*>{new S(MakeI())}; + // CHECK-NOTES: [[@LINE-1]]:5: warning: returning a newly created resource of type 'S *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>' + } + + ::gsl::owner<S*> testReverseFunctionNegative() { + struct C { + int test() { return 5; } + }; + return ::gsl::owner<S*>{new S(C().test())}; + } + + S* testReverseFunctionPositive() { + struct C { + int test() { return 5; } + }; + return ::gsl::owner<S*>{new S(C().test())}; + // CHECK-NOTES: [[@LINE-1]]:5: warning: returning a newly created resource of type 'S *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>' + } + + void testLambdaInLambdaNegative() { + const auto MakeS = []() -> ::gsl::owner<S*> { + const auto MakeI = []() -> int { return 5; }; + return ::gsl::owner<S*>{new S(MakeI())}; + }; + } + + void testLambdaInLambdaPositive() { + const auto MakeS = []() -> S* { + const auto MakeI = []() -> int { return 5; }; + return ::gsl::owner<S*>{new S(MakeI())}; + // CHECK-NOTES: [[@LINE-1]]:7: warning: returning a newly created resource of type 'S *' or 'gsl::owner<>' from a lambda whose return type is not 'gsl::owner<>' + }; + } + + void testLambdaInLambdaWithDoubleReturns() { + const auto MakeS = []() -> S* { + const auto MakeS2 = []() -> S* { + return ::gsl::owner<S*>{new S(1)}; + // CHECK-NOTES: [[@LINE-1]]:9: warning: returning a newly created resource of type 'S *' or 'gsl::owner<>' from a lambda whose return type is not 'gsl::owner<>' [cppcoreguidelines-owning-memory] + }; + return ::gsl::owner<S*>{new S(2)}; + // CHECK-NOTES: [[@LINE-1]]:7: warning: returning a newly created resource of type 'S *' or 'gsl::owner<>' from a lambda whose return type is not 'gsl::owner<>' + }; + } + + void testReverseLambdaInLambdaNegative() { + const auto MakeI = []() -> int { + const auto MakeS = []() -> ::gsl::owner<S*> { return new S(); }; + return 5; + }; + } + + void testReverseLambdaInLambdaPositive() { + const auto MakeI = []() -> int { + const auto MakeS = []() -> S* { return new S(); }; + // CHECK-NOTES: [[@LINE-1]]:39: warning: returning a newly created resource of type 'S *' or 'gsl::owner<>' from a lambda whose return type is not 'gsl::owner<>' + return 5; + }; + } +} -- GitLab From 28c1279db3541bc7b246fd9da0da3da4e09f0eed Mon Sep 17 00:00:00 2001 From: Piotr Zegar <piotr.zegar@nokia.com> Date: Tue, 19 Mar 2024 20:15:08 +0100 Subject: [PATCH 125/307] [clang-tidy] Add bugprone-suspicious-stringview-data-usage check (#83716) This check identifies suspicious usages of std::string_view::data() that could lead to reading out-of-bounds data due to inadequate or incorrect string null termination. Closes #80854 --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt | 1 + .../SuspiciousStringviewDataUsageCheck.cpp | 97 +++++++++++++++++++ .../SuspiciousStringviewDataUsageCheck.h | 38 ++++++++ clang-tools-extra/docs/ReleaseNotes.rst | 7 ++ .../suspicious-stringview-data-usage.rst | 58 +++++++++++ .../docs/clang-tidy/checks/list.rst | 1 + .../clang-tidy/checkers/Inputs/Headers/string | 7 ++ .../suspicious-stringview-data-usage.cpp | 56 +++++++++++ 9 files changed, 268 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-stringview-data-usage.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-stringview-data-usage.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index e518a64abc52..2931325d8b57 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -73,6 +73,7 @@ #include "SuspiciousReallocUsageCheck.h" #include "SuspiciousSemicolonCheck.h" #include "SuspiciousStringCompareCheck.h" +#include "SuspiciousStringviewDataUsageCheck.h" #include "SwappedArgumentsCheck.h" #include "SwitchMissingDefaultCaseCheck.h" #include "TerminatingContinueCheck.h" @@ -218,6 +219,8 @@ public: "bugprone-suspicious-semicolon"); CheckFactories.registerCheck<SuspiciousStringCompareCheck>( "bugprone-suspicious-string-compare"); + CheckFactories.registerCheck<SuspiciousStringviewDataUsageCheck>( + "bugprone-suspicious-stringview-data-usage"); CheckFactories.registerCheck<SwappedArgumentsCheck>( "bugprone-swapped-arguments"); CheckFactories.registerCheck<TerminatingContinueCheck>( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 638fba03a435..081ba67efe15 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -26,6 +26,7 @@ add_clang_library(clangTidyBugproneModule ImplicitWideningOfMultiplicationResultCheck.cpp InaccurateEraseCheck.cpp IncorrectEnableIfCheck.cpp + SuspiciousStringviewDataUsageCheck.cpp SwitchMissingDefaultCaseCheck.cpp IncDecInConditionsCheck.cpp IncorrectRoundingsCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.cpp new file mode 100644 index 000000000000..8f4b0c5e0dce --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.cpp @@ -0,0 +1,97 @@ +//===--- SuspiciousStringviewDataUsageCheck.cpp - clang-tidy --------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "SuspiciousStringviewDataUsageCheck.h" +#include "../utils/Matchers.h" +#include "../utils/OptionsUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +SuspiciousStringviewDataUsageCheck::SuspiciousStringviewDataUsageCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + StringViewTypes(utils::options::parseStringList(Options.get( + "StringViewTypes", "::std::basic_string_view;::llvm::StringRef"))), + AllowedCallees( + utils::options::parseStringList(Options.get("AllowedCallees", ""))) {} + +void SuspiciousStringviewDataUsageCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "StringViewTypes", + utils::options::serializeStringList(StringViewTypes)); + Options.store(Opts, "AllowedCallees", + utils::options::serializeStringList(AllowedCallees)); +} + +bool SuspiciousStringviewDataUsageCheck::isLanguageVersionSupported( + const LangOptions &LangOpts) const { + return LangOpts.CPlusPlus; +} + +std::optional<TraversalKind> +SuspiciousStringviewDataUsageCheck::getCheckTraversalKind() const { + return TK_AsIs; +} + +void SuspiciousStringviewDataUsageCheck::registerMatchers(MatchFinder *Finder) { + + auto AncestorCall = anyOf( + cxxConstructExpr(), callExpr(unless(cxxOperatorCallExpr())), lambdaExpr(), + initListExpr( + hasType(qualType(hasCanonicalType(hasDeclaration(recordDecl())))))); + + auto DataMethod = + cxxMethodDecl(hasName("data"), + ofClass(matchers::matchesAnyListedName(StringViewTypes))); + + auto SizeCall = cxxMemberCallExpr( + callee(cxxMethodDecl(hasAnyName("size", "length"))), + on(ignoringParenImpCasts( + matchers::isStatementIdenticalToBoundNode("self")))); + + auto DescendantSizeCall = expr(hasDescendant( + expr(SizeCall, hasAncestor(expr(AncestorCall).bind("ancestor-size")), + hasAncestor(expr(equalsBoundNode("parent"), + equalsBoundNode("ancestor-size")))))); + + Finder->addMatcher( + cxxMemberCallExpr( + on(ignoringParenImpCasts(expr().bind("self"))), callee(DataMethod), + expr().bind("data-call"), + hasParent(expr(anyOf( + invocation( + expr().bind("parent"), unless(cxxOperatorCallExpr()), + hasAnyArgument( + ignoringParenImpCasts(equalsBoundNode("data-call"))), + unless(hasAnyArgument(ignoringParenImpCasts(SizeCall))), + unless(hasAnyArgument(DescendantSizeCall)), + hasDeclaration(namedDecl( + unless(matchers::matchesAnyListedName(AllowedCallees))))), + initListExpr(expr().bind("parent"), + hasType(qualType(hasCanonicalType(hasDeclaration( + recordDecl(unless(matchers::matchesAnyListedName( + AllowedCallees))))))), + unless(DescendantSizeCall)))))), + this); +} + +void SuspiciousStringviewDataUsageCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *DataCallExpr = + Result.Nodes.getNodeAs<CXXMemberCallExpr>("data-call"); + diag(DataCallExpr->getExprLoc(), + "result of a `data()` call may not be null terminated, provide size " + "information to the callee to prevent potential issues") + << DataCallExpr->getCallee()->getSourceRange(); +} + +} // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.h b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.h new file mode 100644 index 000000000000..31eca0a48722 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.h @@ -0,0 +1,38 @@ +//===--- SuspiciousStringviewDataUsageCheck.h - clang-tidy -------//C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSSTRINGVIEWDATAUSAGECHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSSTRINGVIEWDATAUSAGECHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::bugprone { + +/// Identifies suspicious usages of std::string_view::data() that could lead to +/// reading out-of-bounds data due to inadequate or incorrect string null +/// termination. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/suspicious-stringview-data-usage.html +class SuspiciousStringviewDataUsageCheck : public ClangTidyCheck { +public: + SuspiciousStringviewDataUsageCheck(StringRef Name, ClangTidyContext *Context); + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override; + std::optional<TraversalKind> getCheckTraversalKind() const override; + +private: + std::vector<llvm::StringRef> StringViewTypes; + std::vector<llvm::StringRef> AllowedCallees; +}; + +} // namespace clang::tidy::bugprone + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSSTRINGVIEWDATAUSAGECHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 3e69d2eec942..a604e9276668 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -110,6 +110,13 @@ New checks Detects error-prone Curiously Recurring Template Pattern usage, when the CRTP can be constructed outside itself and the derived class. +- New :doc:`bugprone-suspicious-stringview-data-usage + <clang-tidy/checks/bugprone/suspicious-stringview-data-usage>` check. + + Identifies suspicious usages of ``std::string_view::data()`` that could lead + to reading out-of-bounds data due to inadequate or incorrect string null + termination. + - New :doc:`modernize-use-designated-initializers <clang-tidy/checks/modernize/use-designated-initializers>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-stringview-data-usage.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-stringview-data-usage.rst new file mode 100644 index 000000000000..9b38d8360181 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-stringview-data-usage.rst @@ -0,0 +1,58 @@ +.. title:: clang-tidy - bugprone-suspicious-stringview-data-usage + +bugprone-suspicious-stringview-data-usage +========================================= + +Identifies suspicious usages of ``std::string_view::data()`` that could lead to +reading out-of-bounds data due to inadequate or incorrect string null +termination. + +It warns when the result of ``data()`` is passed to a constructor or function +without also passing the corresponding result of ``size()`` or ``length()`` +member function. Such usage can lead to unintended behavior, particularly when +assuming the data pointed to by ``data()`` is null-terminated. + +The absence of a ``c_str()`` method in ``std::string_view`` often leads +developers to use ``data()`` as a substitute, especially when interfacing with +C APIs that expect null-terminated strings. However, since ``data()`` does not +guarantee null termination, this can result in unintended behavior if the API +relies on proper null termination for correct string interpretation. + +In today's programming landscape, this scenario can occur when implicitly +converting an ``std::string_view`` to an ``std::string``. Since the constructor +in ``std::string`` designed for string-view-like objects is ``explicit``, +attempting to pass an ``std::string_view`` to a function expecting an +``std::string`` will result in a compilation error. As a workaround, developers +may be tempted to utilize the ``.data()`` method to achieve compilation, +introducing potential risks. + +For instance: + +.. code-block:: c++ + + void printString(const std::string& str) { + std::cout << "String: " << str << std::endl; + } + + void something(std::string_view sv) { + printString(sv.data()); + } + +In this example, directly passing ``sv`` to the ``printString`` function would +lead to a compilation error due to the explicit nature of the ``std::string`` +constructor. Consequently, developers might opt for ``sv.data()`` to resolve the +compilation error, albeit introducing potential hazards as discussed. + +.. option:: StringViewTypes + + Option allows users to specify custom string view-like types for analysis. It + accepts a semicolon-separated list of type names or regular expressions + matching these types. Default value is: + `::std::basic_string_view;::llvm::StringRef`. + +.. option:: AllowedCallees + + Specifies methods, functions, or classes where the result of ``.data()`` is + passed to. Allows to exclude such calls from the analysis. Accepts a + semicolon-separated list of names or regular expressions matching these + entities. Default value is: empty string. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index d03e7af688f0..79e81dd174e4 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -139,6 +139,7 @@ Clang-Tidy Checks :doc:`bugprone-suspicious-realloc-usage <bugprone/suspicious-realloc-usage>`, :doc:`bugprone-suspicious-semicolon <bugprone/suspicious-semicolon>`, "Yes" :doc:`bugprone-suspicious-string-compare <bugprone/suspicious-string-compare>`, "Yes" + :doc:`bugprone-suspicious-stringview-data-usage <bugprone/suspicious-stringview-data-usage>`, :doc:`bugprone-swapped-arguments <bugprone/swapped-arguments>`, "Yes" :doc:`bugprone-switch-missing-default-case <bugprone/switch-missing-default-case>`, :doc:`bugprone-terminating-continue <bugprone/terminating-continue>`, "Yes" diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string index f2e4159a2245..28e2b4a231e5 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string +++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string @@ -24,6 +24,7 @@ struct basic_string { basic_string(); basic_string(const C *p, const A &a = A()); basic_string(const C *p, size_type count); + basic_string(const C *b, const C *e); ~basic_string(); @@ -85,6 +86,12 @@ struct basic_string_view { const C *str; constexpr basic_string_view(const C* s) : str(s) {} + const C *data() const; + + bool empty() const; + size_type size() const; + size_type length() const; + size_type find(_Type v, size_type pos = 0) const; size_type find(C ch, size_type pos = 0) const; size_type find(const C* s, size_type pos, size_type count) const; diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-stringview-data-usage.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-stringview-data-usage.cpp new file mode 100644 index 000000000000..8072d60a2f47 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-stringview-data-usage.cpp @@ -0,0 +1,56 @@ +// RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-suspicious-stringview-data-usage %t -- -- -isystem %clang_tidy_headers +#include <string> + +struct View { + const char* str; +}; + +struct Pair { + const char* begin; + const char* end; +}; + +struct ViewWithSize { + const char* str; + std::string_view::size_type size; +}; + +void something(const char*); +void something(const char*, unsigned); +void something(const char*, unsigned, const char*); +void something_str(std::string, unsigned); + +void invalid(std::string_view sv, std::string_view sv2) { + std::string s(sv.data()); +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: result of a `data()` call may not be null terminated, provide size information to the callee to prevent potential issues + std::string si{sv.data()}; +// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: result of a `data()` call may not be null terminated, provide size information to the callee to prevent potential issues + std::string_view s2(sv.data()); +// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: result of a `data()` call may not be null terminated, provide size information to the callee to prevent potential issues + something(sv.data()); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: result of a `data()` call may not be null terminated, provide size information to the callee to prevent potential issues + something(sv.data(), sv.size(), sv2.data()); +// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: result of a `data()` call may not be null terminated, provide size information to the callee to prevent potential issues + something_str(sv.data(), sv.size()); +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: result of a `data()` call may not be null terminated, provide size information to the callee to prevent potential issues + View view{sv.data()}; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: result of a `data()` call may not be null terminated, provide size information to the callee to prevent potential issues +} + +void valid(std::string_view sv) { + std::string s1(sv.data(), sv.data() + sv.size()); + std::string s2(sv.data(), sv.data() + sv.length()); + std::string s3(sv.data(), sv.size() + sv.data()); + std::string s4(sv.data(), sv.length() + sv.data()); + std::string s5(sv.data(), sv.size()); + std::string s6(sv.data(), sv.length()); + something(sv.data(), sv.size()); + something(sv.data(), sv.length()); + ViewWithSize view1{sv.data(), sv.size()}; + ViewWithSize view2{sv.data(), sv.length()}; + Pair view3{sv.data(), sv.data() + sv.size()}; + Pair view4{sv.data(), sv.data() + sv.length()}; + Pair view5{sv.data(), sv.size() + sv.data()}; + Pair view6{sv.data(), sv.length() + sv.data()}; + const char* str{sv.data()}; +} -- GitLab From a6e231bb2a7924f4269e6735d29a54b2318cd16c Mon Sep 17 00:00:00 2001 From: alexfh <alexfh@google.com> Date: Tue, 19 Mar 2024 20:15:30 +0100 Subject: [PATCH 126/307] Revert "[Float2Int] Resolve FIXME: Pick the smallest legal type that fits" (#85843) Reverts llvm/llvm-project#79158, which causes a miscompile. See https://github.com/llvm/llvm-project/pull/79158#issuecomment-2007842032 --- .../llvm/Transforms/Scalar/Float2Int.h | 2 +- llvm/lib/Transforms/Scalar/Float2Int.cpp | 29 +- llvm/test/Transforms/Float2Int/basic.ll | 251 ++++-------------- 3 files changed, 68 insertions(+), 214 deletions(-) diff --git a/llvm/include/llvm/Transforms/Scalar/Float2Int.h b/llvm/include/llvm/Transforms/Scalar/Float2Int.h index 337e229efcf3..83be329bed60 100644 --- a/llvm/include/llvm/Transforms/Scalar/Float2Int.h +++ b/llvm/include/llvm/Transforms/Scalar/Float2Int.h @@ -44,7 +44,7 @@ private: std::optional<ConstantRange> calcRange(Instruction *I); void walkBackwards(); void walkForwards(); - bool validateAndTransform(const DataLayout &DL); + bool validateAndTransform(); Value *convert(Instruction *I, Type *ToTy); void cleanup(); diff --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp index 6ad4be169b58..ccca8bcc1a56 100644 --- a/llvm/lib/Transforms/Scalar/Float2Int.cpp +++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp @@ -311,7 +311,7 @@ void Float2IntPass::walkForwards() { } // If there is a valid transform to be done, do it. -bool Float2IntPass::validateAndTransform(const DataLayout &DL) { +bool Float2IntPass::validateAndTransform() { bool MadeChange = false; // Iterate over every disjoint partition of the def-use graph. @@ -376,24 +376,16 @@ bool Float2IntPass::validateAndTransform(const DataLayout &DL) { LLVM_DEBUG(dbgs() << "F2I: Value not guaranteed to be representable!\n"); continue; } - - // OK, R is known to be representable. - // Pick the smallest legal type that will fit. - Type *Ty = DL.getSmallestLegalIntType(*Ctx, MinBW); - if (!Ty) { - // Every supported target supports 64-bit and 32-bit integers, - // so fallback to a 32 or 64-bit integer if the value fits. - if (MinBW <= 32) { - Ty = Type::getInt32Ty(*Ctx); - } else if (MinBW <= 64) { - Ty = Type::getInt64Ty(*Ctx); - } else { - LLVM_DEBUG(dbgs() << "F2I: Value requires more than bits to represent " - "than the target supports!\n"); - continue; - } + if (MinBW > 64) { + LLVM_DEBUG( + dbgs() << "F2I: Value requires more than 64 bits to represent!\n"); + continue; } + // OK, R is known to be representable. Now pick a type for it. + // FIXME: Pick the smallest legal type that will fit. + Type *Ty = (MinBW > 32) ? Type::getInt64Ty(*Ctx) : Type::getInt32Ty(*Ctx); + for (auto MI = ECs.member_begin(It), ME = ECs.member_end(); MI != ME; ++MI) convert(*MI, Ty); @@ -499,8 +491,7 @@ bool Float2IntPass::runImpl(Function &F, const DominatorTree &DT) { walkBackwards(); walkForwards(); - const DataLayout &DL = F.getParent()->getDataLayout(); - bool Modified = validateAndTransform(DL); + bool Modified = validateAndTransform(); if (Modified) cleanup(); return Modified; diff --git a/llvm/test/Transforms/Float2Int/basic.ll b/llvm/test/Transforms/Float2Int/basic.ll index a454b773f4eb..2854a83179b7 100644 --- a/llvm/test/Transforms/Float2Int/basic.ll +++ b/llvm/test/Transforms/Float2Int/basic.ll @@ -1,29 +1,16 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes=float2int -S | FileCheck %s -check-prefixes=CHECK,NONE -; RUN: opt < %s -passes=float2int -S --data-layout="n64" | FileCheck %s -check-prefixes=CHECK,ONLY64 -; RUN: opt < %s -passes=float2int -S --data-layout="n8:16:32:64"| FileCheck %s -check-prefixes=CHECK,MULTIPLE +; RUN: opt < %s -passes='float2int' -S | FileCheck %s ; ; Positive tests ; define i16 @simple1(i8 %a) { -; NONE-LABEL: @simple1( -; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; NONE-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 1 -; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 -; NONE-NEXT: ret i16 [[TMP2]] -; -; ONLY64-LABEL: @simple1( -; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 -; ONLY64-NEXT: [[T21:%.*]] = add i64 [[TMP1]], 1 -; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i16 -; ONLY64-NEXT: ret i16 [[TMP2]] -; -; MULTIPLE-LABEL: @simple1( -; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 -; MULTIPLE-NEXT: [[T21:%.*]] = add i16 [[TMP1]], 1 -; MULTIPLE-NEXT: ret i16 [[T21]] +; CHECK-LABEL: @simple1( +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; CHECK-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 +; CHECK-NEXT: ret i16 [[TMP2]] ; %t1 = uitofp i8 %a to float %t2 = fadd float %t1, 1.0 @@ -32,23 +19,11 @@ define i16 @simple1(i8 %a) { } define i8 @simple2(i8 %a) { -; NONE-LABEL: @simple2( -; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; NONE-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1 -; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i8 -; NONE-NEXT: ret i8 [[TMP2]] -; -; ONLY64-LABEL: @simple2( -; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 -; ONLY64-NEXT: [[T21:%.*]] = sub i64 [[TMP1]], 1 -; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i8 -; ONLY64-NEXT: ret i8 [[TMP2]] -; -; MULTIPLE-LABEL: @simple2( -; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 -; MULTIPLE-NEXT: [[T21:%.*]] = sub i16 [[TMP1]], 1 -; MULTIPLE-NEXT: [[TMP2:%.*]] = trunc i16 [[T21]] to i8 -; MULTIPLE-NEXT: ret i8 [[TMP2]] +; CHECK-LABEL: @simple2( +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; CHECK-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i8 +; CHECK-NEXT: ret i8 [[TMP2]] ; %t1 = uitofp i8 %a to float %t2 = fsub float %t1, 1.0 @@ -57,22 +32,10 @@ define i8 @simple2(i8 %a) { } define i32 @simple3(i8 %a) { -; NONE-LABEL: @simple3( -; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; NONE-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1 -; NONE-NEXT: ret i32 [[T21]] -; -; ONLY64-LABEL: @simple3( -; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 -; ONLY64-NEXT: [[T21:%.*]] = sub i64 [[TMP1]], 1 -; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i32 -; ONLY64-NEXT: ret i32 [[TMP2]] -; -; MULTIPLE-LABEL: @simple3( -; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 -; MULTIPLE-NEXT: [[T21:%.*]] = sub i16 [[TMP1]], 1 -; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i16 [[T21]] to i32 -; MULTIPLE-NEXT: ret i32 [[TMP2]] +; CHECK-LABEL: @simple3( +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; CHECK-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1 +; CHECK-NEXT: ret i32 [[T21]] ; %t1 = uitofp i8 %a to float %t2 = fsub float %t1, 1.0 @@ -81,23 +44,11 @@ define i32 @simple3(i8 %a) { } define i1 @cmp(i8 %a, i8 %b) { -; NONE-LABEL: @cmp( -; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 -; NONE-NEXT: [[T31:%.*]] = icmp slt i32 [[TMP1]], [[TMP2]] -; NONE-NEXT: ret i1 [[T31]] -; -; ONLY64-LABEL: @cmp( -; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 -; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 -; ONLY64-NEXT: [[T31:%.*]] = icmp slt i64 [[TMP1]], [[TMP2]] -; ONLY64-NEXT: ret i1 [[T31]] -; -; MULTIPLE-LABEL: @cmp( -; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 -; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i16 -; MULTIPLE-NEXT: [[T31:%.*]] = icmp slt i16 [[TMP1]], [[TMP2]] -; MULTIPLE-NEXT: ret i1 [[T31]] +; CHECK-LABEL: @cmp( +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 +; CHECK-NEXT: [[T31:%.*]] = icmp slt i32 [[TMP1]], [[TMP2]] +; CHECK-NEXT: ret i1 [[T31]] ; %t1 = uitofp i8 %a to float %t2 = uitofp i8 %b to float @@ -119,27 +70,12 @@ define i32 @simple4(i32 %a) { } define i32 @simple5(i8 %a, i8 %b) { -; NONE-LABEL: @simple5( -; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 -; NONE-NEXT: [[T31:%.*]] = add i32 [[TMP1]], 1 -; NONE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] -; NONE-NEXT: ret i32 [[T42]] -; -; ONLY64-LABEL: @simple5( -; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 -; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 -; ONLY64-NEXT: [[T31:%.*]] = add i64 [[TMP1]], 1 -; ONLY64-NEXT: [[T42:%.*]] = mul i64 [[T31]], [[TMP2]] -; ONLY64-NEXT: [[TMP3:%.*]] = trunc i64 [[T42]] to i32 -; ONLY64-NEXT: ret i32 [[TMP3]] -; -; MULTIPLE-LABEL: @simple5( -; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 -; MULTIPLE-NEXT: [[T31:%.*]] = add i32 [[TMP1]], 1 -; MULTIPLE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] -; MULTIPLE-NEXT: ret i32 [[T42]] +; CHECK-LABEL: @simple5( +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 +; CHECK-NEXT: [[T31:%.*]] = add i32 [[TMP1]], 1 +; CHECK-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] +; CHECK-NEXT: ret i32 [[T42]] ; %t1 = uitofp i8 %a to float %t2 = uitofp i8 %b to float @@ -150,27 +86,12 @@ define i32 @simple5(i8 %a, i8 %b) { } define i32 @simple6(i8 %a, i8 %b) { -; NONE-LABEL: @simple6( -; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 -; NONE-NEXT: [[T31:%.*]] = sub i32 0, [[TMP1]] -; NONE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] -; NONE-NEXT: ret i32 [[T42]] -; -; ONLY64-LABEL: @simple6( -; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 -; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 -; ONLY64-NEXT: [[T31:%.*]] = sub i64 0, [[TMP1]] -; ONLY64-NEXT: [[T42:%.*]] = mul i64 [[T31]], [[TMP2]] -; ONLY64-NEXT: [[TMP3:%.*]] = trunc i64 [[T42]] to i32 -; ONLY64-NEXT: ret i32 [[TMP3]] -; -; MULTIPLE-LABEL: @simple6( -; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 -; MULTIPLE-NEXT: [[T31:%.*]] = sub i32 0, [[TMP1]] -; MULTIPLE-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] -; MULTIPLE-NEXT: ret i32 [[T42]] +; CHECK-LABEL: @simple6( +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 +; CHECK-NEXT: [[T31:%.*]] = sub i32 0, [[TMP1]] +; CHECK-NEXT: [[T42:%.*]] = mul i32 [[T31]], [[TMP2]] +; CHECK-NEXT: ret i32 [[T42]] ; %t1 = uitofp i8 %a to float %t2 = uitofp i8 %b to float @@ -184,37 +105,15 @@ define i32 @simple6(i8 %a, i8 %b) { ; cause failure of the other. define i32 @multi1(i8 %a, i8 %b, i8 %c, float %d) { -; NONE-LABEL: @multi1( -; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; NONE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 -; NONE-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float -; NONE-NEXT: [[X1:%.*]] = add i32 [[TMP1]], [[TMP2]] -; NONE-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] -; NONE-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 -; NONE-NEXT: [[R:%.*]] = add i32 [[X1]], [[W]] -; NONE-NEXT: ret i32 [[R]] -; -; ONLY64-LABEL: @multi1( -; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 -; ONLY64-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i64 -; ONLY64-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float -; ONLY64-NEXT: [[X1:%.*]] = add i64 [[TMP1]], [[TMP2]] -; ONLY64-NEXT: [[TMP3:%.*]] = trunc i64 [[X1]] to i32 -; ONLY64-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] -; ONLY64-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 -; ONLY64-NEXT: [[R:%.*]] = add i32 [[TMP3]], [[W]] -; ONLY64-NEXT: ret i32 [[R]] -; -; MULTIPLE-LABEL: @multi1( -; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 -; MULTIPLE-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i16 -; MULTIPLE-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float -; MULTIPLE-NEXT: [[X1:%.*]] = add i16 [[TMP1]], [[TMP2]] -; MULTIPLE-NEXT: [[TMP3:%.*]] = zext i16 [[X1]] to i32 -; MULTIPLE-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] -; MULTIPLE-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 -; MULTIPLE-NEXT: [[R:%.*]] = add i32 [[TMP3]], [[W]] -; MULTIPLE-NEXT: ret i32 [[R]] +; CHECK-LABEL: @multi1( +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32 +; CHECK-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float +; CHECK-NEXT: [[X1:%.*]] = add i32 [[TMP1]], [[TMP2]] +; CHECK-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]] +; CHECK-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32 +; CHECK-NEXT: [[R:%.*]] = add i32 [[X1]], [[W]] +; CHECK-NEXT: ret i32 [[R]] ; %fa = uitofp i8 %a to float %fb = uitofp i8 %b to float @@ -228,22 +127,11 @@ define i32 @multi1(i8 %a, i8 %b, i8 %c, float %d) { } define i16 @simple_negzero(i8 %a) { -; NONE-LABEL: @simple_negzero( -; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; NONE-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 0 -; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 -; NONE-NEXT: ret i16 [[TMP2]] -; -; ONLY64-LABEL: @simple_negzero( -; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 -; ONLY64-NEXT: [[T21:%.*]] = add i64 [[TMP1]], 0 -; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i16 -; ONLY64-NEXT: ret i16 [[TMP2]] -; -; MULTIPLE-LABEL: @simple_negzero( -; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 -; MULTIPLE-NEXT: [[T21:%.*]] = add i16 [[TMP1]], 0 -; MULTIPLE-NEXT: ret i16 [[T21]] +; CHECK-LABEL: @simple_negzero( +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; CHECK-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 0 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 +; CHECK-NEXT: ret i16 [[TMP2]] ; %t1 = uitofp i8 %a to float %t2 = fadd fast float %t1, -0.0 @@ -252,26 +140,12 @@ define i16 @simple_negzero(i8 %a) { } define i32 @simple_negative(i8 %call) { -; NONE-LABEL: @simple_negative( -; NONE-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i32 -; NONE-NEXT: [[MUL1:%.*]] = mul i32 [[TMP1]], -3 -; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[MUL1]] to i8 -; NONE-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 -; NONE-NEXT: ret i32 [[CONV3]] -; -; ONLY64-LABEL: @simple_negative( -; ONLY64-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i64 -; ONLY64-NEXT: [[MUL1:%.*]] = mul i64 [[TMP1]], -3 -; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[MUL1]] to i8 -; ONLY64-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 -; ONLY64-NEXT: ret i32 [[CONV3]] -; -; MULTIPLE-LABEL: @simple_negative( -; MULTIPLE-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i16 -; MULTIPLE-NEXT: [[MUL1:%.*]] = mul i16 [[TMP1]], -3 -; MULTIPLE-NEXT: [[TMP2:%.*]] = trunc i16 [[MUL1]] to i8 -; MULTIPLE-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 -; MULTIPLE-NEXT: ret i32 [[CONV3]] +; CHECK-LABEL: @simple_negative( +; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i32 +; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[TMP1]], -3 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[MUL1]] to i8 +; CHECK-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32 +; CHECK-NEXT: ret i32 [[CONV3]] ; %conv1 = sitofp i8 %call to float %mul = fmul float %conv1, -3.000000e+00 @@ -281,22 +155,11 @@ define i32 @simple_negative(i8 %call) { } define i16 @simple_fneg(i8 %a) { -; NONE-LABEL: @simple_fneg( -; NONE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 -; NONE-NEXT: [[T21:%.*]] = sub i32 0, [[TMP1]] -; NONE-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 -; NONE-NEXT: ret i16 [[TMP2]] -; -; ONLY64-LABEL: @simple_fneg( -; ONLY64-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i64 -; ONLY64-NEXT: [[T21:%.*]] = sub i64 0, [[TMP1]] -; ONLY64-NEXT: [[TMP2:%.*]] = trunc i64 [[T21]] to i16 -; ONLY64-NEXT: ret i16 [[TMP2]] -; -; MULTIPLE-LABEL: @simple_fneg( -; MULTIPLE-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16 -; MULTIPLE-NEXT: [[T21:%.*]] = sub i16 0, [[TMP1]] -; MULTIPLE-NEXT: ret i16 [[T21]] +; CHECK-LABEL: @simple_fneg( +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32 +; CHECK-NEXT: [[T21:%.*]] = sub i32 0, [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16 +; CHECK-NEXT: ret i16 [[TMP2]] ; %t1 = uitofp i8 %a to float %t2 = fneg fast float %t1 -- GitLab From c2c1e6ee4ce0df3d000ba880fa6cf58441da6462 Mon Sep 17 00:00:00 2001 From: Florian Hahn <flo@fhahn.com> Date: Tue, 19 Mar 2024 20:16:18 +0100 Subject: [PATCH 127/307] [VPlan] Replace disjoint or with add instead of dropping disjoint. (#83821) Dropping disjoint from an OR may yield incorrect results, as some analysis may have converted it to an Add implicitly (e.g. SCEV used for dependence analysis). Instead, replace it with an equivalent Add. This is possible as all users of the disjoint OR only access lanes where the operands are disjoint or poison otherwise. Note that replacing all disjoint ORs with ADDs instead of dropping the flags is not strictly necessary. It is only needed for disjoint ORs that SCEV treated as ADDs, but those are not tracked. There are other places that may drop poison-generating flags; those likely need similar treatment. Fixes https://github.com/llvm/llvm-project/issues/81872 PR: https://github.com/llvm/llvm-project/pull/83821 --- .../Vectorize/LoopVectorizationPlanner.h | 3 +++ llvm/lib/Transforms/Vectorize/VPlan.h | 6 ++++++ .../Transforms/Vectorize/VPlanPatternMatch.h | 5 +++++ .../Transforms/Vectorize/VPlanTransforms.cpp | 17 +++++++++++++++++ .../Transforms/LoopVectorize/X86/pr81872.ll | 2 +- 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h index e86705e89889..5d03b66b0ce3 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h +++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h @@ -68,6 +68,9 @@ class VPBuilder { public: VPBuilder() = default; VPBuilder(VPBasicBlock *InsertBB) { setInsertPoint(InsertBB); } + VPBuilder(VPRecipeBase *InsertPt) { + setInsertPoint(InsertPt->getParent(), InsertPt->getIterator()); + } /// Clear the insertion point: created instructions will not be inserted into /// a block. diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index d77c7554d50e..d720f17a3a88 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1127,6 +1127,12 @@ public: return WrapFlags.HasNSW; } + bool isDisjoint() const { + assert(OpType == OperationType::DisjointOp && + "recipe cannot have a disjoing flag"); + return DisjointFlags.IsDisjoint; + } + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void printFlags(raw_ostream &O) const; #endif diff --git a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h index aa2535906945..a03a408686ef 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h +++ b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h @@ -261,6 +261,11 @@ m_Mul(const Op0_t &Op0, const Op1_t &Op1) { return m_Binary<Instruction::Mul, Op0_t, Op1_t>(Op0, Op1); } +template <typename Op0_t, typename Op1_t> +inline AllBinaryRecipe_match<Op0_t, Op1_t, Instruction::Or> +m_Or(const Op0_t &Op0, const Op1_t &Op1) { + return m_Binary<Instruction::Or, Op0_t, Op1_t>(Op0, Op1); +} } // namespace VPlanPatternMatch } // namespace llvm diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index a91ccefe4b6d..c6ec99fbbf0a 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -1216,6 +1216,23 @@ void VPlanTransforms::dropPoisonGeneratingRecipes( // load/store. If the underlying instruction has poison-generating flags, // drop them directly. if (auto *RecWithFlags = dyn_cast<VPRecipeWithIRFlags>(CurRec)) { + VPValue *A, *B; + using namespace llvm::VPlanPatternMatch; + // Dropping disjoint from an OR may yield incorrect results, as some + // analysis may have converted it to an Add implicitly (e.g. SCEV used + // for dependence analysis). Instead, replace it with an equivalent Add. + // This is possible as all users of the disjoint OR only access lanes + // where the operands are disjoint or poison otherwise. + if (match(RecWithFlags, m_Or(m_VPValue(A), m_VPValue(B))) && + RecWithFlags->isDisjoint()) { + VPBuilder Builder(RecWithFlags); + VPInstruction *New = Builder.createOverflowingOp( + Instruction::Add, {A, B}, {false, false}, + RecWithFlags->getDebugLoc()); + RecWithFlags->replaceAllUsesWith(New); + RecWithFlags->eraseFromParent(); + CurRec = New; + } RecWithFlags->dropPoisonGeneratingFlags(); } else { Instruction *Instr = dyn_cast_or_null<Instruction>( diff --git a/llvm/test/Transforms/LoopVectorize/X86/pr81872.ll b/llvm/test/Transforms/LoopVectorize/X86/pr81872.ll index 14acb6f57aa0..3f38abc75a58 100644 --- a/llvm/test/Transforms/LoopVectorize/X86/pr81872.ll +++ b/llvm/test/Transforms/LoopVectorize/X86/pr81872.ll @@ -29,7 +29,7 @@ define void @test(ptr noundef align 8 dereferenceable_or_null(16) %arr) #0 { ; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i64> [[VEC_IND]], <i64 1, i64 1, i64 1, i64 1> ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq <4 x i64> [[TMP2]], zeroinitializer ; CHECK-NEXT: [[TMP4:%.*]] = select <4 x i1> [[TMP1]], <4 x i1> [[TMP3]], <4 x i1> zeroinitializer -; CHECK-NEXT: [[TMP5:%.*]] = or i64 [[TMP0]], 1 +; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[TMP0]], 1 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i64, ptr [[ARR]], i64 [[TMP5]] ; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i64, ptr [[TMP6]], i32 0 ; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i64, ptr [[TMP7]], i32 -3 -- GitLab From e4f9175d23950ecaef32db075ed47dafe3be555c Mon Sep 17 00:00:00 2001 From: Kazu Hirata <kazu@google.com> Date: Tue, 19 Mar 2024 12:21:18 -0700 Subject: [PATCH 128/307] [BOLT] Update DIEStreamer (#85818) commit 43a2ec483fe08064b53a6293682e9bab97df61a0 Author: Jonas Devlieghere <jonas@devlieghere.com> Date: Tue Mar 19 08:30:47 2024 -0700 removed parameter Translator from the constructor of DwarfStreamer. This patch fixes the build by updating the constructor of DIEStreamer accordingly. --- bolt/lib/Rewrite/DWARFRewriter.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index 85c2397dcc5b..8dc7b90a6e30 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -283,10 +283,9 @@ public: DIEStreamer(DIEBuilder *DIEBldr, DWARFRewriter &Rewriter, DWARFLinkerBase::OutputFileType OutFileType, raw_pwrite_stream &OutFile, - std::function<StringRef(StringRef Input)> Translator, DWARFLinkerBase::MessageHandlerTy Warning) - : DwarfStreamer(OutFileType, OutFile, Translator, Warning), - DIEBldr(DIEBldr), Rewriter(Rewriter){}; + : DwarfStreamer(OutFileType, OutFile, Warning), DIEBldr(DIEBldr), + Rewriter(Rewriter){}; using DwarfStreamer::emitCompileUnitHeader; @@ -469,7 +468,6 @@ createDIEStreamer(const Triple &TheTriple, raw_pwrite_stream &OutFile, std::unique_ptr<DIEStreamer> Streamer = std::make_unique<DIEStreamer>( &DIEBldr, Rewriter, DWARFLinkerBase::OutputFileType::Object, OutFile, - [](StringRef Input) -> StringRef { return Input; }, [&](const Twine &Warning, StringRef Context, const DWARFDie *) {}); Error Err = Streamer->init(TheTriple, Swift5ReflectionSegmentName); if (Err) -- GitLab From da118c93b40f74f6770cf8550903721555d3c97b Mon Sep 17 00:00:00 2001 From: Alexey Bataev <a.bataev@outlook.com> Date: Thu, 14 Mar 2024 16:16:18 -0400 Subject: [PATCH 129/307] [SLP]Do extra analysis int minbitwidth if some checks return false. The instruction itself can be considered good for minbitwidth casting, even if one of the operand checks returns false. Reviewers: RKSimon Reviewed By: RKSimon Pull Request: https://github.com/llvm/llvm-project/pull/84363 --- .../Transforms/Vectorize/SLPVectorizer.cpp | 95 +++++++++++-------- .../SLPVectorizer/AArch64/horizontal.ll | 20 ++-- 2 files changed, 64 insertions(+), 51 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 13943c13a232..4738c60e5dfa 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -13987,15 +13987,6 @@ bool BoUpSLP::collectValuesToDemote( // If the value is not a vectorized instruction in the expression and not used // by the insertelement instruction and not used in multiple vector nodes, it // cannot be demoted. - // TODO: improve handling of gathered values and others. - auto *I = dyn_cast<Instruction>(V); - const TreeEntry *ITE = I ? getTreeEntry(I) : nullptr; - if (!ITE || !Visited.insert(I).second || MultiNodeScalars.contains(I) || - all_of(I->users(), [&](User *U) { - return isa<InsertElementInst>(U) && !getTreeEntry(U); - })) - return false; - auto IsPotentiallyTruncated = [&](Value *V, unsigned &BitWidth) -> bool { if (MultiNodeScalars.contains(V)) return false; @@ -14010,8 +14001,44 @@ bool BoUpSLP::collectValuesToDemote( BitWidth = std::max(BitWidth, BitWidth1); return BitWidth > 0 && OrigBitWidth >= (BitWidth * 2); }; + auto FinalAnalysis = [&](const TreeEntry *ITE = nullptr) { + if (!IsProfitableToDemote) + return false; + return (ITE && ITE->UserTreeIndices.size() > 1) || + IsPotentiallyTruncated(V, BitWidth); + }; + // TODO: improve handling of gathered values and others. + auto *I = dyn_cast<Instruction>(V); + const TreeEntry *ITE = I ? getTreeEntry(I) : nullptr; + if (!ITE || !Visited.insert(I).second || MultiNodeScalars.contains(I) || + all_of(I->users(), [&](User *U) { + return isa<InsertElementInst>(U) && !getTreeEntry(U); + })) + return FinalAnalysis(); + unsigned Start = 0; unsigned End = I->getNumOperands(); + + auto ProcessOperands = [&](ArrayRef<Value *> Operands, bool &NeedToExit) { + NeedToExit = false; + unsigned InitLevel = MaxDepthLevel; + for (Value *IncValue : Operands) { + unsigned Level = InitLevel; + if (!collectValuesToDemote(IncValue, IsProfitableToDemoteRoot, BitWidth, + ToDemote, DemotedConsts, Visited, Level, + IsProfitableToDemote, IsTruncRoot)) { + if (!IsProfitableToDemote) + return false; + NeedToExit = true; + if (!FinalAnalysis(ITE)) + return false; + continue; + } + MaxDepthLevel = std::max(MaxDepthLevel, Level); + } + return true; + }; + bool NeedToExit = false; switch (I->getOpcode()) { // We can always demote truncations and extensions. Since truncations can @@ -14037,35 +14064,21 @@ bool BoUpSLP::collectValuesToDemote( case Instruction::And: case Instruction::Or: case Instruction::Xor: { - unsigned Level1 = MaxDepthLevel, Level2 = MaxDepthLevel; - if ((ITE->UserTreeIndices.size() > 1 && - !IsPotentiallyTruncated(I, BitWidth)) || - !collectValuesToDemote(I->getOperand(0), IsProfitableToDemoteRoot, - BitWidth, ToDemote, DemotedConsts, Visited, - Level1, IsProfitableToDemote, IsTruncRoot) || - !collectValuesToDemote(I->getOperand(1), IsProfitableToDemoteRoot, - BitWidth, ToDemote, DemotedConsts, Visited, - Level2, IsProfitableToDemote, IsTruncRoot)) + if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) + return false; + if (!ProcessOperands({I->getOperand(0), I->getOperand(1)}, NeedToExit)) return false; - MaxDepthLevel = std::max(Level1, Level2); break; } // We can demote selects if we can demote their true and false values. case Instruction::Select: { + if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) + return false; Start = 1; - unsigned Level1 = MaxDepthLevel, Level2 = MaxDepthLevel; - SelectInst *SI = cast<SelectInst>(I); - if ((ITE->UserTreeIndices.size() > 1 && - !IsPotentiallyTruncated(I, BitWidth)) || - !collectValuesToDemote(SI->getTrueValue(), IsProfitableToDemoteRoot, - BitWidth, ToDemote, DemotedConsts, Visited, - Level1, IsProfitableToDemote, IsTruncRoot) || - !collectValuesToDemote(SI->getFalseValue(), IsProfitableToDemoteRoot, - BitWidth, ToDemote, DemotedConsts, Visited, - Level2, IsProfitableToDemote, IsTruncRoot)) + auto *SI = cast<SelectInst>(I); + if (!ProcessOperands({SI->getTrueValue(), SI->getFalseValue()}, NeedToExit)) return false; - MaxDepthLevel = std::max(Level1, Level2); break; } @@ -14075,23 +14088,20 @@ bool BoUpSLP::collectValuesToDemote( PHINode *PN = cast<PHINode>(I); if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) return false; - unsigned InitLevel = MaxDepthLevel; - for (Value *IncValue : PN->incoming_values()) { - unsigned Level = InitLevel; - if (!collectValuesToDemote(IncValue, IsProfitableToDemoteRoot, BitWidth, - ToDemote, DemotedConsts, Visited, Level, - IsProfitableToDemote, IsTruncRoot)) - return false; - MaxDepthLevel = std::max(MaxDepthLevel, Level); - } + SmallVector<Value *> Ops(PN->incoming_values().begin(), + PN->incoming_values().end()); + if (!ProcessOperands(Ops, NeedToExit)) + return false; break; } // Otherwise, conservatively give up. default: MaxDepthLevel = 1; - return IsProfitableToDemote && IsPotentiallyTruncated(I, BitWidth); + return FinalAnalysis(); } + if (NeedToExit) + return true; ++MaxDepthLevel; // Gather demoted constant operands. @@ -14130,6 +14140,7 @@ void BoUpSLP::computeMinimumValueSizes() { // The first value node for store/insertelement is sext/zext/trunc? Skip it, // resize to the final type. + bool IsTruncRoot = false; bool IsProfitableToDemoteRoot = !IsStoreOrInsertElt; if (NodeIdx != 0 && VectorizableTree[NodeIdx]->State == TreeEntry::Vectorize && @@ -14137,8 +14148,9 @@ void BoUpSLP::computeMinimumValueSizes() { VectorizableTree[NodeIdx]->getOpcode() == Instruction::SExt || VectorizableTree[NodeIdx]->getOpcode() == Instruction::Trunc)) { assert(IsStoreOrInsertElt && "Expected store/insertelement seeded graph."); - ++NodeIdx; + IsTruncRoot = VectorizableTree[NodeIdx]->getOpcode() == Instruction::Trunc; IsProfitableToDemoteRoot = true; + ++NodeIdx; } // Analyzed in reduction already and not profitable - exit. @@ -14270,7 +14282,6 @@ void BoUpSLP::computeMinimumValueSizes() { ReductionBitWidth = bit_ceil(ReductionBitWidth); } bool IsTopRoot = NodeIdx == 0; - bool IsTruncRoot = false; while (NodeIdx < VectorizableTree.size() && VectorizableTree[NodeIdx]->State == TreeEntry::Vectorize && VectorizableTree[NodeIdx]->getOpcode() == Instruction::Trunc) { diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll index 1986b51ec948..7c5f9847db1f 100644 --- a/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll +++ b/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll @@ -228,7 +228,7 @@ for.end: ; preds = %for.end.loopexit, % ; YAML-NEXT: Function: test_unrolled_select ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'Vectorized horizontal reduction with cost ' -; YAML-NEXT: - Cost: '-36' +; YAML-NEXT: - Cost: '-41' ; YAML-NEXT: - String: ' and with tree size ' ; YAML-NEXT: - TreeSize: '10' @@ -246,15 +246,17 @@ define i32 @test_unrolled_select(ptr noalias nocapture readonly %blk1, ptr noali ; CHECK-NEXT: [[P2_045:%.*]] = phi ptr [ [[BLK2:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR88:%.*]], [[IF_END_86]] ] ; CHECK-NEXT: [[P1_044:%.*]] = phi ptr [ [[BLK1:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR:%.*]], [[IF_END_86]] ] ; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[P1_044]], align 1 -; CHECK-NEXT: [[TMP1:%.*]] = zext <8 x i8> [[TMP0]] to <8 x i32> +; CHECK-NEXT: [[TMP1:%.*]] = zext <8 x i8> [[TMP0]] to <8 x i16> ; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i8>, ptr [[P2_045]], align 1 -; CHECK-NEXT: [[TMP3:%.*]] = zext <8 x i8> [[TMP2]] to <8 x i32> -; CHECK-NEXT: [[TMP4:%.*]] = sub nsw <8 x i32> [[TMP1]], [[TMP3]] -; CHECK-NEXT: [[TMP5:%.*]] = icmp slt <8 x i32> [[TMP4]], zeroinitializer -; CHECK-NEXT: [[TMP6:%.*]] = sub nsw <8 x i32> zeroinitializer, [[TMP4]] -; CHECK-NEXT: [[TMP7:%.*]] = select <8 x i1> [[TMP5]], <8 x i32> [[TMP6]], <8 x i32> [[TMP4]] -; CHECK-NEXT: [[TMP8:%.*]] = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[TMP7]]) -; CHECK-NEXT: [[OP_RDX]] = add i32 [[TMP8]], [[S_047]] +; CHECK-NEXT: [[TMP3:%.*]] = zext <8 x i8> [[TMP2]] to <8 x i16> +; CHECK-NEXT: [[TMP4:%.*]] = sub <8 x i16> [[TMP1]], [[TMP3]] +; CHECK-NEXT: [[TMP5:%.*]] = sext <8 x i16> [[TMP4]] to <8 x i32> +; CHECK-NEXT: [[TMP6:%.*]] = icmp slt <8 x i32> [[TMP5]], zeroinitializer +; CHECK-NEXT: [[TMP7:%.*]] = sub <8 x i16> zeroinitializer, [[TMP4]] +; CHECK-NEXT: [[TMP8:%.*]] = select <8 x i1> [[TMP6]], <8 x i16> [[TMP7]], <8 x i16> [[TMP4]] +; CHECK-NEXT: [[TMP9:%.*]] = sext <8 x i16> [[TMP8]] to <8 x i32> +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[TMP9]]) +; CHECK-NEXT: [[OP_RDX]] = add i32 [[TMP10]], [[S_047]] ; CHECK-NEXT: [[CMP83:%.*]] = icmp slt i32 [[OP_RDX]], [[LIM:%.*]] ; CHECK-NEXT: br i1 [[CMP83]], label [[IF_END_86]], label [[FOR_END_LOOPEXIT:%.*]] ; CHECK: if.end.86: -- GitLab From 0b59af4d86cf8d3ee3eb1a8e5673b1a21bb387b5 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng <dtcxzyw2333@gmail.com> Date: Wed, 20 Mar 2024 03:28:19 +0800 Subject: [PATCH 130/307] [InstCombine] Clear sign-bit of the constant magnitude in copysign (#85787) Alive2: https://alive2.llvm.org/ce/z/vFykcZ Address the comment https://github.com/llvm/llvm-project/pull/85772#discussion_r1530179048. Unfortunately, non-splat vector constants are not supported because we haven't implemented constant folding of fabs with vector operands. --- .../InstCombine/InstCombineCalls.cpp | 10 +++ .../InstCombine/copysign-fneg-fabs.ll | 79 +++++++++++++++++++ llvm/test/Transforms/InstCombine/fcmp.ll | 10 +-- 3 files changed, 94 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 8537dbc6fe53..3eafcb03644e 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2473,6 +2473,16 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { if (match(Sign, m_Intrinsic<Intrinsic::copysign>(m_Value(), m_Value(X)))) return replaceOperand(*II, 1, X); + // Clear sign-bit of constant magnitude: + // copysign -MagC, X --> copysign MagC, X + // TODO: Support constant folding for fabs + const APFloat *MagC; + if (match(Mag, m_APFloat(MagC)) && MagC->isNegative()) { + APFloat PosMagC = *MagC; + PosMagC.clearSign(); + return replaceOperand(*II, 0, ConstantFP::get(Mag->getType(), PosMagC)); + } + // Peek through changes of magnitude's sign-bit. This call rewrites those: // copysign (fabs X), Sign --> copysign X, Sign // copysign (fneg X), Sign --> copysign X, Sign diff --git a/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll b/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll index af939cf74399..a63eeab6a4b1 100644 --- a/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll +++ b/llvm/test/Transforms/InstCombine/copysign-fneg-fabs.ll @@ -275,6 +275,85 @@ define half @fneg_fabs_copysign_multi_use_fabs(half %x, half %y, ptr %ptr) { ret half %fabs.copysign } +define half @copysign_pos(half %a) { +; CHECK-LABEL: @copysign_pos( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RET:%.*]] = call half @llvm.copysign.f16(half 0xH3C00, half [[A:%.*]]) +; CHECK-NEXT: ret half [[RET]] +; +entry: + %ret = call half @llvm.copysign.f16(half 0xH3C00, half %a) + ret half %ret +} + +define half @copysign_neg(half %a) { +; CHECK-LABEL: @copysign_neg( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RET:%.*]] = call half @llvm.copysign.f16(half 0xH3C00, half [[A:%.*]]) +; CHECK-NEXT: ret half [[RET]] +; +entry: + %ret = call half @llvm.copysign.f16(half 0xHBC00, half %a) + ret half %ret +} + +define half @copysign_negzero(half %a) { +; CHECK-LABEL: @copysign_negzero( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RET:%.*]] = call half @llvm.copysign.f16(half 0xH0000, half [[A:%.*]]) +; CHECK-NEXT: ret half [[RET]] +; +entry: + %ret = call half @llvm.copysign.f16(half 0xH8000, half %a) + ret half %ret +} + +define half @copysign_negnan(half %a) { +; CHECK-LABEL: @copysign_negnan( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RET:%.*]] = call half @llvm.copysign.f16(half 0xH7E00, half [[A:%.*]]) +; CHECK-NEXT: ret half [[RET]] +; +entry: + %ret = call half @llvm.copysign.f16(half 0xHFE00, half %a) + ret half %ret +} + +define half @copysign_neginf(half %a) { +; CHECK-LABEL: @copysign_neginf( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RET:%.*]] = call half @llvm.copysign.f16(half 0xH7C00, half [[A:%.*]]) +; CHECK-NEXT: ret half [[RET]] +; +entry: + %ret = call half @llvm.copysign.f16(half 0xHFC00, half %a) + ret half %ret +} + +define <4 x half> @copysign_splat(<4 x half> %a) { +; CHECK-LABEL: @copysign_splat( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RET:%.*]] = call <4 x half> @llvm.copysign.v4f16(<4 x half> <half 0xH3C00, half 0xH3C00, half 0xH3C00, half 0xH3C00>, <4 x half> [[A:%.*]]) +; CHECK-NEXT: ret <4 x half> [[RET]] +; +entry: + %ret = call <4 x half> @llvm.copysign.v4f16(<4 x half> splat(half 0xHBC00), <4 x half> %a) + ret <4 x half> %ret +} + +; TODO: Support constant folding of fabs + +define <4 x half> @copysign_vec4(<4 x half> %a) { +; CHECK-LABEL: @copysign_vec4( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RET:%.*]] = call <4 x half> @llvm.copysign.v4f16(<4 x half> <half 0xH3C00, half 0xHBC00, half undef, half poison>, <4 x half> [[A:%.*]]) +; CHECK-NEXT: ret <4 x half> [[RET]] +; +entry: + %ret = call <4 x half> @llvm.copysign.v4f16(<4 x half> <half 0xH3C00, half 0xHBC00, half undef, half poison>, <4 x half> %a) + ret <4 x half> %ret +} + declare half @llvm.fabs.f16(half) declare <2 x half> @llvm.fabs.v2f16(<2 x half>) declare half @llvm.copysign.f16(half, half) diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll index 159c84d0dd8a..f2701d16d0f3 100644 --- a/llvm/test/Transforms/InstCombine/fcmp.ll +++ b/llvm/test/Transforms/InstCombine/fcmp.ll @@ -644,7 +644,7 @@ define <2 x i1> @is_signbit_set_anyzero(<2 x double> %x) { define i1 @is_signbit_clear(double %x) { ; CHECK-LABEL: @is_signbit_clear( -; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]]) +; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]]) ; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00 ; CHECK-NEXT: ret i1 [[R]] ; @@ -655,7 +655,7 @@ define i1 @is_signbit_clear(double %x) { define i1 @is_signbit_clear_1(double %x) { ; CHECK-LABEL: @is_signbit_clear_1( -; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]]) +; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]]) ; CHECK-NEXT: [[R:%.*]] = fcmp ugt double [[S]], 0.000000e+00 ; CHECK-NEXT: ret i1 [[R]] ; @@ -666,7 +666,7 @@ define i1 @is_signbit_clear_1(double %x) { define i1 @is_signbit_clear_2(double %x) { ; CHECK-LABEL: @is_signbit_clear_2( -; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]]) +; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]]) ; CHECK-NEXT: [[R:%.*]] = fcmp oge double [[S]], 0.000000e+00 ; CHECK-NEXT: ret i1 [[R]] ; @@ -677,7 +677,7 @@ define i1 @is_signbit_clear_2(double %x) { define i1 @is_signbit_clear_3(double %x) { ; CHECK-LABEL: @is_signbit_clear_3( -; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]]) +; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]]) ; CHECK-NEXT: [[R:%.*]] = fcmp uge double [[S]], 0.000000e+00 ; CHECK-NEXT: ret i1 [[R]] ; @@ -705,7 +705,7 @@ define i1 @is_signbit_set_extra_use(double %x, ptr %p) { define i1 @is_signbit_clear_nonzero(double %x) { ; CHECK-LABEL: @is_signbit_clear_nonzero( -; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]]) +; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]]) ; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 1.000000e+00 ; CHECK-NEXT: ret i1 [[R]] ; -- GitLab From 32a6e9d66945c28a9cae476b6d2eb803ca2ab098 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jonas@devlieghere.com> Date: Tue, 19 Mar 2024 08:30:47 -0700 Subject: [PATCH 131/307] [dsymutil] Remove support for obfuscated bitcode (#85713) Remove support for obfuscated bitcode in dsymutil and the DWARF linker. We no longer support bitcode submissions and the obfuscation support has been removed from the rest of the compiler. rdar://123863918 --- llvm/docs/CommandGuide/dsymutil.rst | 4 - .../llvm/CodeGen/NonRelocatableStringpool.h | 6 +- .../llvm/DWARFLinker/Classic/DWARFStreamer.h | 8 +- .../llvm/DWARFLinker/DWARFLinkerBase.h | 1 - .../llvm/DWARFLinker/Parallel/DWARFLinker.h | 3 +- llvm/lib/CodeGen/NonRelocatableStringpool.cpp | 5 - llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 4 +- .../lib/DWARFLinker/Classic/DWARFStreamer.cpp | 12 +- llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp | 6 +- .../Parallel/DWARFLinkerGlobalData.h | 15 -- .../DWARFLinker/Parallel/DWARFLinkerImpl.cpp | 4 +- .../DWARFLinker/Parallel/DWARFLinkerImpl.h | 3 +- .../lib/DWARFLinker/Parallel/OutputSections.h | 2 +- .../StringEntryToDwarfStringPoolEntryMap.h | 2 +- llvm/test/tools/dsymutil/ARM/obfuscated.test | 200 ------------------ .../tools/dsymutil/Inputs/obfuscated.2.arm64 | Bin 10339 -> 0 bytes .../tools/dsymutil/Inputs/obfuscated.2.map | 22 -- .../tools/dsymutil/Inputs/obfuscated.arm64 | Bin 10434 -> 0 bytes .../test/tools/dsymutil/Inputs/obfuscated.map | 17 -- llvm/test/tools/dsymutil/cmdline.test | 1 - llvm/tools/dsymutil/CMakeLists.txt | 1 - llvm/tools/dsymutil/DwarfLinkerForBinary.cpp | 14 +- llvm/tools/dsymutil/LinkUtils.h | 5 - llvm/tools/dsymutil/MachOUtils.cpp | 7 +- llvm/tools/dsymutil/MachOUtils.h | 4 +- llvm/tools/dsymutil/Options.td | 6 - llvm/tools/dsymutil/SymbolMap.cpp | 157 -------------- llvm/tools/dsymutil/SymbolMap.h | 53 ----- llvm/tools/dsymutil/dsymutil.cpp | 15 +- llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp | 6 +- 30 files changed, 28 insertions(+), 555 deletions(-) delete mode 100644 llvm/test/tools/dsymutil/ARM/obfuscated.test delete mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.2.arm64 delete mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.2.map delete mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.arm64 delete mode 100644 llvm/test/tools/dsymutil/Inputs/obfuscated.map delete mode 100644 llvm/tools/dsymutil/SymbolMap.cpp delete mode 100644 llvm/tools/dsymutil/SymbolMap.h diff --git a/llvm/docs/CommandGuide/dsymutil.rst b/llvm/docs/CommandGuide/dsymutil.rst index af9d7f16b361..e3f2f33224b0 100644 --- a/llvm/docs/CommandGuide/dsymutil.rst +++ b/llvm/docs/CommandGuide/dsymutil.rst @@ -140,10 +140,6 @@ OPTIONS (in bytes) to the linked dSYM. The table is sorted by the output size listing the object files with the largest contribution first. -.. option:: --symbol-map <bcsymbolmap> - - Update the existing dSYMs inplace using symbol map specified. - .. option:: -s, --symtab Dumps the symbol table found in *executable* or object file(s) and exits. diff --git a/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h b/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h index 3dc0731f5a04..4b8eed7bdb1b 100644 --- a/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h +++ b/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h @@ -27,10 +27,7 @@ public: /// order. using MapTy = StringMap<DwarfStringPoolEntry, BumpPtrAllocator>; - NonRelocatableStringpool( - std::function<StringRef(StringRef Input)> Translator = nullptr, - bool PutEmptyString = false) - : Translator(Translator) { + NonRelocatableStringpool(bool PutEmptyString = false) { if (PutEmptyString) getEntry(""); } @@ -59,7 +56,6 @@ private: MapTy Strings; uint64_t CurrentEndOffset = 0; unsigned NumEntries = 0; - std::function<StringRef(StringRef Input)> Translator; }; /// Helper for making strong types. diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h index bebdfd5e6025..e7a1a3cd838c 100644 --- a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h +++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h @@ -45,16 +45,13 @@ class DwarfStreamer : public DwarfEmitter { public: DwarfStreamer(DWARFLinkerBase::OutputFileType OutFileType, raw_pwrite_stream &OutFile, - DWARFLinkerBase::TranslatorFuncTy Translator, DWARFLinkerBase::MessageHandlerTy Warning) - : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator), - WarningHandler(Warning) {} + : OutFile(OutFile), OutFileType(OutFileType), WarningHandler(Warning) {} virtual ~DwarfStreamer() = default; static Expected<std::unique_ptr<DwarfStreamer>> createStreamer( const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType, - raw_pwrite_stream &OutFile, DWARFLinkerBase::TranslatorFuncTy Translator, - DWARFLinkerBase::MessageHandlerTy Warning); + raw_pwrite_stream &OutFile, DWARFLinkerBase::MessageHandlerTy Warning); Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName); @@ -295,7 +292,6 @@ private: /// The output file we stream the linked Dwarf to. raw_pwrite_stream &OutFile; DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object; - std::function<StringRef(StringRef Input)> Translator; uint64_t RangesSectionSize = 0; uint64_t RngListsSectionSize = 0; diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h index 5c811b668f0a..70b25cf02df7 100644 --- a/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h +++ b/llvm/include/llvm/DWARFLinker/DWARFLinkerBase.h @@ -82,7 +82,6 @@ public: std::function<void(const DWARFFile &File, llvm::StringRef Output)>; using ObjectPrefixMapTy = std::map<std::string, std::string>; using CompileUnitHandlerTy = function_ref<void(const DWARFUnit &Unit)>; - using TranslatorFuncTy = std::function<StringRef(StringRef)>; using SwiftInterfacesMapTy = std::map<std::string, std::string>; /// Type of output file. enum class OutputFileType : uint8_t { diff --git a/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h index 5312712a4a5b..8acc046d0724 100644 --- a/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/Parallel/DWARFLinker.h @@ -123,8 +123,7 @@ public: /// Creates dwarf linker instance. static std::unique_ptr<DWARFLinker> - createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler, - TranslatorFuncTy StringsTranslator = nullptr); + createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler); /// Set output DWARF handler. Result of linking DWARF is set of sections /// containing final debug info. DWARFLinkerBase::link() pass generated diff --git a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp index e8391afb8e3f..26857c6a4088 100644 --- a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp +++ b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp @@ -12,8 +12,6 @@ namespace llvm { DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) { - if (Translator) - S = Translator(S); auto I = Strings.insert({S, DwarfStringPoolEntry()}); auto &Entry = I.first->second; if (I.second || !Entry.isIndexed()) { @@ -28,9 +26,6 @@ DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) { StringRef NonRelocatableStringpool::internString(StringRef S) { DwarfStringPoolEntry Entry{nullptr, 0, DwarfStringPoolEntry::NotIndexed}; - if (Translator) - S = Translator(S); - auto InsertResult = Strings.insert({S, Entry}); return InsertResult.first->getKey(); } diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp index 9b581a6c9ab7..60f664ece7ee 100644 --- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp @@ -2701,8 +2701,8 @@ Error DWARFLinker::link() { // This Dwarf string pool which is used for emission. It must be used // serially as the order of calling getStringOffset matters for // reproducibility. - OffsetsStringPool DebugStrPool(StringsTranslator, true); - OffsetsStringPool DebugLineStrPool(StringsTranslator, false); + OffsetsStringPool DebugStrPool(true); + OffsetsStringPool DebugLineStrPool(false); DebugDieValuePool StringOffsetPool; // ODR Contexts for the optimize. diff --git a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp index 6d522370e440..8b31b5ead29a 100644 --- a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp +++ b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp @@ -32,10 +32,9 @@ using namespace dwarf_linker::classic; Expected<std::unique_ptr<DwarfStreamer>> DwarfStreamer::createStreamer( const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType, - raw_pwrite_stream &OutFile, DWARFLinkerBase::TranslatorFuncTy Translator, - DWARFLinkerBase::MessageHandlerTy Warning) { + raw_pwrite_stream &OutFile, DWARFLinkerBase::MessageHandlerTy Warning) { std::unique_ptr<DwarfStreamer> Streamer = - std::make_unique<DwarfStreamer>(FileType, OutFile, Translator, Warning); + std::make_unique<DwarfStreamer>(FileType, OutFile, Warning); if (Error Err = Streamer->init(TheTriple, "__DWARF")) return std::move(Err); @@ -977,11 +976,10 @@ void DwarfStreamer::emitLineTableString(const DWARFDebugLine::Prologue &P, switch (String.getForm()) { case dwarf::DW_FORM_string: { - StringRef TranslatedString = - (Translator) ? Translator(*StringVal) : *StringVal; - Asm->OutStreamer->emitBytes(TranslatedString.data()); + StringRef Str = *StringVal; + Asm->OutStreamer->emitBytes(Str.data()); Asm->emitInt8(0); - LineSectionSize += TranslatedString.size() + 1; + LineSectionSize += Str.size() + 1; } break; case dwarf::DW_FORM_strp: case dwarf::DW_FORM_line_strp: { diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp index ad8d28a64317..31c7e867767a 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinker.cpp @@ -15,8 +15,6 @@ using namespace dwarf_linker::parallel; std::unique_ptr<DWARFLinker> DWARFLinker::createLinker(MessageHandlerTy ErrorHandler, - MessageHandlerTy WarningHandler, - TranslatorFuncTy StringsTranslator) { - return std::make_unique<DWARFLinkerImpl>(ErrorHandler, WarningHandler, - StringsTranslator); + MessageHandlerTy WarningHandler) { + return std::make_unique<DWARFLinkerImpl>(ErrorHandler, WarningHandler); } diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h index 38c261a8106f..7ca81eb34f00 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h @@ -21,7 +21,6 @@ class DWARFDie; namespace dwarf_linker { namespace parallel { -using TranslatorFuncTy = std::function<StringRef(StringRef)>; using MessageHandlerTy = std::function<void( const Twine &Warning, StringRef Context, const DWARFDie *DIE)>; @@ -95,19 +94,6 @@ public: /// Returns global string pool. StringPool &getStringPool() { return Strings; } - /// Set translation function. - void setTranslator(TranslatorFuncTy Translator) { - this->Translator = Translator; - } - - /// Translate specified string. - StringRef translateString(StringRef String) { - if (Translator) - return Translator(String); - - return String; - } - /// Returns linking options. const DWARFLinkerOptions &getOptions() const { return Options; } @@ -161,7 +147,6 @@ public: protected: llvm::parallel::PerThreadBumpPtrAllocator Allocator; StringPool Strings; - TranslatorFuncTy Translator; DWARFLinkerOptions Options; MessageHandlerTy WarningHandler; MessageHandlerTy ErrorHandler; diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp index 49b08997eb9c..e68bf0c227a0 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp @@ -20,11 +20,9 @@ using namespace dwarf_linker; using namespace dwarf_linker::parallel; DWARFLinkerImpl::DWARFLinkerImpl(MessageHandlerTy ErrorHandler, - MessageHandlerTy WarningHandler, - TranslatorFuncTy StringsTranslator) + MessageHandlerTy WarningHandler) : UniqueUnitID(0), DebugStrStrings(GlobalData), DebugLineStrStrings(GlobalData), CommonSections(GlobalData) { - GlobalData.setTranslator(StringsTranslator); GlobalData.setErrorHandler(ErrorHandler); GlobalData.setWarningHandler(WarningHandler); } diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h index 7c17c5b79c7c..597bb1b4da59 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h @@ -26,8 +26,7 @@ namespace parallel { class DWARFLinkerImpl : public DWARFLinker { public: DWARFLinkerImpl(MessageHandlerTy ErrorHandler, - MessageHandlerTy WarningHandler, - TranslatorFuncTy StringsTranslator); + MessageHandlerTy WarningHandler); /// Add object file to be linked. Pre-load compile unit die. Call /// \p OnCUDieLoaded for each compile unit die. If specified \p File diff --git a/llvm/lib/DWARFLinker/Parallel/OutputSections.h b/llvm/lib/DWARFLinker/Parallel/OutputSections.h index a21e4b2b75a5..0e1f2dae54bc 100644 --- a/llvm/lib/DWARFLinker/Parallel/OutputSections.h +++ b/llvm/lib/DWARFLinker/Parallel/OutputSections.h @@ -253,7 +253,7 @@ struct SectionDescriptor : SectionDescriptorBase { /// Emit specified inplace string value into the current section contents. void emitInplaceString(StringRef String) { - OS << GlobalData.translateString(String); + OS << String; emitIntVal(0, 1); } diff --git a/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h b/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h index 858f224777db..f67536ef7a1a 100644 --- a/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h +++ b/llvm/lib/DWARFLinker/Parallel/StringEntryToDwarfStringPoolEntryMap.h @@ -33,7 +33,7 @@ public: DwarfStringPoolEntryWithExtString *DataPtr = GlobalData.getAllocator() .Allocate<DwarfStringPoolEntryWithExtString>(); - DataPtr->String = GlobalData.translateString(String->getKey()); + DataPtr->String = String->getKey(); DataPtr->Index = DwarfStringPoolEntry::NotIndexed; DataPtr->Offset = 0; DataPtr->Symbol = nullptr; diff --git a/llvm/test/tools/dsymutil/ARM/obfuscated.test b/llvm/test/tools/dsymutil/ARM/obfuscated.test deleted file mode 100644 index 3443b8e63469..000000000000 --- a/llvm/test/tools/dsymutil/ARM/obfuscated.test +++ /dev/null @@ -1,200 +0,0 @@ -REQUIRES: system-darwin - -RUN: dsymutil --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck %s - -RUN: dsymutil --accelerator=Pub --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=PUB %s - -RUN: dsymutil --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=NOHIDDEN %s - -RUN: dsymutil --symbol-map %p/../Inputs/obfuscated.2.map %p/../Inputs/obfuscated.2.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=NOHIDDEN %s - -// Run with plist and make sure dsymutil finds it. -RUN: mkdir -p %t.dSYM/Contents/Resources/DWARF/ -RUN: mkdir -p %t.mapdir -RUN: cp %p/../Inputs/obfuscated.arm64 %t.dSYM/Contents/Resources/DWARF/ -RUN: cp %p/../Inputs/E828A486-8433-3A5E-B6DB-A6294D28133D.plist %t.dSYM/Contents/Resources/ -RUN: cp %p/../Inputs/obfuscated.map %t.mapdir/506AA50A-6B26-3B37-86D2-DC6EBD57B720.bcsymbolmap -RUN: dsymutil --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=OBFUSCATING %s - -// Run without plist and make sure dsymutil doesn't crash. -RUN: rm %t.dSYM/Contents/Resources/E828A486-8433-3A5E-B6DB-A6294D28133D.plist -RUN: dsymutil --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=NOTOBFUSCATING %s - -// ---------------------------------------- -// Repeat the same steps for --linker parallel. -RUN: dsymutil --linker parallel --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck %s - -RUN: dsymutil --linker parallel --accelerator=Pub --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=PUB %s - -RUN: dsymutil --linker parallel --symbol-map %p/../Inputs/obfuscated.map %p/../Inputs/obfuscated.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=NOHIDDEN %s - -RUN: dsymutil --linker parallel --symbol-map %p/../Inputs/obfuscated.2.map %p/../Inputs/obfuscated.2.arm64 -f -o - \ -RUN: | llvm-dwarfdump -v - \ -RUN: | FileCheck --check-prefix=NOHIDDEN %s - -// Run with plist and make sure dsymutil finds it. -RUN: mkdir -p %t.dSYM/Contents/Resources/DWARF/ -RUN: mkdir -p %t.mapdir -RUN: cp %p/../Inputs/obfuscated.arm64 %t.dSYM/Contents/Resources/DWARF/ -RUN: cp %p/../Inputs/E828A486-8433-3A5E-B6DB-A6294D28133D.plist %t.dSYM/Contents/Resources/ -RUN: cp %p/../Inputs/obfuscated.map %t.mapdir/506AA50A-6B26-3B37-86D2-DC6EBD57B720.bcsymbolmap -RUN: dsymutil --linker parallel --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=OBFUSCATING %s - -// Run without plist and make sure dsymutil doesn't crash. -RUN: rm %t.dSYM/Contents/Resources/E828A486-8433-3A5E-B6DB-A6294D28133D.plist -RUN: dsymutil --linker parallel --symbol-map %t.mapdir %t.dSYM 2>&1 | FileCheck --check-prefix=NOTOBFUSCATING %s - -OBFUSCATING-NOT: not unobfuscating - -NOTOBFUSCATING: not unobfuscating - -NOHIDDEN-NOT: __hidden# - -CHECK: .debug_info contents: - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "main.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "main") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "one.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "one") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "two.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "two") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "three.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "three") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "four.c") -CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x0000011e) -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "four") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "five.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "five") - -CHECK: DW_TAG_compile_unit [1] * -CHECK: DW_AT_producer [DW_FORM_strp] ( {{.*}} "Apple LLVM version 7.0.0 (clang-700.2.38.2)") -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "six.c") -CHECK: DW_AT_comp_dir [DW_FORM_strp] ( {{.*}} "/Users/steven/dev/alpena/tests/src") -CHECK: DW_TAG_subprogram [2] -CHECK: DW_AT_name [DW_FORM_strp] ( {{.*}} "six") - -CHECK: .debug_line contents: -CHECK: file_names[ 1]: -CHECK: name: "main.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "one.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "two.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "three.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "four.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "five.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 -CHECK: file_names[ 1]: -CHECK: name: "six.c" -CHECK: dir_index: 0 -CHECK: mod_time: 0x00000000 -CHECK: length: 0x00000000 - -PUB: .debug_pubnames contents: -PUB: length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000000, unit_size = 0x00000044 -PUB: 0x0000002e "main" -PUB: length = 0x00000016, format = DWARF32, version = 0x0002, unit_offset = 0x00000044, unit_size = 0x00000044 -PUB: 0x0000002e "one" -PUB: length = 0x00000016, format = DWARF32, version = 0x0002, unit_offset = 0x00000088, unit_size = 0x00000044 -PUB: 0x0000002e "two" -PUB: length = 0x00000018, format = DWARF32, version = 0x0002, unit_offset = 0x000000cc, unit_size = 0x00000044 -PUB: 0x0000002e "three" -PUB: length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000110, unit_size = 0x00000044 -PUB: 0x0000002e "four" -PUB: length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000154, unit_size = 0x00000044 -PUB: 0x0000002e "five" -PUB: length = 0x00000016, format = DWARF32, version = 0x0002, unit_offset = 0x00000198, unit_size = 0x00000044 -PUB: 0x0000002e "six" - -CHECK: .apple_names contents: - -CHECK: String: 0x00000091 "five" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x00000182 -CHECK-NEXT: ] -CHECK: String: 0x0000009c "six" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x000001c6 -CHECK-NEXT: ] -CHECK: String: 0x00000078 "three" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x000000fa -CHECK-NEXT: ] -CHECK: String: 0x0000006c "two" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x000000b6 -CHECK-NEXT: ] -CHECK: String: 0x00000057 "main" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x0000002e -CHECK-NEXT: ] -CHECK: String: 0x00000085 "four" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x0000013e -CHECK-NEXT: ] -CHECK: String: 0x00000062 "one" -CHECK-NEXT: Data 0 [ -CHECK-NEXT: Atom[0]: 0x00000072 -CHECK-NEXT: ] diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.2.arm64 b/llvm/test/tools/dsymutil/Inputs/obfuscated.2.arm64 deleted file mode 100644 index b40e023eb4916cca1fe38388ce12b030c1a51eda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10339 zcmeHNO>A355Pr|jbJ8?*5>i!-f<mAz6jY#YY4{1ESZN@6<tGY(0s^i4^GIAdwy_;Z zq^hw{4hSwtRDxcRkjjA*qUxdT1rCS{pk6q@k)K1Qs1nFGkODJrXV%aAY$v(Gjx>Hd zv$NmM&dzSK``(SeZf*8imTdv`0(S%7jG-iH1Rnc=cYk|r@Y9)zKR<l-yUomzmu^K! zZw**h50q>0Ov7^+cp6xU+2qqxuTIT94}wO1XPQnI5$7i`6k>kr<@x4XzkRJ)$C3jD zX4DB$^;W7}8^-(Nyd3<6hKYq^Q`BYER2d3FRI1DAic;zRt*=Quh^eCBczXzs>m{C8 z^ztRI3@voL4+!s|LbJB;FH@<ObA<)6*YU0pURMAwSZo?QR0y$Lcsp0fid^B1qAxek z$5q0^IcL%_SdUMf*PFmXoJ!6oQA1RtBz%$;&Ce)^$c!z-LNPF{ZSf#26=8cOO!45n z2$4^T%IZ?Om=~pLIfOS*llGYFOhG(cH$l0v4xX8L?)22DnR#mUwKh(2@K>rvpMriN z&LRLqyv`)&o+2xJ*wT&%I3}wy<RJTlYZ^(2te0M15cyoelX7dkI(I&XR_%%LQsq=( z!K;M)tJ~7QS;DK|*&YjP7_YRPE~J*ciay@SsKl!i%;bUX;ZfR#{2T9*c)yW<<G}^i z0-F6xrPF2at?+yd$0Xie)OPsp79ar?<H2I}wfcA`2=9ApGqELJs#MB*!Vey_(eb*w zrGLK@UiUpzX!8&vfLBUobi571<FIXP6R)~jf@}%<*WV-kJ4*iaA8z9qsoB3``fLVO zx_>7LkNrEj1zzXgOs$E4iGYcKiGYcKiGYc~e<uQXo*K2~Ap-vu-sj7f#pmMNNq&va zdH0f>C3&3WJjs(JS4o~F`5eiwgWL}t&6AA(xh*XUZ^g?jS3Nifr?PMk7E7sI0cylz zE}QiV2abw>kO&ILg2M5j@DK<^dDwwI4Veg-2$%?%2$%?%2$%?%2$%?%2$%?%2$%@` zpCf=TPa+n+wX*HM<9py2UflVwAZ<8u)A9RZAw#q)!q)=PUfUVytvmZ;?>PHhXUug* zUFSa6IqW*eT_@o>kGsxet`m)&u1EF)=o5Z7_|C3FHwifA`?M><*8@XNw09`dvuy;p z4j=@+u-GXATpJJqUvcadVO$~brN~YZ9#IH<jj}_8V~t4i#Y+R>2#gP}edLE5jjNul zuM7W3`zdA5a}#_O9&9D;-&6KH6P@jED0_~3XZyX7rqY6=+}ZvWWzR9~Z2yU}=Loj5 z9|g~4JTXQO0;`2XsUR(|He~Uroa#G#42)UGA_4bZNYVtu6gGj2uZ9UmCTwydXoA5A zo6s_s9pU)HCgg4sdZQHbw~Ib&kMDr|zQg8Sf-^;J8>~2l)?ttYXcvI-qX(O9IepZg zzzW<`T7bBq{T$c_VO!3rh^{!(8U)wE27_>8PPB-wc(XOgc~IXEVe~!W#?>`{ceNtA z;{DbjAA`EcAl&#IgXoIST7z5$^_L97jn^4OSA2ya_Mm+z4x2`NAT|>JWvy?}z6}5( z4_H`;#?eHj`3bytZTziJW!T458J2=7<3_IpNGVlL_}96Fgo)p%!RuV^BjI24vRM;y z(3M26{{&>W0>J%I2?_9E`i0~)4A1}k4L_af!|?&3&bIJlA(`+|cy<9h!2bYYP50av z2VY#dc>OFqM^-Oh{|L%Mz&``yCrazU7l1DTUjhCG_(xz|1c;A21`=iw%9|(vVSb~G z7)UrRDF1*zK$tLCoFo}j8H?9|kuVofewXTbj3kD}h~v?1@Y6pe95cot3L|%{-B618 L<Jax=xFP1h4!zc3 diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.2.map b/llvm/test/tools/dsymutil/Inputs/obfuscated.2.map deleted file mode 100644 index 6efca5960311..000000000000 --- a/llvm/test/tools/dsymutil/Inputs/obfuscated.2.map +++ /dev/null @@ -1,22 +0,0 @@ -BCSymbolMap Version: 2.0 -_two -_three -_four -_five -_six -LLVM version 3.9.0 (ssh://git@stash.sd.apple.com/devtools/clang.git c74ae34bd917b77f9c848bd599dfde2813fb509f) -main -main.c -/Volumes/Data/dev/BitcodeBuildTests/unit -one -one.c -two -two.c -three -three.c -four -four.c -five -five.c -six -six.c diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.arm64 b/llvm/test/tools/dsymutil/Inputs/obfuscated.arm64 deleted file mode 100644 index 8395798be17ff1aaea4397cd38c2b0f26f465cb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10434 zcmeHNO>7%Q6y9BDoiv0rZ4nA8Y649lMW~7i2~a^5LqhWdC4@*Igc#ZJCUNE1R_s7p zA&5+bdV>Q8Bv4Ng;({twRaJ4K2sjmS;edc6sv;z~lv6>J@9n&|S&uhq(j)AXo@d^h zZ@!&*GduP^@Ao%;|EJBeYzxu~ZH8_n$<lHVMJIHlZ~eWsfn%><`uWo%&-Wd8%3;6N zVOcGxucADK@*e0IRH>=-iP2X_r(b|!h<`D|XPU(GBY;ZHjJ`5c-|F{Yt@nxLq9RH@ zrK;XaRazVQF2AiOe{~aL(cA)QvQ~pSDoRzV%h^icGRL>}j^;y50}0Q!h54ji^Qi@| zQ1+J4!{qyb`Fa92>lWjityGut#d*e?d>5IoDa049*3BIaN-Y=P%olSiUz{uXcKv!> zW<FYT5tBpwRMNU`K$RLv&!ox2vdWuqSRD0b0w$?&D>YvVE$fzi*p`7%e-YZ^;dN1} zkWrP>i`h~^m8(k)d>yMAPkUV?%t!Z4*xtMko*O?oIXW^fd-zLZo;<+cn3Tp89vAT} zfEe+5IX(R>qo}YoPA1r`o4(=!%6RCWCQ&NqWtZnwCYxRI-q@P2OT#UzTPo3Iz_*ks z&U=-H@pbX|rg$=4JLKbS*1%V?^?ZL}zS4cs;}WlouaGZ#<TK+pnb3THGvDN4=^0%L zUwJuO%q)5plkbG9`TpSUCwilK#4CKbS$&tuH<;9XDIVY81JX0PR4P+07d+(;4iJ-X zu37W_%H8K4jOG!q@KsNjvAT_X6D^vrpF2$SNzdp~`26veGqdLS&M=>xb7ywQSIVB6 zr7N0z=M27cx8RE&b?l8J5Jw=6KpcTM0&xW52>kaVK+jWq@f&l7pX2tj{Tkc%vYli5 z2-^j=huE&N{S4c0u|4J6`XPmW%I3ITp1bLnn_9@{a$fOpzX}<tu<=OP7zi7WhK)fo z78jJa;>|8sJv>!sa(Jp%i<x{8*Nr8PKpcTM0&xW52*eSHBM?U*jzAoNI0A75;t2d- zBVg~dd)p7ViS~}<!S;RjemtW)M=h!(+7Xk7q53aZ{lB6-wtuokyfl6Utr{<B1#LBU z()hChUeXTR<F5vINlR>x@4&1yLedu7<7WcAq&2q3e-z*)?XeYp7$fI+;tx&BYO|ik zC&@{uL|3Bbn2z@eISj4m_!yotlsKfXMA9)Gp8*uXaS`4NP~woj5?#l1TmdM8<2!i& zgc67Jm54j0<0pV3IIh7vgwPO&^p#a`Ovm+Tj+=0=Fo*P&m2pf*8?D1I)PZ83@Va!u z{RMMK-!)EZIi{nRI0{h5x*wmm{a5>)`1GmJWFsxbIj$!Z+97*_wN13zZb$2Nw=+56 z-d%IMYwn?%`%um8tGNR;H&t_=thvW(Zgb7upPY0P$%$mk=gwVVKMoqlqW`V8xn2r+ zG+*`v8v%EF>!j1PV+JJOm_fF|ZW)lVV+Pp-yJbL{j~QeO?3Q6LV2};4TZW;4L6(1$ z;Sffr_Ya+YN1?%rKd!rJ1hqCGkoP3fh_g`$UPO(c)31Sp7fB=NylX)4B4`Aia196! zvPRIE)_{;829tXX+1uNY&FJ8M2*^_Xw?U;s1PJvenV&!oXO_91@{`G8gnRgjWp1bg z`AKGO2!m3HM{vO~D22TeGypXAQhE&W^xv+dH*?ycB;>QLq;(S_Hf^IOD80o-Zz;X| z;`yFy&@6O(`h3qfDAUk&Xcg^i&<~;OP&&lFhW-Gh^Og8-KuPF~BKuqVfLwu6^%5Bn z`feecHZKXCi)7d6147>$RMqdRSQeeVWFO~tnIoJ2TZ3r!=R$K#U`DQW2Woo0CO#@A HJHh-5T*?4# diff --git a/llvm/test/tools/dsymutil/Inputs/obfuscated.map b/llvm/test/tools/dsymutil/Inputs/obfuscated.map deleted file mode 100644 index 30fed8bf9b5a..000000000000 --- a/llvm/test/tools/dsymutil/Inputs/obfuscated.map +++ /dev/null @@ -1,17 +0,0 @@ -one -two -three -four -five -six -.str -Apple LLVM version 7.0.0 (clang-700.2.38.2) -main -main.c -/Users/steven/dev/alpena/tests/src -one.c -two.c -three.c -four.c -five.c -six.c diff --git a/llvm/test/tools/dsymutil/cmdline.test b/llvm/test/tools/dsymutil/cmdline.test index 36cf3f542695..814252b6e230 100644 --- a/llvm/test/tools/dsymutil/cmdline.test +++ b/llvm/test/tools/dsymutil/cmdline.test @@ -28,7 +28,6 @@ CHECK: -remarks-output-format <format> CHECK: -remarks-prepend-path <path> CHECK: -reproducer <mode> CHECK: -statistics -CHECK: -symbol-map CHECK: -symtab CHECK: {{-S}} CHECK: -toolchain diff --git a/llvm/tools/dsymutil/CMakeLists.txt b/llvm/tools/dsymutil/CMakeLists.txt index 53f882e90b4e..efe28bda68eb 100644 --- a/llvm/tools/dsymutil/CMakeLists.txt +++ b/llvm/tools/dsymutil/CMakeLists.txt @@ -32,7 +32,6 @@ add_llvm_tool(dsymutil MachOUtils.cpp Reproducer.cpp RelocationMap.cpp - SymbolMap.cpp DEPENDS intrinsics_gen diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp index 5ae5ecd556ad..677dfc44c54a 100644 --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -634,25 +634,19 @@ bool DwarfLinkerForBinary::linkImpl( DebugMap DebugMap(Map.getTriple(), Map.getBinaryPath()); - std::function<StringRef(StringRef)> TranslationLambda = [&](StringRef Input) { - assert(Options.Translator); - return Options.Translator(Input); - }; - std::unique_ptr<Linker> GeneralLinker = Linker::createLinker( [&](const Twine &Error, StringRef Context, const DWARFDie *DIE) { reportError(Error, Context, DIE); }, [&](const Twine &Warning, StringRef Context, const DWARFDie *DIE) { reportWarning(Warning, Context, DIE); - }, - Options.Translator ? TranslationLambda : nullptr); + }); std::unique_ptr<classic::DwarfStreamer> Streamer; if (!Options.NoOutput) { if (Expected<std::unique_ptr<classic::DwarfStreamer>> StreamerOrErr = classic::DwarfStreamer::createStreamer( - Map.getTriple(), ObjectType, OutFile, Options.Translator, + Map.getTriple(), ObjectType, OutFile, [&](const Twine &Warning, StringRef Context, const DWARFDie *DIE) { reportWarning(Warning, Context, DIE); @@ -866,8 +860,8 @@ bool DwarfLinkerForBinary::linkImpl( if (Map.getTriple().isOSDarwin() && !Map.getBinaryPath().empty() && ObjectType == Linker::OutputFileType::Object) return MachOUtils::generateDsymCompanion( - Options.VFS, Map, Options.Translator, - *Streamer->getAsmPrinter().OutStreamer, OutFile, RelocationsToApply); + Options.VFS, Map, *Streamer->getAsmPrinter().OutStreamer, OutFile, + RelocationsToApply); Streamer->finish(); return true; diff --git a/llvm/tools/dsymutil/LinkUtils.h b/llvm/tools/dsymutil/LinkUtils.h index fd9d985097d6..6aa0b847eebd 100644 --- a/llvm/tools/dsymutil/LinkUtils.h +++ b/llvm/tools/dsymutil/LinkUtils.h @@ -9,8 +9,6 @@ #ifndef LLVM_TOOLS_DSYMUTIL_LINKOPTIONS_H #define LLVM_TOOLS_DSYMUTIL_LINKOPTIONS_H -#include "SymbolMap.h" - #include "llvm/ADT/Twine.h" #include "llvm/Remarks/RemarkFormat.h" #include "llvm/Support/VirtualFileSystem.h" @@ -87,9 +85,6 @@ struct LinkOptions { /// The Resources directory in the .dSYM bundle. std::optional<std::string> ResourceDir; - /// Symbol map translator. - SymbolMapTranslator Translator; - /// Virtual File System. llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = vfs::getRealFileSystem(); diff --git a/llvm/tools/dsymutil/MachOUtils.cpp b/llvm/tools/dsymutil/MachOUtils.cpp index 3efc1aff8237..8e144d640ed0 100644 --- a/llvm/tools/dsymutil/MachOUtils.cpp +++ b/llvm/tools/dsymutil/MachOUtils.cpp @@ -373,7 +373,7 @@ static unsigned segmentLoadCommandSize(bool Is64Bit, unsigned NumSections) { // \a OutFile and it must be using a MachObjectWriter object to do so. bool generateDsymCompanion( llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, const DebugMap &DM, - SymbolMapTranslator &Translator, MCStreamer &MS, raw_fd_ostream &OutFile, + MCStreamer &MS, raw_fd_ostream &OutFile, const std::vector<MachOUtils::DwarfRelocationApplicationInfo> &RelocationsToApply) { auto &ObjectStreamer = static_cast<MCObjectStreamer &>(MS); @@ -509,12 +509,9 @@ bool generateDsymCompanion( } SmallString<0> NewSymtab; - std::function<StringRef(StringRef)> TranslationLambda = - Translator ? [&](StringRef Input) { return Translator(Input); } - : static_cast<std::function<StringRef(StringRef)>>(nullptr); // Legacy dsymutil puts an empty string at the start of the line table. // thus we set NonRelocatableStringpool(,PutEmptyString=true) - NonRelocatableStringpool NewStrings(TranslationLambda, true); + NonRelocatableStringpool NewStrings(true); unsigned NListSize = Is64Bit ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); unsigned NumSyms = 0; uint64_t NewStringsSize = 0; diff --git a/llvm/tools/dsymutil/MachOUtils.h b/llvm/tools/dsymutil/MachOUtils.h index 059d9fdd788a..0229647b00f8 100644 --- a/llvm/tools/dsymutil/MachOUtils.h +++ b/llvm/tools/dsymutil/MachOUtils.h @@ -8,8 +8,6 @@ #ifndef LLVM_TOOLS_DSYMUTIL_MACHOUTILS_H #define LLVM_TOOLS_DSYMUTIL_MACHOUTILS_H -#include "SymbolMap.h" - #include "llvm/ADT/StringRef.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/VirtualFileSystem.h" @@ -59,7 +57,7 @@ bool generateUniversalBinary(SmallVectorImpl<ArchAndFile> &ArchFiles, StringRef SDKPath, bool Fat64 = false); bool generateDsymCompanion( llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, const DebugMap &DM, - SymbolMapTranslator &Translator, MCStreamer &MS, raw_fd_ostream &OutFile, + MCStreamer &MS, raw_fd_ostream &OutFile, const std::vector<MachOUtils::DwarfRelocationApplicationInfo> &RelocationsToApply); diff --git a/llvm/tools/dsymutil/Options.td b/llvm/tools/dsymutil/Options.td index a4e4c6c4cdb9..d8cec0cb2c41 100644 --- a/llvm/tools/dsymutil/Options.td +++ b/llvm/tools/dsymutil/Options.td @@ -128,12 +128,6 @@ def object_prefix_map: Separate<["--", "-"], "object-prefix-map">, Group<grp_general>; def: Joined<["--", "-"], "object-prefix-map=">, Alias<object_prefix_map>; -def symbolmap: Separate<["--", "-"], "symbol-map">, - MetaVarName<"<bcsymbolmap>">, - HelpText<"Updates the existing dSYMs inplace using symbol map specified.">, - Group<grp_general>; -def: Joined<["--", "-"], "symbol-map=">, Alias<symbolmap>; - def arch: Separate<["--", "-"], "arch">, MetaVarName<"<arch>">, HelpText<"Link DWARF debug information only for specified CPU architecture" diff --git a/llvm/tools/dsymutil/SymbolMap.cpp b/llvm/tools/dsymutil/SymbolMap.cpp deleted file mode 100644 index c55362e5f775..000000000000 --- a/llvm/tools/dsymutil/SymbolMap.cpp +++ /dev/null @@ -1,157 +0,0 @@ -//===- tools/dsymutil/SymbolMap.cpp ---------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "SymbolMap.h" -#include "DebugMap.h" -#include "MachOUtils.h" - -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/WithColor.h" - -#ifdef __APPLE__ -#include <CoreFoundation/CoreFoundation.h> -#include <uuid/uuid.h> -#endif - -namespace llvm { -namespace dsymutil { - -StringRef SymbolMapTranslator::operator()(StringRef Input) { - if (!Input.starts_with("__hidden#") && !Input.starts_with("___hidden#")) - return Input; - - StringRef Line = Input.drop_front(sizeof("__hidden#") - 1); - bool MightNeedUnderscore = Line.consume_front("#"); - - std::size_t LineNumber = std::numeric_limits<std::size_t>::max(); - Line.split('_').first.getAsInteger(10, LineNumber); - if (LineNumber >= UnobfuscatedStrings.size()) { - WithColor::warning() << "reference to a unexisting unobfuscated string " - << Input << ": symbol map mismatch?\n" - << Line << '\n'; - return Input; - } - - const std::string &Translation = UnobfuscatedStrings[LineNumber]; - if (!MightNeedUnderscore || !MangleNames) - return Translation; - - // Objective-C symbols for the MachO symbol table start with a \1. Please see - // `MangleContext::mangleObjCMethodName` in clang. - if (Translation[0] == 1) - return StringRef(Translation).drop_front(); - - // We need permanent storage for the string we are about to create. Just - // append it to the vector containing translations. This should only happen - // during MachO symbol table translation, thus there should be no risk on - // exponential growth. - UnobfuscatedStrings.emplace_back("_" + Translation); - return UnobfuscatedStrings.back(); -} - -SymbolMapTranslator SymbolMapLoader::Load(StringRef InputFile, - const DebugMap &Map) const { - if (SymbolMap.empty()) - return {}; - - std::string SymbolMapPath = SymbolMap; - -#if __APPLE__ - // Look through the UUID Map. - if (sys::fs::is_directory(SymbolMapPath) && !Map.getUUID().empty()) { - uuid_string_t UUIDString; - uuid_unparse_upper((const uint8_t *)Map.getUUID().data(), UUIDString); - - SmallString<256> PlistPath( - sys::path::parent_path(sys::path::parent_path(InputFile))); - sys::path::append(PlistPath, StringRef(UUIDString).str() + ".plist"); - - CFStringRef plistFile = CFStringCreateWithCString( - kCFAllocatorDefault, PlistPath.c_str(), kCFStringEncodingUTF8); - CFURLRef fileURL = CFURLCreateWithFileSystemPath( - kCFAllocatorDefault, plistFile, kCFURLPOSIXPathStyle, false); - CFReadStreamRef resourceData = - CFReadStreamCreateWithFile(kCFAllocatorDefault, fileURL); - if (resourceData) { - CFReadStreamOpen(resourceData); - CFDictionaryRef plist = (CFDictionaryRef)CFPropertyListCreateWithStream( - kCFAllocatorDefault, resourceData, 0, kCFPropertyListImmutable, - nullptr, nullptr); - - if (plist) { - if (CFDictionaryContainsKey(plist, CFSTR("DBGOriginalUUID"))) { - CFStringRef OldUUID = (CFStringRef)CFDictionaryGetValue( - plist, CFSTR("DBGOriginalUUID")); - - StringRef UUID(CFStringGetCStringPtr(OldUUID, kCFStringEncodingUTF8)); - SmallString<256> BCSymbolMapPath(SymbolMapPath); - sys::path::append(BCSymbolMapPath, UUID.str() + ".bcsymbolmap"); - SymbolMapPath = std::string(BCSymbolMapPath); - } - CFRelease(plist); - } - CFReadStreamClose(resourceData); - CFRelease(resourceData); - } - CFRelease(fileURL); - CFRelease(plistFile); - } -#endif - - if (sys::fs::is_directory(SymbolMapPath)) { - SymbolMapPath += (Twine("/") + sys::path::filename(InputFile) + "-" + - MachOUtils::getArchName(Map.getTriple().getArchName()) + - ".bcsymbolmap") - .str(); - } - - auto ErrOrMemBuffer = MemoryBuffer::getFile(SymbolMapPath); - if (auto EC = ErrOrMemBuffer.getError()) { - WithColor::warning() << SymbolMapPath << ": " << EC.message() - << ": not unobfuscating.\n"; - return {}; - } - - std::vector<std::string> UnobfuscatedStrings; - auto &MemBuf = **ErrOrMemBuffer; - StringRef Data(MemBuf.getBufferStart(), - MemBuf.getBufferEnd() - MemBuf.getBufferStart()); - StringRef LHS; - std::tie(LHS, Data) = Data.split('\n'); - bool MangleNames = false; - - // Check version string first. - if (!LHS.starts_with("BCSymbolMap Version:")) { - // Version string not present, warns but try to parse it. - WithColor::warning() << SymbolMapPath - << " is missing version string: assuming 1.0.\n"; - UnobfuscatedStrings.emplace_back(LHS); - } else if (LHS.equals("BCSymbolMap Version: 1.0")) { - MangleNames = true; - } else if (LHS.equals("BCSymbolMap Version: 2.0")) { - MangleNames = false; - } else { - StringRef VersionNum; - std::tie(LHS, VersionNum) = LHS.split(':'); - WithColor::warning() << SymbolMapPath - << " has unsupported symbol map version" << VersionNum - << ": not unobfuscating.\n"; - return {}; - } - - while (!Data.empty()) { - std::tie(LHS, Data) = Data.split('\n'); - UnobfuscatedStrings.emplace_back(LHS); - } - - return SymbolMapTranslator(std::move(UnobfuscatedStrings), MangleNames); -} - -} // namespace dsymutil -} // namespace llvm diff --git a/llvm/tools/dsymutil/SymbolMap.h b/llvm/tools/dsymutil/SymbolMap.h deleted file mode 100644 index 977de31a5a17..000000000000 --- a/llvm/tools/dsymutil/SymbolMap.h +++ /dev/null @@ -1,53 +0,0 @@ -//=- tools/dsymutil/SymbolMap.h -----------------------------------*- C++ -*-=// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TOOLS_DSYMUTIL_SYMBOLMAP_H -#define LLVM_TOOLS_DSYMUTIL_SYMBOLMAP_H - -#include "llvm/ADT/StringRef.h" - -#include <string> -#include <vector> - -namespace llvm { -namespace dsymutil { -class DebugMap; - -/// Callable class to unobfuscate strings based on a BCSymbolMap. -class SymbolMapTranslator { -public: - SymbolMapTranslator() : MangleNames(false) {} - - SymbolMapTranslator(std::vector<std::string> UnobfuscatedStrings, - bool MangleNames) - : UnobfuscatedStrings(std::move(UnobfuscatedStrings)), - MangleNames(MangleNames) {} - - StringRef operator()(StringRef Input); - - operator bool() const { return !UnobfuscatedStrings.empty(); } - -private: - std::vector<std::string> UnobfuscatedStrings; - bool MangleNames; -}; - -/// Class to initialize SymbolMapTranslators from a BCSymbolMap. -class SymbolMapLoader { -public: - SymbolMapLoader(std::string SymbolMap) : SymbolMap(std::move(SymbolMap)) {} - - SymbolMapTranslator Load(StringRef InputFile, const DebugMap &Map) const; - -private: - const std::string SymbolMap; -}; -} // namespace dsymutil -} // namespace llvm - -#endif // LLVM_TOOLS_DSYMUTIL_SYMBOLMAP_H diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp index 25e281c415e7..bc968b6387b6 100644 --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/tools/dsymutil/dsymutil.cpp @@ -108,7 +108,6 @@ struct DsymutilOptions { bool Flat = false; bool InputIsYAMLDebugMap = false; bool ForceKeepFunctionForStatic = false; - std::string SymbolMap; std::string OutputFile; std::string Toolchain; std::string ReproducerPath; @@ -341,12 +340,6 @@ static Expected<DsymutilOptions> getOptions(opt::InputArgList &Args) { return DWARFLinkerType.takeError(); } - if (opt::Arg *SymbolMap = Args.getLastArg(OPT_symbolmap)) - Options.SymbolMap = SymbolMap->getValue(); - - if (Args.hasArg(OPT_symbolmap)) - Options.LinkOpts.Update = true; - if (Expected<std::vector<std::string>> InputFiles = getInputs(Args, Options.LinkOpts.Update)) { Options.InputFiles = std::move(*InputFiles); @@ -560,8 +553,7 @@ getOutputFileName(StringRef InputFile, const DsymutilOptions &Options) { return OutputLocation(Options.OutputFile); // When updating, do in place replacement. - if (Options.OutputFile.empty() && - (Options.LinkOpts.Update || !Options.SymbolMap.empty())) + if (Options.OutputFile.empty() && Options.LinkOpts.Update) return OutputLocation(std::string(InputFile)); // When dumping the debug map, just return an empty output location. This @@ -668,8 +660,6 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) { return EXIT_FAILURE; } - SymbolMapLoader SymMapLoader(Options.SymbolMap); - for (auto &InputFile : Options.InputFiles) { // Dump the symbol table for each input file and requested arch if (Options.DumpStab) { @@ -760,9 +750,6 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) { if (Options.DumpDebugMap) continue; - if (!Options.SymbolMap.empty()) - Options.LinkOpts.Translator = SymMapLoader.Load(InputFile, *Map); - if (Map->begin() == Map->end()) { std::lock_guard<std::mutex> Guard(ErrorHandlerMutex); WithColor::warning() diff --git a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp index bd17f3c4a659..285dcf75ecd9 100644 --- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp +++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp @@ -338,9 +338,9 @@ Error linkDebugInfoImpl(object::ObjectFile &File, const Options &Options, Triple TargetTriple = File.makeTriple(); std::unique_ptr<classic::DwarfStreamer> Streamer; if (Expected<std::unique_ptr<classic::DwarfStreamer>> StreamerOrErr = - classic::DwarfStreamer::createStreamer( - TargetTriple, Linker::OutputFileType::Object, OutStream, nullptr, - ReportWarn)) + classic::DwarfStreamer::createStreamer(TargetTriple, + Linker::OutputFileType::Object, + OutStream, ReportWarn)) Streamer = std::move(*StreamerOrErr); else return StreamerOrErr.takeError(); -- GitLab From 8af3f74294d5e6ccf4e5c91ad5c25a1d7384ec1c Mon Sep 17 00:00:00 2001 From: Kazu Hirata <kazu@google.com> Date: Tue, 19 Mar 2024 12:37:32 -0700 Subject: [PATCH 132/307] Revert "[BOLT] Update DIEStreamer (#85818)" This reverts commit e4f9175d23950ecaef32db075ed47dafe3be555c. commit 3176c157190c80b4279dec86c4b9b84472d8ccac Author: Andres Villegas <andresvi@google.com> Date: Tue Mar 19 10:58:31 2024 -0700 reverted 43a2ec483fe08064b53a6293682e9bab97df61a0. --- bolt/lib/Rewrite/DWARFRewriter.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index 8dc7b90a6e30..85c2397dcc5b 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -283,9 +283,10 @@ public: DIEStreamer(DIEBuilder *DIEBldr, DWARFRewriter &Rewriter, DWARFLinkerBase::OutputFileType OutFileType, raw_pwrite_stream &OutFile, + std::function<StringRef(StringRef Input)> Translator, DWARFLinkerBase::MessageHandlerTy Warning) - : DwarfStreamer(OutFileType, OutFile, Warning), DIEBldr(DIEBldr), - Rewriter(Rewriter){}; + : DwarfStreamer(OutFileType, OutFile, Translator, Warning), + DIEBldr(DIEBldr), Rewriter(Rewriter){}; using DwarfStreamer::emitCompileUnitHeader; @@ -468,6 +469,7 @@ createDIEStreamer(const Triple &TheTriple, raw_pwrite_stream &OutFile, std::unique_ptr<DIEStreamer> Streamer = std::make_unique<DIEStreamer>( &DIEBldr, Rewriter, DWARFLinkerBase::OutputFileType::Object, OutFile, + [](StringRef Input) -> StringRef { return Input; }, [&](const Twine &Warning, StringRef Context, const DWARFDie *) {}); Error Err = Streamer->init(TheTriple, Swift5ReflectionSegmentName); if (Err) -- GitLab From 4b61d5bd6155f43792dd37a8975df68365b1e24a Mon Sep 17 00:00:00 2001 From: "Balaji V. Iyer" <43187390+bviyer@users.noreply.github.com> Date: Tue, 19 Mar 2024 14:44:03 -0500 Subject: [PATCH 133/307] [ArmNeonTransforms][Bazel] Added appropriate deps for BUILD.bazel file. (#85852) --- utils/bazel/llvm-project-overlay/mlir/BUILD.bazel | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel index 57d4e1a91f06..ba3f60380d34 100644 --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -1937,16 +1937,13 @@ cc_library( deps = [ ":ArithDialect", ":ArmNeonDialect", - ":ArmNeonIncGen", + ":DialectUtils", ":FuncDialect", ":IR", ":LLVMDialect", - ":SideEffectInterfaces", ":Support", ":Transforms", ":VectorDialect", - "//llvm:Core", - "//llvm:Support", ], ) -- GitLab From 3dc1b5044e25fc7e574719355091fccddad29ce4 Mon Sep 17 00:00:00 2001 From: Joseph Huber <huberjn@outlook.com> Date: Tue, 19 Mar 2024 14:44:59 -0500 Subject: [PATCH 134/307] [libc] Make 'printf' converter output "(null)" instead of "null" (#85845) Summary: Currently we print `null` for the null pointer in a `%s` expression. Although it's not defined by the standard, other implementations choose to use `(null)` to indicate this. We also currently print `(nullptr)` so I think it's more consistent to use parens in both cases. --- libc/docs/dev/printf_behavior.rst | 2 ++ libc/docs/dev/undefined_behavior.rst | 7 +++++++ libc/src/stdio/printf_core/string_converter.h | 2 +- libc/test/src/stdio/sprintf_test.cpp | 4 ++-- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libc/docs/dev/printf_behavior.rst b/libc/docs/dev/printf_behavior.rst index 00d6c83f4b0d..9548bfda57aa 100644 --- a/libc/docs/dev/printf_behavior.rst +++ b/libc/docs/dev/printf_behavior.rst @@ -1,3 +1,5 @@ +.. _printf_behavior: + ==================================== Printf Behavior Under All Conditions ==================================== diff --git a/libc/docs/dev/undefined_behavior.rst b/libc/docs/dev/undefined_behavior.rst index 3a06b7007feb..50e8bdde89dd 100644 --- a/libc/docs/dev/undefined_behavior.rst +++ b/libc/docs/dev/undefined_behavior.rst @@ -74,3 +74,10 @@ The POSIX.1 standard does not delineate the behavior consequent to invoking hsea Path without Leading Slashs in shm_open ---------------------------------------- POSIX.1 leaves that when the name of a shared memory object does not begin with a slash, the behavior is implementation defined. In such cases, the shm_open in LLVM libc is implemented to behave as if the name began with a slash. + +Handling of NULL arguments to the 's' format specifier +------------------------------------------------------ +The C standard does not specify behavior for ``printf("%s", NULL)``. We will +print the string literal ``(null)`` unless using the +``LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS`` option described in :ref:`printf +behavior<printf_behavior>`. diff --git a/libc/src/stdio/printf_core/string_converter.h b/libc/src/stdio/printf_core/string_converter.h index 04dc5a06da22..9e05591079fa 100644 --- a/libc/src/stdio/printf_core/string_converter.h +++ b/libc/src/stdio/printf_core/string_converter.h @@ -25,7 +25,7 @@ LIBC_INLINE int convert_string(Writer *writer, const FormatSection &to_conv) { #ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS if (str_ptr == nullptr) { - str_ptr = "null"; + str_ptr = "(null)"; } #endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS diff --git a/libc/test/src/stdio/sprintf_test.cpp b/libc/test/src/stdio/sprintf_test.cpp index ab8bdb23b118..8dde95d02a96 100644 --- a/libc/test/src/stdio/sprintf_test.cpp +++ b/libc/test/src/stdio/sprintf_test.cpp @@ -121,8 +121,8 @@ TEST(LlvmLibcSPrintfTest, StringConv) { #ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS written = LIBC_NAMESPACE::sprintf(buff, "%s", nullptr); - EXPECT_EQ(written, 4); - ASSERT_STREQ(buff, "null"); + EXPECT_EQ(written, 6); + ASSERT_STREQ(buff, "(null)"); #endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS } -- GitLab From 41283403f5a201c93b64b0f5b0e3ee3bc5f5e2b1 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jonas@devlieghere.com> Date: Tue, 19 Mar 2024 12:45:17 -0700 Subject: [PATCH 135/307] [BOLT] Update DWARFRewriter for 32a6e9d66945 --- bolt/lib/Rewrite/DWARFRewriter.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index 85c2397dcc5b..8dc7b90a6e30 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -283,10 +283,9 @@ public: DIEStreamer(DIEBuilder *DIEBldr, DWARFRewriter &Rewriter, DWARFLinkerBase::OutputFileType OutFileType, raw_pwrite_stream &OutFile, - std::function<StringRef(StringRef Input)> Translator, DWARFLinkerBase::MessageHandlerTy Warning) - : DwarfStreamer(OutFileType, OutFile, Translator, Warning), - DIEBldr(DIEBldr), Rewriter(Rewriter){}; + : DwarfStreamer(OutFileType, OutFile, Warning), DIEBldr(DIEBldr), + Rewriter(Rewriter){}; using DwarfStreamer::emitCompileUnitHeader; @@ -469,7 +468,6 @@ createDIEStreamer(const Triple &TheTriple, raw_pwrite_stream &OutFile, std::unique_ptr<DIEStreamer> Streamer = std::make_unique<DIEStreamer>( &DIEBldr, Rewriter, DWARFLinkerBase::OutputFileType::Object, OutFile, - [](StringRef Input) -> StringRef { return Input; }, [&](const Twine &Warning, StringRef Context, const DWARFDie *) {}); Error Err = Streamer->init(TheTriple, Swift5ReflectionSegmentName); if (Err) -- GitLab From 5cccc405e3981dfb97d5fee05b44a2ac6388191c Mon Sep 17 00:00:00 2001 From: Joseph Huber <huberjn@outlook.com> Date: Tue, 19 Mar 2024 14:45:09 -0500 Subject: [PATCH 136/307] Revert "[OpenMP] Disable flaky barrier fence test (#85093)" This reverts commit cd8843f87af2f04a85dda12b37738596cbf4cd5e. Originally disabled to try to unstick the AMD build bot, didn't make a difference after a week so it goes back in. --- openmp/libomptarget/test/offloading/barrier_fence.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openmp/libomptarget/test/offloading/barrier_fence.c b/openmp/libomptarget/test/offloading/barrier_fence.c index 9c3027f091d3..b9a8ca27965a 100644 --- a/openmp/libomptarget/test/offloading/barrier_fence.c +++ b/openmp/libomptarget/test/offloading/barrier_fence.c @@ -3,10 +3,6 @@ // RUN: %libomptarget-compileopt-generic -fopenmp-offload-mandatory -O3 // RUN: %libomptarget-run-generic -// FIXME: This test is flaky on all targets -// UNSUPPORTED: amdgcn-amd-amdhsa -// UNSUPPORTED: nvptx64-nvidia-cuda -// UNSUPPORTED: nvptx64-nvidia-cuda-LTO // UNSUPPORTED: aarch64-unknown-linux-gnu // UNSUPPORTED: aarch64-unknown-linux-gnu-LTO // UNSUPPORTED: x86_64-pc-linux-gnu -- GitLab From 85b6af198fdad9aead0449a645d839b1c7635dfd Mon Sep 17 00:00:00 2001 From: OverMighty <its.overmighty@gmail.com> Date: Tue, 19 Mar 2024 19:47:01 +0000 Subject: [PATCH 137/307] [libc][math][c23] Add linux/* entrypoints for nextup* and nextdown* (#85803) See https://github.com/llvm/llvm-project/pull/85484#discussion_r1526971653. There already were entrypoints for linux/x86_64. I haven't tested on the other targets and will rely on the buildbots. --- libc/config/linux/aarch64/entrypoints.txt | 8 ++++++++ libc/config/linux/arm/entrypoints.txt | 6 ++++++ libc/config/linux/riscv/entrypoints.txt | 8 ++++++++ libc/config/linux/x86_64/entrypoints.txt | 6 +++--- libc/docs/math/index.rst | 16 ++++++++-------- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 58502e4ec1c6..dbf81c284e78 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -417,9 +417,15 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.nextafter libc.src.math.nextafterf libc.src.math.nextafterl + libc.src.math.nextdown + libc.src.math.nextdownf + libc.src.math.nextdownl libc.src.math.nexttoward libc.src.math.nexttowardf libc.src.math.nexttowardl + libc.src.math.nextup + libc.src.math.nextupf + libc.src.math.nextupl libc.src.math.powf libc.src.math.remainderf libc.src.math.remainder @@ -472,6 +478,8 @@ if(LIBC_TYPES_HAS_FLOAT128) libc.src.math.modff128 libc.src.math.nanf128 libc.src.math.nextafterf128 + libc.src.math.nextdownf128 + libc.src.math.nextupf128 libc.src.math.rintf128 libc.src.math.roundf128 libc.src.math.sqrtf128 diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt index bf1559b2f023..3bc5d8efc9d2 100644 --- a/libc/config/linux/arm/entrypoints.txt +++ b/libc/config/linux/arm/entrypoints.txt @@ -285,9 +285,15 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.nextafter libc.src.math.nextafterf libc.src.math.nextafterl + libc.src.math.nextdown + libc.src.math.nextdownf + libc.src.math.nextdownl libc.src.math.nexttoward libc.src.math.nexttowardf libc.src.math.nexttowardl + libc.src.math.nextup + libc.src.math.nextupf + libc.src.math.nextupl libc.src.math.powf libc.src.math.remainder libc.src.math.remainderf diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index d789f03fedc4..b42a55a4d712 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -425,9 +425,15 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.nextafter libc.src.math.nextafterf libc.src.math.nextafterl + libc.src.math.nextdown + libc.src.math.nextdownf + libc.src.math.nextdownl libc.src.math.nexttoward libc.src.math.nexttowardf libc.src.math.nexttowardl + libc.src.math.nextup + libc.src.math.nextupf + libc.src.math.nextupl libc.src.math.powf libc.src.math.remainderf libc.src.math.remainder @@ -480,6 +486,8 @@ if(LIBC_TYPES_HAS_FLOAT128) libc.src.math.modff128 libc.src.math.nanf128 libc.src.math.nextafterf128 + libc.src.math.nextdownf128 + libc.src.math.nextupf128 libc.src.math.rintf128 libc.src.math.roundf128 libc.src.math.sqrtf128 diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index f81d334e9e78..e8cf11266624 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -429,12 +429,12 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.nextafter libc.src.math.nextafterf libc.src.math.nextafterl - libc.src.math.nexttoward - libc.src.math.nexttowardf - libc.src.math.nexttowardl libc.src.math.nextdown libc.src.math.nextdownf libc.src.math.nextdownl + libc.src.math.nexttoward + libc.src.math.nexttowardf + libc.src.math.nexttowardl libc.src.math.nextup libc.src.math.nextupf libc.src.math.nextupl diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst index dbcffc1432e8..d337d060fb5d 100644 --- a/libc/docs/math/index.rst +++ b/libc/docs/math/index.rst @@ -275,13 +275,13 @@ Basic Operations +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | nextafterf128| |check| | |check| | | |check| | | | | | | | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ -| nextdown | |check| | | | | | | | | | | | | +| nextdown | |check| | |check| | |check| | |check| | | | | | | | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ -| nextdownf | |check| | | | | | | | | | | | | +| nextdownf | |check| | |check| | |check| | |check| | | | | | | | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ -| nextdownl | |check| | | | | | | | | | | | | +| nextdownl | |check| | |check| | |check| | |check| | | | | | | | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ -| nextdownf128 | |check| | | | | | | | | | | | | +| nextdownf128 | |check| | |check| | | |check| | | | | | | | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | nexttoward | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ @@ -289,13 +289,13 @@ Basic Operations +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | nexttowardl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ -| nextup | |check| | | | | | | | | | | | | +| nextup | |check| | |check| | |check| | |check| | | | | | | | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ -| nextupf | |check| | | | | | | | | | | | | +| nextupf | |check| | |check| | |check| | |check| | | | | | | | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ -| nextupl | |check| | | | | | | | | | | | | +| nextupl | |check| | |check| | |check| | |check| | | | | | | | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ -| nextupf128 | |check| | | | | | | | | | | | | +| nextupf128 | |check| | |check| | | |check| | | | | | | | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | remainder | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ -- GitLab From 4549f8910ed9bc6479b6e641c2611d4b36a2cd63 Mon Sep 17 00:00:00 2001 From: LLVM GN Syncbot <llvmgnsyncbot@gmail.com> Date: Tue, 19 Mar 2024 19:52:29 +0000 Subject: [PATCH 138/307] [gn build] Port 28c1279db354 --- .../gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn index 3b41f9b4007f..cd90c7752e16 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn @@ -81,6 +81,7 @@ static_library("bugprone") { "SuspiciousReallocUsageCheck.cpp", "SuspiciousSemicolonCheck.cpp", "SuspiciousStringCompareCheck.cpp", + "SuspiciousStringviewDataUsageCheck.cpp", "SwappedArgumentsCheck.cpp", "SwitchMissingDefaultCaseCheck.cpp", "TerminatingContinueCheck.cpp", -- GitLab From ac7a456181a8506c1adbe97dac72775b89a4fc24 Mon Sep 17 00:00:00 2001 From: LLVM GN Syncbot <llvmgnsyncbot@gmail.com> Date: Tue, 19 Mar 2024 19:52:30 +0000 Subject: [PATCH 139/307] [gn build] Port 32a6e9d66945 --- llvm/utils/gn/secondary/llvm/tools/dsymutil/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/utils/gn/secondary/llvm/tools/dsymutil/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/dsymutil/BUILD.gn index d22d0433656e..5710e07b07cf 100644 --- a/llvm/utils/gn/secondary/llvm/tools/dsymutil/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/tools/dsymutil/BUILD.gn @@ -31,7 +31,6 @@ driver_executable("dsymutil") { "MachOUtils.cpp", "RelocationMap.cpp", "Reproducer.cpp", - "SymbolMap.cpp", "dsymutil.cpp", ] if (host_os == "mac") { -- GitLab From 3cd9dccbb4235e057d0e53ab0b9673f3766800d4 Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulkirth@google.com> Date: Tue, 19 Mar 2024 13:03:02 -0700 Subject: [PATCH 140/307] [cmake] Disable using FatLTO on Apple platforms (#85708) FatLTO currently only supports ELF, so ensure we don't use it on non-ELF platforms. --- llvm/cmake/modules/AddLLVM.cmake | 2 +- llvm/cmake/modules/HandleLLVMOptions.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index d84d9d7cca68..745935f14051 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1637,7 +1637,7 @@ function(add_unittest test_suite test_name) # The runtime benefits of LTO don't outweight the compile time costs for tests. if(LLVM_ENABLE_LTO) if((UNIX OR MINGW) AND LINKER_IS_LLD) - if(LLVM_ENABLE_FATLTO) + if(LLVM_ENABLE_FATLTO AND NOT APPLE) # When using FatLTO, just use relocatable linking. set_property(TARGET ${test_name} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--no-fat-lto-objects") diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake index 92fa9839db65..185266c0861e 100644 --- a/llvm/cmake/modules/HandleLLVMOptions.cmake +++ b/llvm/cmake/modules/HandleLLVMOptions.cmake @@ -1282,7 +1282,7 @@ elseif(LLVM_ENABLE_LTO) endif() endif() -if(LLVM_ENABLE_FATLTO AND (FUCHSIA OR UNIX)) +if(LLVM_ENABLE_FATLTO AND UNIX AND NOT APPLE) append("-ffat-lto-objects" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) if(NOT LINKER_IS_LLD_LINK) append("-ffat-lto-objects" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS) -- GitLab From ffd08c7759000f55332f1657a1fab64a7adc03fd Mon Sep 17 00:00:00 2001 From: Stephen Tozer <stephen.tozer@sony.com> Date: Tue, 19 Mar 2024 20:07:07 +0000 Subject: [PATCH 141/307] [RemoveDIs][NFC] Rename DPValue -> DbgVariableRecord (#85216) This is the major rename patch that prior patches have built towards. The DPValue class is being renamed to DbgVariableRecord, which reflects the updated terminology for the "final" implementation of the RemoveDI feature. This is a pure string substitution + clang-format patch. The only manual component of this patch was determining where to perform these string substitutions: `DPValue` and `DPV` are almost exclusively used for DbgRecords, *except* for: - llvm/lib/target, where 'DP' is used to mean double-precision, and so appears as part of .td files and in variable names. NB: There is a single existing use of `DPValue` here that refers to debug info, which I've manually updated. - llvm/tools/gold, where 'LDPV' is used as a prefix for symbol visibility enums. Outside of these places, I've applied several basic string substitutions, with the intent that they only affect DbgRecord-related identifiers; I've checked them as I went through to verify this, with reasonable confidence that there are no unintended changes that slipped through the cracks. The substitutions applied are all case-sensitive, and are applied in the order shown: ``` DPValue -> DbgVariableRecord DPVal -> DbgVarRec DPV -> DVR ``` Following the previous rename patches, it should be the case that there are no instances of any of these strings that are meant to refer to the general case of DbgRecords, or anything other than the DPValue class. The idea behind this patch is therefore that pure string substitution is correct in all cases as long as these assumptions hold. --- clang/lib/CodeGen/CGStmtOpenMP.cpp | 4 +- llvm/docs/RemoveDIsDebugInfo.md | 10 +- .../llvm/CodeGen/FunctionLoweringInfo.h | 2 +- llvm/include/llvm/IR/BasicBlock.h | 6 +- llvm/include/llvm/IR/DIBuilder.h | 7 +- llvm/include/llvm/IR/DebugInfo.h | 40 +- llvm/include/llvm/IR/DebugInfoMetadata.h | 12 +- .../include/llvm/IR/DebugProgramInstruction.h | 157 +++-- llvm/include/llvm/IR/Metadata.h | 26 +- llvm/include/llvm/Transforms/Utils/Local.h | 8 +- .../Transforms/Utils/MemoryTaggingSupport.h | 2 +- .../llvm/Transforms/Utils/SSAUpdater.h | 7 +- .../llvm/Transforms/Utils/ValueMapper.h | 36 +- llvm/lib/AsmParser/LLParser.cpp | 14 +- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 20 +- llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 6 +- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 29 +- llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 48 +- .../CodeGen/AssignmentTrackingAnalysis.cpp | 154 +++-- llvm/lib/CodeGen/CodeGenPrepare.cpp | 60 +- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 18 +- llvm/lib/CodeGen/SelectOptimize.cpp | 4 +- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 24 +- .../SelectionDAG/FunctionLoweringInfo.cpp | 2 +- .../SelectionDAG/SelectionDAGBuilder.cpp | 49 +- .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 12 +- llvm/lib/IR/AsmWriter.cpp | 61 +- llvm/lib/IR/AutoUpgrade.cpp | 24 +- llvm/lib/IR/BasicBlock.cpp | 26 +- llvm/lib/IR/DIBuilder.cpp | 38 +- llvm/lib/IR/DebugInfo.cpp | 122 ++-- llvm/lib/IR/DebugInfoMetadata.cpp | 8 +- llvm/lib/IR/DebugProgramInstruction.cpp | 217 +++--- llvm/lib/IR/Instruction.cpp | 10 +- llvm/lib/IR/LLVMContextImpl.cpp | 4 +- llvm/lib/IR/LLVMContextImpl.h | 16 +- llvm/lib/IR/LegacyPassManager.cpp | 5 +- llvm/lib/IR/Metadata.cpp | 31 +- llvm/lib/IR/Value.cpp | 8 +- llvm/lib/IR/Verifier.cpp | 144 ++-- .../Target/AArch64/AArch64StackTagging.cpp | 2 +- llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 85 +-- llvm/lib/Transforms/Coroutines/CoroInternal.h | 4 +- llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 25 +- llvm/lib/Transforms/IPO/IROutliner.cpp | 4 +- llvm/lib/Transforms/IPO/MergeFunctions.cpp | 62 +- .../Transforms/IPO/ThinLTOBitcodeWriter.cpp | 4 +- .../InstCombine/InstCombineCalls.cpp | 2 +- .../InstCombine/InstCombineInternal.h | 7 +- .../InstCombine/InstructionCombining.cpp | 136 ++-- .../Instrumentation/HWAddressSanitizer.cpp | 7 +- llvm/lib/Transforms/Scalar/ADCE.cpp | 15 +- .../Scalar/DeadStoreElimination.cpp | 5 +- llvm/lib/Transforms/Scalar/JumpThreading.cpp | 46 +- .../Transforms/Scalar/LoopStrengthReduce.cpp | 20 +- llvm/lib/Transforms/Scalar/SROA.cpp | 48 +- .../Transforms/Scalar/SimpleLoopUnswitch.cpp | 5 +- .../Scalar/SpeculativeExecution.cpp | 23 +- llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 85 +-- llvm/lib/Transforms/Utils/CloneFunction.cpp | 24 +- llvm/lib/Transforms/Utils/CodeExtractor.cpp | 30 +- llvm/lib/Transforms/Utils/InlineFunction.cpp | 24 +- llvm/lib/Transforms/Utils/LCSSA.cpp | 10 +- llvm/lib/Transforms/Utils/Local.cpp | 377 +++++----- .../Transforms/Utils/LoopRotationUtils.cpp | 53 +- .../Transforms/Utils/LoopUnrollRuntime.cpp | 5 +- llvm/lib/Transforms/Utils/LoopUtils.cpp | 26 +- llvm/lib/Transforms/Utils/MemoryOpRemark.cpp | 2 +- .../Transforms/Utils/MemoryTaggingSupport.cpp | 14 +- .../Utils/PromoteMemoryToRegister.cpp | 70 +- llvm/lib/Transforms/Utils/SSAUpdater.cpp | 26 +- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 69 +- llvm/lib/Transforms/Utils/ValueMapper.cpp | 12 +- llvm/test/DebugInfo/dpvalue-print-nocrash.ll | 2 +- llvm/test/Transforms/LoopRotate/dbgvalue.ll | 2 +- .../tools/llvm-reduce/remove-dp-values.ll | 2 +- .../llvm-reduce/deltas/ReduceDbgRecords.cpp | 12 +- .../llvm-reduce/deltas/ReduceDbgRecords.h | 2 +- llvm/unittests/IR/BasicBlockDbgInfoTest.cpp | 643 +++++++++--------- llvm/unittests/IR/DebugInfoTest.cpp | 182 ++--- llvm/unittests/IR/IRBuilderTest.cpp | 6 +- llvm/unittests/IR/ValueTest.cpp | 14 +- llvm/unittests/Transforms/Utils/LocalTest.cpp | 23 +- 83 files changed, 1899 insertions(+), 1787 deletions(-) diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 8edcc4ceea94..f37ac549d10a 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -4770,9 +4770,9 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( assert(!Last.isTerminator() && "unexpected terminator"); if (auto *Marker = CGF.Builder.GetInsertBlock()->getTrailingDbgRecords()) { - for (llvm::DPValue &DPV : llvm::reverse( + for (llvm::DbgVariableRecord &DVR : llvm::reverse( llvm::filterDbgVars(Marker->getDbgRecordRange()))) { - UpdateExpr(Last.getContext(), &DPV, Offset); + UpdateExpr(Last.getContext(), &DVR, Offset); break; } } diff --git a/llvm/docs/RemoveDIsDebugInfo.md b/llvm/docs/RemoveDIsDebugInfo.md index e654313aaa67..2cb17e2b5e44 100644 --- a/llvm/docs/RemoveDIsDebugInfo.md +++ b/llvm/docs/RemoveDIsDebugInfo.md @@ -64,10 +64,10 @@ This will all happen transparently without needing to think about it! We're using a dedicated C++ class called `DbgRecord` to store debug info, with a one-to-one relationship between each instance of a debug intrinsic and each `DbgRecord` object in any LLVM IR program; these `DbgRecord`s are represented in the IR as non-instruction debug records, as described in the [Source Level Debugging](project:SourceLevelDebugging.rst#Debug Records) document. This class has a set of subclasses that store exactly the same information as is stored in debugging intrinsics. Each one also has almost entirely the same set of methods, that behave in the same way: https://llvm.org/docs/doxygen/classllvm_1_1DbgRecord.html - https://llvm.org/docs/doxygen/classllvm_1_1DPValue.html + https://llvm.org/docs/doxygen/classllvm_1_1DbgVariableRecord.html https://llvm.org/docs/doxygen/classllvm_1_1DPLabel.html -This allows you to treat a `DPValue` as if it's a `dbg.value`/`dbg.declare`/`dbg.assign` intrinsic most of the time, for example in generic (auto-param) lambdas, and the same for `DPLabel` and `dbg.label`s. +This allows you to treat a `DbgVariableRecord` as if it's a `dbg.value`/`dbg.declare`/`dbg.assign` intrinsic most of the time, for example in generic (auto-param) lambdas, and the same for `DPLabel` and `dbg.label`s. ## How do these `DbgRecords` fit into the instruction stream? @@ -95,13 +95,13 @@ Like so: Each instruction has a pointer to a `DPMarker` (which will become optional), that contains a list of `DbgRecord` objects. No debugging records appear in the instruction list at all. `DbgRecord`s have a parent pointer to their owning `DPMarker`, and each `DPMarker` has a pointer back to it's owning instruction. -Not shown are the links from DbgRecord to other parts of the `Value`/`Metadata` hierachy: `DbgRecord` subclasses have tracking pointers to the DIMetadata that they use, and `DPValue` has references to `Value`s that are stored in a `DebugValueUser` base class. This refers to a `ValueAsMetadata` object referring to `Value`s, via the `TrackingMetadata` facility. +Not shown are the links from DbgRecord to other parts of the `Value`/`Metadata` hierachy: `DbgRecord` subclasses have tracking pointers to the DIMetadata that they use, and `DbgVariableRecord` has references to `Value`s that are stored in a `DebugValueUser` base class. This refers to a `ValueAsMetadata` object referring to `Value`s, via the `TrackingMetadata` facility. -The various kinds of debug intrinsic (value, declare, assign, label) are all stored in `DbgRecord` subclasses, with a "RecordKind" field distinguishing `DPLabel`s from `DPValue`s, and a `LocationType` field in the `DPValue` class further disambiguating the various debug variable intrinsics it can represent. +The various kinds of debug intrinsic (value, declare, assign, label) are all stored in `DbgRecord` subclasses, with a "RecordKind" field distinguishing `DPLabel`s from `DbgVariableRecord`s, and a `LocationType` field in the `DbgVariableRecord` class further disambiguating the various debug variable intrinsics it can represent. ## Finding debug info records -Utilities such as `findDbgUsers` and the like now have an optional argument that will return the set of `DPValue` records that refer to a `Value`. You should be able to treat them the same as intrinsics. +Utilities such as `findDbgUsers` and the like now have an optional argument that will return the set of `DbgVariableRecord` records that refer to a `Value`. You should be able to treat them the same as intrinsics. ## Examining debug info records at positions diff --git a/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h b/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h index 31af3014afe4..45a47d7333e3 100644 --- a/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -191,7 +191,7 @@ public: /// Collection of dbg.declare instructions handled after argument /// lowering and before ISel proper. SmallPtrSet<const DbgDeclareInst *, 8> PreprocessedDbgDeclares; - SmallPtrSet<const DPValue *, 8> PreprocessedDPVDeclares; + SmallPtrSet<const DbgVariableRecord *, 8> PreprocessedDVRDeclares; /// set - Initialize this FunctionLoweringInfo with the given Function /// and its associated MachineFunction. diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index 88e341d7ad6f..51444c7f8c9c 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -38,7 +38,7 @@ class LLVMContext; class Module; class PHINode; class ValueSymbolTable; -class DPValue; +class DbgVariableRecord; class DPMarker; /// LLVM Basic Block Representation @@ -121,10 +121,10 @@ public: DPMarker *getNextMarker(Instruction *I); /// Insert a DbgRecord into a block at the position given by \p I. - void insertDbgRecordAfter(DbgRecord *DPV, Instruction *I); + void insertDbgRecordAfter(DbgRecord *DR, Instruction *I); /// Insert a DbgRecord into a block at the position given by \p Here. - void insertDbgRecordBefore(DbgRecord *DPV, InstListType::iterator Here); + void insertDbgRecordBefore(DbgRecord *DR, InstListType::iterator Here); /// Eject any debug-info trailing at the end of a block. DbgRecords can /// transiently be located "off the end" of a block if the blocks terminator diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index d758d2494286..002f2db6da54 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -101,9 +101,10 @@ namespace llvm { DbgInstPtr insertLabel(DILabel *LabelInfo, const DILocation *DL, BasicBlock *InsertBB, Instruction *InsertBefore); - /// Internal helper. Track metadata if untracked and insert \p DPV. - void insertDPValue(DPValue *DPV, BasicBlock *InsertBB, - Instruction *InsertBefore, bool InsertAtHead = false); + /// Internal helper. Track metadata if untracked and insert \p DVR. + void insertDbgVariableRecord(DbgVariableRecord *DVR, BasicBlock *InsertBB, + Instruction *InsertBefore, + bool InsertAtHead = false); /// Internal helper with common code used by insertDbg{Value,Addr}Intrinsic. Instruction *insertDbgIntrinsic(llvm::Function *Intrinsic, llvm::Value *Val, diff --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h index 6673908d3ed3..53cede5409e2 100644 --- a/llvm/include/llvm/IR/DebugInfo.h +++ b/llvm/include/llvm/IR/DebugInfo.h @@ -34,23 +34,25 @@ namespace llvm { class DbgDeclareInst; class DbgValueInst; class DbgVariableIntrinsic; -class DPValue; +class DbgVariableRecord; class Instruction; class Module; /// Finds dbg.declare intrinsics declaring local variables as living in the /// memory that 'V' points to. TinyPtrVector<DbgDeclareInst *> findDbgDeclares(Value *V); -/// As above, for DPVDeclares. -TinyPtrVector<DPValue *> findDPVDeclares(Value *V); +/// As above, for DVRDeclares. +TinyPtrVector<DbgVariableRecord *> findDVRDeclares(Value *V); /// Finds the llvm.dbg.value intrinsics describing a value. -void findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, - Value *V, SmallVectorImpl<DPValue *> *DPValues = nullptr); +void findDbgValues( + SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V, + SmallVectorImpl<DbgVariableRecord *> *DbgVariableRecords = nullptr); /// Finds the debug info intrinsics describing a value. -void findDbgUsers(SmallVectorImpl<DbgVariableIntrinsic *> &DbgInsts, - Value *V, SmallVectorImpl<DPValue *> *DPValues = nullptr); +void findDbgUsers( + SmallVectorImpl<DbgVariableIntrinsic *> &DbgInsts, Value *V, + SmallVectorImpl<DbgVariableRecord *> *DbgVariableRecords = nullptr); /// Find subprogram that is enclosing this scope. DISubprogram *getDISubprogram(const MDNode *Scope); @@ -58,7 +60,7 @@ DISubprogram *getDISubprogram(const MDNode *Scope); /// Produce a DebugLoc to use for each dbg.declare that is promoted to a /// dbg.value. DebugLoc getDebugValueLoc(DbgVariableIntrinsic *DII); -DebugLoc getDebugValueLoc(DPValue *DPV); +DebugLoc getDebugValueLoc(DbgVariableRecord *DVR); /// Strip debug info in the module if it exists. /// @@ -109,7 +111,8 @@ public: void processVariable(const Module &M, const DILocalVariable *DVI); /// Process debug info location. void processLocation(const Module &M, const DILocation *Loc); - /// Process a DbgRecord (e.g, treat a DPValue like a DbgVariableIntrinsic). + /// Process a DbgRecord (e.g, treat a DbgVariableRecord like a + /// DbgVariableIntrinsic). void processDbgRecord(const Module &M, const DbgRecord &DR); /// Process subprogram. @@ -193,10 +196,10 @@ inline AssignmentInstRange getAssignmentInsts(const DbgAssignIntrinsic *DAI) { return getAssignmentInsts(DAI->getAssignID()); } -inline AssignmentInstRange getAssignmentInsts(const DPValue *DPV) { - assert(DPV->isDbgAssign() && - "Can't get assignment instructions for non-assign DPV!"); - return getAssignmentInsts(DPV->getAssignID()); +inline AssignmentInstRange getAssignmentInsts(const DbgVariableRecord *DVR) { + assert(DVR->isDbgAssign() && + "Can't get assignment instructions for non-assign DVR!"); + return getAssignmentInsts(DVR->getAssignID()); } // @@ -231,9 +234,10 @@ inline AssignmentMarkerRange getAssignmentMarkers(const Instruction *Inst) { return make_range(Value::user_iterator(), Value::user_iterator()); } -inline SmallVector<DPValue *> getDPVAssignmentMarkers(const Instruction *Inst) { +inline SmallVector<DbgVariableRecord *> +getDVRAssignmentMarkers(const Instruction *Inst) { if (auto *ID = Inst->getMetadata(LLVMContext::MD_DIAssignID)) - return cast<DIAssignID>(ID)->getAllDPValueUsers(); + return cast<DIAssignID>(ID)->getAllDbgVariableRecordUsers(); return {}; } @@ -261,7 +265,7 @@ bool calculateFragmentIntersect( std::optional<DIExpression::FragmentInfo> &Result); bool calculateFragmentIntersect( const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits, - uint64_t SliceSizeInBits, const DPValue *DPVAssign, + uint64_t SliceSizeInBits, const DbgVariableRecord *DVRAssign, std::optional<DIExpression::FragmentInfo> &Result); /// Helper struct for trackAssignments, below. We don't use the similar @@ -276,8 +280,8 @@ struct VarRecord { VarRecord(DbgVariableIntrinsic *DVI) : Var(DVI->getVariable()), DL(getDebugValueLoc(DVI)) {} - VarRecord(DPValue *DPV) - : Var(DPV->getVariable()), DL(getDebugValueLoc(DPV)) {} + VarRecord(DbgVariableRecord *DVR) + : Var(DVR->getVariable()), DL(getDebugValueLoc(DVR)) {} VarRecord(DILocalVariable *Var, DILocation *DL) : Var(Var), DL(DL) {} friend bool operator<(const VarRecord &LHS, const VarRecord &RHS) { return std::tie(LHS.Var, LHS.DL) < std::tie(RHS.Var, RHS.DL); diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 5e827b4a2e03..2805f6c47805 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -65,7 +65,7 @@ enum Tag : uint16_t; } class DbgVariableIntrinsic; -class DPValue; +class DbgVariableRecord; extern cl::opt<bool> EnableFSDiscriminator; @@ -323,8 +323,8 @@ public: // This node has no operands to replace. void replaceOperandWith(unsigned I, Metadata *New) = delete; - SmallVector<DPValue *> getAllDPValueUsers() { - return Context.getReplaceableUses()->getAllDPValueUsers(); + SmallVector<DbgVariableRecord *> getAllDbgVariableRecordUsers() { + return Context.getReplaceableUses()->getAllDbgVariableRecordUsers(); } static DIAssignID *getDistinct(LLVMContext &Context) { @@ -3840,8 +3840,8 @@ public: return MD->getMetadataID() == DIArgListKind; } - SmallVector<DPValue *> getAllDPValueUsers() { - return ReplaceableMetadataImpl::getAllDPValueUsers(); + SmallVector<DbgVariableRecord *> getAllDbgVariableRecordUsers() { + return ReplaceableMetadataImpl::getAllDbgVariableRecordUsers(); } void handleChangedOperand(void *Ref, Metadata *New); @@ -3871,7 +3871,7 @@ class DebugVariable { public: DebugVariable(const DbgVariableIntrinsic *DII); - DebugVariable(const DPValue *DPV); + DebugVariable(const DbgVariableRecord *DVR); DebugVariable(const DILocalVariable *Var, std::optional<FragmentInfo> FragmentInfo, diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h index e902cebb8803..db41e9acc7be 100644 --- a/llvm/include/llvm/IR/DebugProgramInstruction.h +++ b/llvm/include/llvm/IR/DebugProgramInstruction.h @@ -27,12 +27,13 @@ // %bar = void call @ext(%foo) // ; bar->DbgMarker = { // ; StoredDbgRecords = { -// ; DPValue(metadata i32 %foo, ...) +// ; DbgVariableRecord(metadata i32 %foo, ...) // ; } // ; } // ;; There is a debug-info record in front of the %bar instruction, // ;; thus it points at a DPMarker object. That DPMarker contains a -// ;; DPValue in it's ilist, storing the equivalent information to the +// ;; DbgVariableRecord in it's ilist, storing the equivalent information +// to the // ;; dbg.value above: the Value, DILocalVariable, etc. // // This structure separates the two concerns of the position of the debug-info @@ -66,7 +67,7 @@ class DbgInfoIntrinsic; class DbgLabelInst; class DIAssignID; class DPMarker; -class DPValue; +class DbgVariableRecord; class raw_ostream; /// A typed tracking MDNode reference that does not require a definition for its @@ -219,7 +220,8 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DbgRecord &R) { /// Records a position in IR for a source label (DILabel). Corresponds to the /// llvm.dbg.label intrinsic. -/// FIXME: Rename DbgLabelRecord when DPValue is renamed to DbgVariableRecord. +/// FIXME: Rename DbgLabelRecord when DbgVariableRecord is renamed to +/// DbgVariableRecord. class DPLabel : public DbgRecord { DbgRecordParamRef<DILabel> Label; @@ -257,7 +259,7 @@ public: /// /// This class inherits from DebugValueUser to allow LLVM's metadata facilities /// to update our references to metadata beneath our feet. -class DPValue : public DbgRecord, protected DebugValueUser { +class DbgVariableRecord : public DbgRecord, protected DebugValueUser { friend class DebugValueUser; public: @@ -269,9 +271,10 @@ public: End, ///< Marks the end of the concrete types. Any, ///< To indicate all LocationTypes in searches. }; - /// Classification of the debug-info record that this DPValue represents. - /// Essentially, "is this a dbg.value or dbg.declare?". dbg.declares are not - /// currently supported, but it would be trivial to do so. + /// Classification of the debug-info record that this DbgVariableRecord + /// represents. Essentially, "is this a dbg.value or dbg.declare?". + /// dbg.declares are not currently supported, but it would be trivial to do + /// so. /// FIXME: We could use spare padding bits from DbgRecord for this. LocationType Type; @@ -284,63 +287,69 @@ public: DbgRecordParamRef<DIExpression> AddressExpression; public: - /// Create a new DPValue representing the intrinsic \p DVI, for example the - /// assignment represented by a dbg.value. - DPValue(const DbgVariableIntrinsic *DVI); - DPValue(const DPValue &DPV); - /// Directly construct a new DPValue representing a dbg.value intrinsic - /// assigning \p Location to the DV / Expr / DI variable. - DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr, - const DILocation *DI, LocationType Type = LocationType::Value); - DPValue(Metadata *Value, DILocalVariable *Variable, DIExpression *Expression, - DIAssignID *AssignID, Metadata *Address, - DIExpression *AddressExpression, const DILocation *DI); + /// Create a new DbgVariableRecord representing the intrinsic \p DVI, for + /// example the assignment represented by a dbg.value. + DbgVariableRecord(const DbgVariableIntrinsic *DVI); + DbgVariableRecord(const DbgVariableRecord &DVR); + /// Directly construct a new DbgVariableRecord representing a dbg.value + /// intrinsic assigning \p Location to the DV / Expr / DI variable. + DbgVariableRecord(Metadata *Location, DILocalVariable *DV, DIExpression *Expr, + const DILocation *DI, + LocationType Type = LocationType::Value); + DbgVariableRecord(Metadata *Value, DILocalVariable *Variable, + DIExpression *Expression, DIAssignID *AssignID, + Metadata *Address, DIExpression *AddressExpression, + const DILocation *DI); private: /// Private constructor for creating new instances during parsing only. Only - /// called through `createUnresolvedDPValue` below, which makes clear that - /// this is used for parsing only, and will later return a subclass depending - /// on which Type is passed. - DPValue(LocationType Type, Metadata *Val, MDNode *Variable, - MDNode *Expression, MDNode *AssignID, Metadata *Address, - MDNode *AddressExpression, MDNode *DI); + /// called through `createUnresolvedDbgVariableRecord` below, which makes + /// clear that this is used for parsing only, and will later return a subclass + /// depending on which Type is passed. + DbgVariableRecord(LocationType Type, Metadata *Val, MDNode *Variable, + MDNode *Expression, MDNode *AssignID, Metadata *Address, + MDNode *AddressExpression, MDNode *DI); public: - /// Used to create DPValues during parsing, where some metadata references may - /// still be unresolved. Although for some fields a generic `Metadata*` - /// argument is accepted for forward type-references, the verifier and - /// accessors will reject incorrect types later on. The function is used for - /// all types of DPValues for simplicity while parsing, but asserts if any - /// necessary fields are empty or unused fields are not empty, i.e. if the - /// #dbg_assign fields are used for a non-dbg-assign type. - static DPValue *createUnresolvedDPValue(LocationType Type, Metadata *Val, - MDNode *Variable, MDNode *Expression, - MDNode *AssignID, Metadata *Address, - MDNode *AddressExpression, - MDNode *DI); - - static DPValue *createDPVAssign(Value *Val, DILocalVariable *Variable, - DIExpression *Expression, - DIAssignID *AssignID, Value *Address, - DIExpression *AddressExpression, - const DILocation *DI); - static DPValue *createLinkedDPVAssign(Instruction *LinkedInstr, Value *Val, - DILocalVariable *Variable, - DIExpression *Expression, - Value *Address, - DIExpression *AddressExpression, - const DILocation *DI); - - static DPValue *createDPValue(Value *Location, DILocalVariable *DV, - DIExpression *Expr, const DILocation *DI); - static DPValue *createDPValue(Value *Location, DILocalVariable *DV, - DIExpression *Expr, const DILocation *DI, - DPValue &InsertBefore); - static DPValue *createDPVDeclare(Value *Address, DILocalVariable *DV, - DIExpression *Expr, const DILocation *DI); - static DPValue *createDPVDeclare(Value *Address, DILocalVariable *DV, - DIExpression *Expr, const DILocation *DI, - DPValue &InsertBefore); + /// Used to create DbgVariableRecords during parsing, where some metadata + /// references may still be unresolved. Although for some fields a generic + /// `Metadata*` argument is accepted for forward type-references, the verifier + /// and accessors will reject incorrect types later on. The function is used + /// for all types of DbgVariableRecords for simplicity while parsing, but + /// asserts if any necessary fields are empty or unused fields are not empty, + /// i.e. if the #dbg_assign fields are used for a non-dbg-assign type. + static DbgVariableRecord * + createUnresolvedDbgVariableRecord(LocationType Type, Metadata *Val, + MDNode *Variable, MDNode *Expression, + MDNode *AssignID, Metadata *Address, + MDNode *AddressExpression, MDNode *DI); + + static DbgVariableRecord * + createDVRAssign(Value *Val, DILocalVariable *Variable, + DIExpression *Expression, DIAssignID *AssignID, + Value *Address, DIExpression *AddressExpression, + const DILocation *DI); + static DbgVariableRecord * + createLinkedDVRAssign(Instruction *LinkedInstr, Value *Val, + DILocalVariable *Variable, DIExpression *Expression, + Value *Address, DIExpression *AddressExpression, + const DILocation *DI); + + static DbgVariableRecord *createDbgVariableRecord(Value *Location, + DILocalVariable *DV, + DIExpression *Expr, + const DILocation *DI); + static DbgVariableRecord * + createDbgVariableRecord(Value *Location, DILocalVariable *DV, + DIExpression *Expr, const DILocation *DI, + DbgVariableRecord &InsertBefore); + static DbgVariableRecord *createDVRDeclare(Value *Address, + DILocalVariable *DV, + DIExpression *Expr, + const DILocation *DI); + static DbgVariableRecord * + createDVRDeclare(Value *Address, DILocalVariable *DV, DIExpression *Expr, + const DILocation *DI, DbgVariableRecord &InsertBefore); /// Iterator for ValueAsMetadata that internally uses direct pointer iteration /// over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the @@ -412,7 +421,8 @@ public: unsigned getNumVariableLocationOps() const; bool hasArgList() const { return isa<DIArgList>(getRawLocation()); } - /// Returns true if this DPValue has no empty MDNodes in its location list. + /// Returns true if this DbgVariableRecord has no empty MDNodes in its + /// location list. bool hasValidLocation() const { return getVariableLocationOp(0) != nullptr; } /// Does this describe the address of a local variable. True for dbg.addr @@ -445,10 +455,10 @@ public: /// replaceVariableLocationOp and addVariableLocationOps should be used where /// possible to avoid creating invalid state. void setRawLocation(Metadata *NewLocation) { - assert( - (isa<ValueAsMetadata>(NewLocation) || isa<DIArgList>(NewLocation) || - isa<MDNode>(NewLocation)) && - "Location for a DPValue must be either ValueAsMetadata or DIArgList"); + assert((isa<ValueAsMetadata>(NewLocation) || isa<DIArgList>(NewLocation) || + isa<MDNode>(NewLocation)) && + "Location for a DbgVariableRecord must be either ValueAsMetadata or " + "DIArgList"); resetDebugValue(0, NewLocation); } @@ -456,12 +466,12 @@ public: /// is described. std::optional<uint64_t> getFragmentSizeInBits() const; - bool isEquivalentTo(const DPValue &Other) const { + bool isEquivalentTo(const DbgVariableRecord &Other) const { return DbgLoc == Other.DbgLoc && isIdenticalToWhenDefined(Other); } // Matches the definition of the Instruction version, equivalent to above but // without checking DbgLoc. - bool isIdenticalToWhenDefined(const DPValue &Other) const { + bool isIdenticalToWhenDefined(const DbgVariableRecord &Other) const { return std::tie(Type, DebugValues, Variable, Expression, AddressExpression) == std::tie(Other.Type, Other.DebugValues, Other.Variable, @@ -497,10 +507,10 @@ public: /// @} - DPValue *clone() const; - /// Convert this DPValue back into a dbg.value intrinsic. + DbgVariableRecord *clone() const; + /// Convert this DbgVariableRecord back into a dbg.value intrinsic. /// \p InsertBefore Optional position to insert this intrinsic. - /// \returns A new dbg.value intrinsic representiung this DPValue. + /// \returns A new dbg.value intrinsic representiung this DbgVariableRecord. DbgVariableIntrinsic *createDebugIntrinsic(Module *M, Instruction *InsertBefore) const; @@ -517,12 +527,13 @@ public: } }; -/// Filter the DbgRecord range to DPValue types only and downcast. +/// Filter the DbgRecord range to DbgVariableRecord types only and downcast. static inline auto filterDbgVars(iterator_range<simple_ilist<DbgRecord>::iterator> R) { return map_range( - make_filter_range(R, [](DbgRecord &E) { return isa<DPValue>(E); }), - [](DbgRecord &E) { return std::ref(cast<DPValue>(E)); }); + make_filter_range(R, + [](DbgRecord &E) { return isa<DbgVariableRecord>(E); }), + [](DbgRecord &E) { return std::ref(cast<DbgVariableRecord>(E)); }); } /// Per-instruction record of debug-info. If an Instruction is the position of diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h index da6744fdd091..22da54a1f03c 100644 --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -43,7 +43,7 @@ namespace llvm { class Module; class ModuleSlotTracker; class raw_ostream; -class DPValue; +class DbgVariableRecord; template <typename T> class StringMapEntry; template <typename ValueTy> class StringMapEntryStorage; class Type; @@ -205,23 +205,23 @@ private: /// Base class for tracking ValueAsMetadata/DIArgLists with user lookups and /// Owner callbacks outside of ValueAsMetadata. /// -/// Currently only inherited by DPValue; if other classes need to use it, then -/// a SubclassID will need to be added (either as a new field or by making -/// DebugValue into a PointerIntUnion) to discriminate between the subclasses in -/// lookup and callback handling. +/// Currently only inherited by DbgVariableRecord; if other classes need to use +/// it, then a SubclassID will need to be added (either as a new field or by +/// making DebugValue into a PointerIntUnion) to discriminate between the +/// subclasses in lookup and callback handling. class DebugValueUser { protected: // Capacity to store 3 debug values. // TODO: Not all DebugValueUser instances need all 3 elements, if we - // restructure the DPValue class then we can template parameterize this array - // size. + // restructure the DbgVariableRecord class then we can template parameterize + // this array size. std::array<Metadata *, 3> DebugValues; ArrayRef<Metadata *> getDebugValues() const { return DebugValues; } public: - DPValue *getUser(); - const DPValue *getUser() const; + DbgVariableRecord *getUser(); + const DbgVariableRecord *getUser() const; /// To be called by ReplaceableMetadataImpl::replaceAllUsesWith, where `Old` /// is a pointer to one of the pointers in `DebugValues` (so should be type /// Metadata**), and `NewDebugValue` is the new Metadata* that is replacing @@ -407,8 +407,8 @@ public: static void SalvageDebugInfo(const Constant &C); /// Returns the list of all DIArgList users of this. SmallVector<Metadata *> getAllArgListUsers(); - /// Returns the list of all DPValue users of this. - SmallVector<DPValue *> getAllDPValueUsers(); + /// Returns the list of all DbgVariableRecord users of this. + SmallVector<DbgVariableRecord *> getAllDbgVariableRecordUsers(); /// Resolve all uses of this. /// @@ -494,8 +494,8 @@ public: SmallVector<Metadata *> getAllArgListUsers() { return ReplaceableMetadataImpl::getAllArgListUsers(); } - SmallVector<DPValue *> getAllDPValueUsers() { - return ReplaceableMetadataImpl::getAllDPValueUsers(); + SmallVector<DbgVariableRecord *> getAllDbgVariableRecordUsers() { + return ReplaceableMetadataImpl::getAllDbgVariableRecordUsers(); } static void handleDeletion(Value *V); diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h index cc1336287436..9ae026fa95d2 100644 --- a/llvm/include/llvm/Transforms/Utils/Local.h +++ b/llvm/include/llvm/Transforms/Utils/Local.h @@ -262,21 +262,21 @@ CallInst *changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr); /// that has an associated llvm.dbg.declare intrinsic. void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, StoreInst *SI, DIBuilder &Builder); -void ConvertDebugDeclareToDebugValue(DPValue *DPV, StoreInst *SI, +void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, StoreInst *SI, DIBuilder &Builder); /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value /// that has an associated llvm.dbg.declare intrinsic. void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, LoadInst *LI, DIBuilder &Builder); -void ConvertDebugDeclareToDebugValue(DPValue *DPV, LoadInst *LI, +void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, LoadInst *LI, DIBuilder &Builder); /// Inserts a llvm.dbg.value intrinsic after a phi that has an associated /// llvm.dbg.declare intrinsic. void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, PHINode *LI, DIBuilder &Builder); -void ConvertDebugDeclareToDebugValue(DPValue *DPV, PHINode *LI, +void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, PHINode *LI, DIBuilder &Builder); /// Lowers llvm.dbg.declare intrinsics into appropriate set of @@ -313,7 +313,7 @@ void salvageDebugInfo(Instruction &I); /// Mark undef if salvaging cannot be completed. void salvageDebugInfoForDbgValues(Instruction &I, ArrayRef<DbgVariableIntrinsic *> Insns, - ArrayRef<DPValue *> DPInsns); + ArrayRef<DbgVariableRecord *> DPInsns); /// Given an instruction \p I and DIExpression \p DIExpr operating on /// it, append the effects of \p I to the DIExpression operand list diff --git a/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h index df61f60de4f2..d649e6995e55 100644 --- a/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h +++ b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h @@ -53,7 +53,7 @@ struct AllocaInfo { SmallVector<IntrinsicInst *, 2> LifetimeEnd; SmallVector<DbgVariableIntrinsic *, 2> DbgVariableIntrinsics; // Non-intrinsic records of variable locations. - SmallVector<DPValue *, 2> DbgVariableRecords; + SmallVector<DbgVariableRecord *, 2> DbgVariableRecords; }; struct StackInfo { diff --git a/llvm/include/llvm/Transforms/Utils/SSAUpdater.h b/llvm/include/llvm/Transforms/Utils/SSAUpdater.h index c79d436fc676..29d96a0ab6bf 100644 --- a/llvm/include/llvm/Transforms/Utils/SSAUpdater.h +++ b/llvm/include/llvm/Transforms/Utils/SSAUpdater.h @@ -23,7 +23,7 @@ class BasicBlock; class Instruction; class LoadInst; class PHINode; -class DPValue; +class DbgVariableRecord; template <typename T> class SmallVectorImpl; template <typename T> class SSAUpdaterTraits; class Type; @@ -124,7 +124,8 @@ public: void UpdateDebugValues(Instruction *I); void UpdateDebugValues(Instruction *I, SmallVectorImpl<DbgValueInst *> &DbgValues); - void UpdateDebugValues(Instruction *I, SmallVectorImpl<DPValue *> &DbgValues); + void UpdateDebugValues(Instruction *I, + SmallVectorImpl<DbgVariableRecord *> &DbgValues); /// Rewrite a use like \c RewriteUse but handling in-block definitions. /// @@ -136,7 +137,7 @@ public: private: Value *GetValueAtEndOfBlockInternal(BasicBlock *BB); void UpdateDebugValue(Instruction *I, DbgValueInst *DbgValue); - void UpdateDebugValue(Instruction *I, DPValue *DbgValue); + void UpdateDebugValue(Instruction *I, DbgVariableRecord *DbgValue); }; /// Helper class for promoting a collection of loads and stores into SSA diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h index dd183bc04f0c..54e3e62dc3af 100644 --- a/llvm/include/llvm/Transforms/Utils/ValueMapper.h +++ b/llvm/include/llvm/Transforms/Utils/ValueMapper.h @@ -180,8 +180,9 @@ public: Constant *mapConstant(const Constant &C); void remapInstruction(Instruction &I); - void remapDPValue(Module *M, DPValue &V); - void remapDPValueRange(Module *M, iterator_range<DbgRecordIterator> Range); + void remapDbgVariableRecord(Module *M, DbgVariableRecord &V); + void remapDbgVariableRecordRange(Module *M, + iterator_range<DbgRecordIterator> Range); void remapFunction(Function &F); void remapGlobalObjectMetadata(GlobalObject &GO); @@ -267,21 +268,26 @@ inline void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, ValueMapper(VM, Flags, TypeMapper, Materializer).remapInstruction(*I); } -/// Remap the Values used in the DPValue \a V using the value map \a VM. -inline void RemapDPValue(Module *M, DPValue *V, ValueToValueMapTy &VM, - RemapFlags Flags = RF_None, - ValueMapTypeRemapper *TypeMapper = nullptr, - ValueMaterializer *Materializer = nullptr) { - ValueMapper(VM, Flags, TypeMapper, Materializer).remapDPValue(M, *V); +/// Remap the Values used in the DbgVariableRecord \a V using the value map \a +/// VM. +inline void RemapDbgVariableRecord(Module *M, DbgVariableRecord *V, + ValueToValueMapTy &VM, + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = nullptr, + ValueMaterializer *Materializer = nullptr) { + ValueMapper(VM, Flags, TypeMapper, Materializer) + .remapDbgVariableRecord(M, *V); } -/// Remap the Values used in the DPValue \a V using the value map \a VM. -inline void RemapDPValueRange(Module *M, - iterator_range<DbgRecordIterator> Range, - ValueToValueMapTy &VM, RemapFlags Flags = RF_None, - ValueMapTypeRemapper *TypeMapper = nullptr, - ValueMaterializer *Materializer = nullptr) { - ValueMapper(VM, Flags, TypeMapper, Materializer).remapDPValueRange(M, Range); +/// Remap the Values used in the DbgVariableRecord \a V using the value map \a +/// VM. +inline void +RemapDbgVariableRecordRange(Module *M, iterator_range<DbgRecordIterator> Range, + ValueToValueMapTy &VM, RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = nullptr, + ValueMaterializer *Materializer = nullptr) { + ValueMapper(VM, Flags, TypeMapper, Materializer) + .remapDbgVariableRecordRange(M, Range); } /// Remap the operands, metadata, arguments, and instructions of a function. diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index ad1fdf64015b..2c352be74931 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -6558,10 +6558,10 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) { /// (MDNode ',' Metadata ',' Metadata ',')? MDNode ')' bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) { using RecordKind = DbgRecord::Kind; - using LocType = DPValue::LocationType; - LocTy DPVLoc = Lex.getLoc(); + using LocType = DbgVariableRecord::LocationType; + LocTy DVRLoc = Lex.getLoc(); if (Lex.getKind() != lltok::DbgRecordType) - return error(DPVLoc, "expected debug record type here"); + return error(DVRLoc, "expected debug record type here"); RecordKind RecordType = StringSwitch<RecordKind>(Lex.getStrVal()) .Case("declare", RecordKind::ValueKind) .Case("value", RecordKind::ValueKind) @@ -6569,7 +6569,7 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) { .Case("label", RecordKind::LabelKind); // Parsing labels is trivial; parse here and early exit, otherwise go into the - // full DPValue processing stage. + // full DbgVariableRecord processing stage. if (RecordType == RecordKind::LabelKind) { Lex.Lex(); if (parseToken(lltok::lparen, "Expected '(' here")) @@ -6649,9 +6649,9 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) { if (parseToken(lltok::rparen, "Expected ')' here")) return true; - DR = DPValue::createUnresolvedDPValue(ValueType, ValLocMD, Variable, - Expression, AssignID, AddressLocation, - AddressExpression, DebugLoc); + DR = DbgVariableRecord::createUnresolvedDbgVariableRecord( + ValueType, ValLocMD, Variable, Expression, AssignID, AddressLocation, + AddressExpression, DebugLoc); return false; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index dd1b3d97f026..826108432383 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -6425,7 +6425,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_DEBUG_RECORD_VALUE: case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE: case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: { - // DPValues are placed after the Instructions that they are attached to. + // DbgVariableRecords are placed after the Instructions that they are + // attached to. Instruction *Inst = getLastInstruction(); if (!Inst) return error("Invalid dbg record: missing instruction"); @@ -6468,29 +6469,30 @@ Error BitcodeReader::parseFunctionBody(Function *F) { RawLocation = getFnMetadataByID(Record[Slot++]); } - DPValue *DPV = nullptr; + DbgVariableRecord *DVR = nullptr; switch (BitCode) { case bitc::FUNC_CODE_DEBUG_RECORD_VALUE: case bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE: - DPV = new DPValue(RawLocation, Var, Expr, DIL, - DPValue::LocationType::Value); + DVR = new DbgVariableRecord(RawLocation, Var, Expr, DIL, + DbgVariableRecord::LocationType::Value); break; case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE: - DPV = new DPValue(RawLocation, Var, Expr, DIL, - DPValue::LocationType::Declare); + DVR = new DbgVariableRecord(RawLocation, Var, Expr, DIL, + DbgVariableRecord::LocationType::Declare); break; case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: { DIAssignID *ID = cast<DIAssignID>(getFnMetadataByID(Record[Slot++])); DIExpression *AddrExpr = cast<DIExpression>(getFnMetadataByID(Record[Slot++])); Metadata *Addr = getFnMetadataByID(Record[Slot++]); - DPV = new DPValue(RawLocation, Var, Expr, ID, Addr, AddrExpr, DIL); + DVR = new DbgVariableRecord(RawLocation, Var, Expr, ID, Addr, AddrExpr, + DIL); break; } default: - llvm_unreachable("Unknown DPValue bitcode"); + llvm_unreachable("Unknown DbgVariableRecord bitcode"); } - Inst->getParent()->insertDbgRecordBefore(DPV, Inst->getIterator()); + Inst->getParent()->insertDbgRecordBefore(DVR, Inst->getIterator()); continue; // This isn't an instruction. } case bitc::FUNC_CODE_INST_CALL: { diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index fb005ee826ec..9102f3a60cff 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -621,9 +621,9 @@ class MetadataLoader::MetadataLoaderImpl { for (auto &BB : F) for (auto &I : BB) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - if (DPV.isDbgDeclare()) - UpdateDeclareIfNeeded(&DPV); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + if (DVR.isDbgDeclare()) + UpdateDeclareIfNeeded(&DVR); } if (auto *DDI = dyn_cast<DbgDeclareInst>(&I)) UpdateDeclareIfNeeded(DDI); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 2e26e95064c3..fd211f74f07c 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -3547,7 +3547,8 @@ void ModuleBitcodeWriter::writeFunction( /// without the ValueAsMetadata wrapper. auto PushValueOrMetadata = [&Vals, InstID, this](Metadata *RawLocation) { - assert(RawLocation && "RawLocation unexpectedly null in DPValue"); + assert(RawLocation && + "RawLocation unexpectedly null in DbgVariableRecord"); if (ValueAsMetadata *VAM = dyn_cast<ValueAsMetadata>(RawLocation)) { SmallVector<unsigned, 2> ValAndType; // If the value is a fwd-ref the type is also pushed. We don't @@ -3586,25 +3587,25 @@ void ModuleBitcodeWriter::writeFunction( // ..., LocationMetadata // dbg_assign (FUNC_CODE_DEBUG_RECORD_ASSIGN) // ..., LocationMetadata, DIAssignID, DIExpression, LocationMetadata - DPValue &DPV = cast<DPValue>(DR); - Vals.push_back(VE.getMetadataID(&*DPV.getDebugLoc())); - Vals.push_back(VE.getMetadataID(DPV.getVariable())); - Vals.push_back(VE.getMetadataID(DPV.getExpression())); - if (DPV.isDbgValue()) { - if (PushValueOrMetadata(DPV.getRawLocation())) + DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR); + Vals.push_back(VE.getMetadataID(&*DVR.getDebugLoc())); + Vals.push_back(VE.getMetadataID(DVR.getVariable())); + Vals.push_back(VE.getMetadataID(DVR.getExpression())); + if (DVR.isDbgValue()) { + if (PushValueOrMetadata(DVR.getRawLocation())) Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE, Vals, FUNCTION_DEBUG_RECORD_VALUE_ABBREV); else Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_VALUE, Vals); - } else if (DPV.isDbgDeclare()) { - Vals.push_back(VE.getMetadataID(DPV.getRawLocation())); + } else if (DVR.isDbgDeclare()) { + Vals.push_back(VE.getMetadataID(DVR.getRawLocation())); Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_DECLARE, Vals); } else { - assert(DPV.isDbgAssign() && "Unexpected DbgRecord kind"); - Vals.push_back(VE.getMetadataID(DPV.getRawLocation())); - Vals.push_back(VE.getMetadataID(DPV.getAssignID())); - Vals.push_back(VE.getMetadataID(DPV.getAddressExpression())); - Vals.push_back(VE.getMetadataID(DPV.getRawAddress())); + assert(DVR.isDbgAssign() && "Unexpected DbgRecord kind"); + Vals.push_back(VE.getMetadataID(DVR.getRawLocation())); + Vals.push_back(VE.getMetadataID(DVR.getAssignID())); + Vals.push_back(VE.getMetadataID(DVR.getAddressExpression())); + Vals.push_back(VE.getMetadataID(DVR.getRawAddress())); Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN, Vals); } Vals.clear(); diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 1c439c954321..3209dca253fe 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -144,10 +144,10 @@ static OrderMap orderModule(const Module &M) { } }; - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - OrderConstantFromMetadata(DPV.getRawLocation()); - if (DPV.isDbgAssign()) - OrderConstantFromMetadata(DPV.getRawAddress()); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + OrderConstantFromMetadata(DVR.getRawLocation()); + if (DVR.isDbgAssign()) + OrderConstantFromMetadata(DVR.getRawAddress()); } for (const Value *V : I.operands()) { @@ -285,10 +285,10 @@ static UseListOrderStack predictUseListOrder(const Module &M) { predictValueUseListOrder(&A, &F, OM, Stack); for (const BasicBlock &BB : F) { for (const Instruction &I : BB) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - PredictValueOrderFromMetadata(DPV.getRawLocation()); - if (DPV.isDbgAssign()) - PredictValueOrderFromMetadata(DPV.getRawAddress()); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + PredictValueOrderFromMetadata(DVR.getRawLocation()); + if (DVR.isDbgAssign()) + PredictValueOrderFromMetadata(DVR.getRawAddress()); } for (const Value *Op : I.operands()) { if (isa<Constant>(*Op) || isa<InlineAsm>(*Op)) // Visit GlobalValues. @@ -447,15 +447,15 @@ ValueEnumerator::ValueEnumerator(const Module &M, continue; } // Enumerate non-local location metadata. - DPValue &DPV = cast<DPValue>(DR); - EnumerateNonLocalValuesFromMetadata(DPV.getRawLocation()); - EnumerateMetadata(&F, DPV.getExpression()); - EnumerateMetadata(&F, DPV.getVariable()); - EnumerateMetadata(&F, &*DPV.getDebugLoc()); - if (DPV.isDbgAssign()) { - EnumerateNonLocalValuesFromMetadata(DPV.getRawAddress()); - EnumerateMetadata(&F, DPV.getAssignID()); - EnumerateMetadata(&F, DPV.getAddressExpression()); + DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR); + EnumerateNonLocalValuesFromMetadata(DVR.getRawLocation()); + EnumerateMetadata(&F, DVR.getExpression()); + EnumerateMetadata(&F, DVR.getVariable()); + EnumerateMetadata(&F, &*DVR.getDebugLoc()); + if (DVR.isDbgAssign()) { + EnumerateNonLocalValuesFromMetadata(DVR.getRawAddress()); + EnumerateMetadata(&F, DVR.getAssignID()); + EnumerateMetadata(&F, DVR.getAddressExpression()); } } for (const Use &Op : I.operands()) { @@ -1128,12 +1128,14 @@ void ValueEnumerator::incorporateFunction(const Function &F) { AddFnLocalMetadata(MD->getMetadata()); } /// RemoveDIs: Add non-instruction function-local metadata uses. - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - assert(DPV.getRawLocation() && "DPValue location unexpectedly null"); - AddFnLocalMetadata(DPV.getRawLocation()); - if (DPV.isDbgAssign()) { - assert(DPV.getRawAddress() && "DPValue location unexpectedly null"); - AddFnLocalMetadata(DPV.getRawAddress()); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + assert(DVR.getRawLocation() && + "DbgVariableRecord location unexpectedly null"); + AddFnLocalMetadata(DVR.getRawLocation()); + if (DVR.isDbgAssign()) { + assert(DVR.getRawAddress() && + "DbgVariableRecord location unexpectedly null"); + AddFnLocalMetadata(DVR.getRawAddress()); } } if (!I.getType()->isVoidTy()) diff --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp index 52774c7d7322..09177950fc82 100644 --- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp +++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp @@ -215,7 +215,8 @@ void FunctionVarLocs::init(FunctionVarLocsBuilder &Builder) { // Insert a contiguous block of VarLocInfos for each instruction, mapping it // to the start and end position in the vector with VarLocsBeforeInst. This - // block includes VarLocs for any DPValues attached to that instruction. + // block includes VarLocs for any DbgVariableRecords attached to that + // instruction. for (auto &P : Builder.VarLocsBeforeInst) { // Process VarLocs attached to a DbgRecord alongside their marker // Instruction. @@ -226,12 +227,12 @@ void FunctionVarLocs::init(FunctionVarLocsBuilder &Builder) { // Any VarLocInfos attached to a DbgRecord should now be remapped to their // marker Instruction, in order of DbgRecord appearance and prior to any // VarLocInfos attached directly to that instruction. - for (const DPValue &DPV : filterDbgVars(I->getDbgRecordRange())) { - // Even though DPV defines a variable location, VarLocsBeforeInst can + for (const DbgVariableRecord &DVR : filterDbgVars(I->getDbgRecordRange())) { + // Even though DVR defines a variable location, VarLocsBeforeInst can // still be empty if that VarLoc was redundant. - if (!Builder.VarLocsBeforeInst.count(&DPV)) + if (!Builder.VarLocsBeforeInst.count(&DVR)) continue; - for (const VarLocInfo &VarLoc : Builder.VarLocsBeforeInst[&DPV]) + for (const VarLocInfo &VarLoc : Builder.VarLocsBeforeInst[&DVR]) VarLocRecords.emplace_back(VarLoc); } for (const VarLocInfo &VarLoc : P.second) @@ -830,10 +831,10 @@ class MemLocFragmentFill { void process(BasicBlock &BB, VarFragMap &LiveSet) { BBInsertBeforeMap[&BB].clear(); for (auto &I : BB) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - if (const auto *Locs = FnVarLocs->getWedge(&DPV)) { + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + if (const auto *Locs = FnVarLocs->getWedge(&DVR)) { for (const VarLocInfo &Loc : *Locs) { - addDef(Loc, &DPV, *I.getParent(), LiveSet); + addDef(Loc, &DVR, *I.getParent(), LiveSet); } } } @@ -1027,7 +1028,7 @@ public: /// i.e. for all values x and y where x != y: /// join(x, x) = x /// join(x, y) = NoneOrPhi - using AssignRecord = PointerUnion<DbgAssignIntrinsic *, DPValue *>; + using AssignRecord = PointerUnion<DbgAssignIntrinsic *, DbgVariableRecord *>; struct Assignment { enum S { Known, NoneOrPhi } Status; /// ID of the assignment. nullptr if Status is not Known. @@ -1054,16 +1055,16 @@ public: else if (isa<DbgAssignIntrinsic *>(Source)) OS << Source.get<DbgAssignIntrinsic *>(); else - OS << Source.get<DPValue *>(); + OS << Source.get<DbgVariableRecord *>(); OS << ")"; } static Assignment make(DIAssignID *ID, DbgAssignIntrinsic *Source) { return Assignment(Known, ID, Source); } - static Assignment make(DIAssignID *ID, DPValue *Source) { + static Assignment make(DIAssignID *ID, DbgVariableRecord *Source) { assert(Source->isDbgAssign() && - "Cannot make an assignment from a non-assign DPValue"); + "Cannot make an assignment from a non-assign DbgVariableRecord"); return Assignment(Known, ID, Source); } static Assignment make(DIAssignID *ID, AssignRecord Source) { @@ -1084,7 +1085,7 @@ public: // If the Status is Known then we expect there to be an assignment ID. assert(Status == NoneOrPhi || ID); } - Assignment(S Status, DIAssignID *ID, DPValue *Source) + Assignment(S Status, DIAssignID *ID, DbgVariableRecord *Source) : Status(Status), ID(ID), Source(Source) { // If the Status is Known then we expect there to be an assignment ID. assert(Status == NoneOrPhi || ID); @@ -1119,10 +1120,10 @@ private: /// Clear the location definitions currently cached for insertion after /p /// After. void resetInsertionPoint(Instruction &After); - void resetInsertionPoint(DPValue &After); + void resetInsertionPoint(DbgVariableRecord &After); // emitDbgValue can be called with: - // Source=[AssignRecord|DbgValueInst*|DbgAssignIntrinsic*|DPValue*] + // Source=[AssignRecord|DbgValueInst*|DbgAssignIntrinsic*|DbgVariableRecord*] // Since AssignRecord can be cast to one of the latter two types, and all // other types have a shared interface, we use a template to handle the latter // three types, and an explicit overload for AssignRecord that forwards to @@ -1355,9 +1356,10 @@ private: /// attachment, \p I. void processUntaggedInstruction(Instruction &I, BlockInfo *LiveSet); void processDbgAssign(AssignRecord Assign, BlockInfo *LiveSet); - void processDPValue(DPValue &DPV, BlockInfo *LiveSet); - void processDbgValue(PointerUnion<DbgValueInst *, DPValue *> DbgValueRecord, - BlockInfo *LiveSet); + void processDbgVariableRecord(DbgVariableRecord &DVR, BlockInfo *LiveSet); + void processDbgValue( + PointerUnion<DbgValueInst *, DbgVariableRecord *> DbgValueRecord, + BlockInfo *LiveSet); /// Add an assignment to memory for the variable /p Var. void addMemDef(BlockInfo *LiveSet, VariableID Var, const Assignment &AV); /// Add an assignment to the variable /p Var. @@ -1457,10 +1459,10 @@ static DIAssignID *getIDFromMarker(const DbgAssignIntrinsic &DAI) { return cast<DIAssignID>(DAI.getAssignID()); } -static DIAssignID *getIDFromMarker(const DPValue &DPV) { - assert(DPV.isDbgAssign() && - "Cannot get a DIAssignID from a non-assign DPValue!"); - return DPV.getAssignID(); +static DIAssignID *getIDFromMarker(const DbgVariableRecord &DVR) { + assert(DVR.isDbgAssign() && + "Cannot get a DIAssignID from a non-assign DbgVariableRecord!"); + return DVR.getAssignID(); } /// Return true if \p Var has an assignment in \p M matching \p AV. @@ -1493,10 +1495,10 @@ const char *locStr(AssignmentTrackingLowering::LocKind Loc) { } #endif -VarLocInsertPt getNextNode(const DbgRecord *DPV) { - auto NextIt = ++(DPV->getIterator()); - if (NextIt == DPV->getMarker()->getDbgRecordRange().end()) - return DPV->getMarker()->MarkedInstr; +VarLocInsertPt getNextNode(const DbgRecord *DVR) { + auto NextIt = ++(DVR->getIterator()); + if (NextIt == DVR->getMarker()->getDbgRecordRange().end()) + return DVR->getMarker()->MarkedInstr; return &*NextIt; } VarLocInsertPt getNextNode(const Instruction *Inst) { @@ -1515,10 +1517,10 @@ DbgAssignIntrinsic *CastToDbgAssign(DbgVariableIntrinsic *DVI) { return cast<DbgAssignIntrinsic>(DVI); } -DPValue *CastToDbgAssign(DPValue *DPV) { - assert(DPV->isDbgAssign() && - "Attempted to cast non-assign DPValue to DPVAssign."); - return DPV; +DbgVariableRecord *CastToDbgAssign(DbgVariableRecord *DVR) { + assert(DVR->isDbgAssign() && + "Attempted to cast non-assign DbgVariableRecord to DVRAssign."); + return DVR; } void AssignmentTrackingLowering::emitDbgValue( @@ -1527,7 +1529,7 @@ void AssignmentTrackingLowering::emitDbgValue( if (isa<DbgAssignIntrinsic *>(Source)) emitDbgValue(Kind, cast<DbgAssignIntrinsic *>(Source), After); else - emitDbgValue(Kind, cast<DPValue *>(Source), After); + emitDbgValue(Kind, cast<DbgVariableRecord *>(Source), After); } template <typename T> void AssignmentTrackingLowering::emitDbgValue( @@ -1674,7 +1676,7 @@ void AssignmentTrackingLowering::processUntaggedInstruction( void AssignmentTrackingLowering::processTaggedInstruction( Instruction &I, AssignmentTrackingLowering::BlockInfo *LiveSet) { auto Linked = at::getAssignmentMarkers(&I); - auto LinkedDPAssigns = at::getDPVAssignmentMarkers(&I); + auto LinkedDPAssigns = at::getDVRAssignmentMarkers(&I); // No dbg.assign intrinsics linked. // FIXME: All vars that have a stack slot this store modifies that don't have // a dbg.assign linked to it should probably treat this like an untagged @@ -1757,8 +1759,8 @@ void AssignmentTrackingLowering::processTaggedInstruction( }; for (DbgAssignIntrinsic *DAI : Linked) ProcessLinkedAssign(DAI); - for (DPValue *DPV : LinkedDPAssigns) - ProcessLinkedAssign(DPV); + for (DbgVariableRecord *DVR : LinkedDPAssigns) + ProcessLinkedAssign(DVR); } void AssignmentTrackingLowering::processDbgAssign(AssignRecord Assign, @@ -1803,13 +1805,13 @@ void AssignmentTrackingLowering::processDbgAssign(AssignRecord Assign, emitDbgValue(LocKind::Val, DbgAssign, DbgAssign); } }; - if (isa<DPValue *>(Assign)) - return ProcessDbgAssignImpl(cast<DPValue *>(Assign)); + if (isa<DbgVariableRecord *>(Assign)) + return ProcessDbgAssignImpl(cast<DbgVariableRecord *>(Assign)); return ProcessDbgAssignImpl(cast<DbgAssignIntrinsic *>(Assign)); } void AssignmentTrackingLowering::processDbgValue( - PointerUnion<DbgValueInst *, DPValue *> DbgValueRecord, + PointerUnion<DbgValueInst *, DbgVariableRecord *> DbgValueRecord, BlockInfo *LiveSet) { auto ProcessDbgValueImpl = [&](auto *DbgValue) { // Only other tracking variables that are at some point stack homed. @@ -1834,8 +1836,8 @@ void AssignmentTrackingLowering::processDbgValue( setLocKind(LiveSet, Var, LocKind::Val); emitDbgValue(LocKind::Val, DbgValue, DbgValue); }; - if (isa<DPValue *>(DbgValueRecord)) - return ProcessDbgValueImpl(cast<DPValue *>(DbgValueRecord)); + if (isa<DbgVariableRecord *>(DbgValueRecord)) + return ProcessDbgValueImpl(cast<DbgVariableRecord *>(DbgValueRecord)); return ProcessDbgValueImpl(cast<DbgValueInst *>(DbgValueRecord)); } @@ -1860,16 +1862,16 @@ void AssignmentTrackingLowering::processDbgInstruction( else if (auto *DVI = dyn_cast<DbgValueInst>(&I)) processDbgValue(DVI, LiveSet); } -void AssignmentTrackingLowering::processDPValue( - DPValue &DPV, AssignmentTrackingLowering::BlockInfo *LiveSet) { +void AssignmentTrackingLowering::processDbgVariableRecord( + DbgVariableRecord &DVR, AssignmentTrackingLowering::BlockInfo *LiveSet) { // Ignore assignments to zero bits of the variable. - if (hasZeroSizedFragment(DPV)) + if (hasZeroSizedFragment(DVR)) return; - if (DPV.isDbgAssign()) - processDbgAssign(&DPV, LiveSet); - else if (DPV.isDbgValue()) - processDbgValue(&DPV, LiveSet); + if (DVR.isDbgAssign()) + processDbgAssign(&DVR, LiveSet); + else if (DVR.isDbgValue()) + processDbgValue(&DVR, LiveSet); } void AssignmentTrackingLowering::resetInsertionPoint(Instruction &After) { @@ -1879,7 +1881,7 @@ void AssignmentTrackingLowering::resetInsertionPoint(Instruction &After) { return; R->second.clear(); } -void AssignmentTrackingLowering::resetInsertionPoint(DPValue &After) { +void AssignmentTrackingLowering::resetInsertionPoint(DbgVariableRecord &After) { auto *R = InsertBeforeMap.find(getNextNode(&After)); if (R == InsertBeforeMap.end()) return; @@ -1919,9 +1921,9 @@ void AssignmentTrackingLowering::process(BasicBlock &BB, BlockInfo *LiveSet) { // Skip over non-variable debug records (i.e., labels). They're going to // be read from IR (possibly re-ordering them within the debug record // range) rather than from the analysis results. - for (DPValue &DPV : filterDbgVars(II->getDbgRecordRange())) { - resetInsertionPoint(DPV); - processDPValue(DPV, LiveSet); + for (DbgVariableRecord &DVR : filterDbgVars(II->getDbgRecordRange())) { + resetInsertionPoint(DVR); + processDbgVariableRecord(DVR, LiveSet); assert(LiveSet->isValid()); } } @@ -2000,9 +2002,11 @@ AssignmentTrackingLowering::joinAssignment(const Assignment &A, return A.Source; if (!A.Source || !B.Source) return AssignRecord(); - assert(isa<DPValue *>(A.Source) == isa<DPValue *>(B.Source)); - if (isa<DPValue *>(A.Source) && - cast<DPValue *>(A.Source)->isEquivalentTo(*cast<DPValue *>(B.Source))) + assert(isa<DbgVariableRecord *>(A.Source) == + isa<DbgVariableRecord *>(B.Source)); + if (isa<DbgVariableRecord *>(A.Source) && + cast<DbgVariableRecord *>(A.Source)->isEquivalentTo( + *cast<DbgVariableRecord *>(B.Source))) return A.Source; if (isa<DbgAssignIntrinsic *>(A.Source) && cast<DbgAssignIntrinsic *>(A.Source)->isIdenticalTo( @@ -2123,8 +2127,8 @@ DbgDeclareInst *DynCastToDbgDeclare(DbgVariableIntrinsic *DVI) { return dyn_cast<DbgDeclareInst>(DVI); } -DPValue *DynCastToDbgDeclare(DPValue *DPV) { - return DPV->isDbgDeclare() ? DPV : nullptr; +DbgVariableRecord *DynCastToDbgDeclare(DbgVariableRecord *DVR) { + return DVR->isDbgDeclare() ? DVR : nullptr; } /// Build a map of {Variable x: Variables y} where all variable fragments @@ -2161,7 +2165,7 @@ static AssignmentTrackingLowering::OverlapMap buildOverlapMapAndRecordDeclares( // We need to add fragments for untagged stores too so that we can correctly // clobber overlapped fragment locations later. SmallVector<DbgDeclareInst *> InstDeclares; - SmallVector<DPValue *> DPDeclares; + SmallVector<DbgVariableRecord *> DPDeclares; auto ProcessDbgRecord = [&](auto *Record, auto &DeclareList) { if (auto *Declare = DynCastToDbgDeclare(Record)) { DeclareList.push_back(Declare); @@ -2176,8 +2180,8 @@ static AssignmentTrackingLowering::OverlapMap buildOverlapMapAndRecordDeclares( }; for (auto &BB : Fn) { for (auto &I : BB) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) - ProcessDbgRecord(&DPV, DPDeclares); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) + ProcessDbgRecord(&DVR, DPDeclares); if (auto *DII = dyn_cast<DbgVariableIntrinsic>(&I)) { ProcessDbgRecord(DII, InstDeclares); } else if (auto Info = getUntaggedStoreAssignmentInfo( @@ -2218,8 +2222,8 @@ static AssignmentTrackingLowering::OverlapMap buildOverlapMapAndRecordDeclares( }; for (DbgAssignIntrinsic *DAI : at::getAssignmentMarkers(Info->Base)) HandleDbgAssignForStore(DAI); - for (DPValue *DPV : at::getDPVAssignmentMarkers(Info->Base)) - HandleDbgAssignForStore(DPV); + for (DbgVariableRecord *DVR : at::getDVRAssignmentMarkers(Info->Base)) + HandleDbgAssignForStore(DVR); } } } @@ -2269,10 +2273,10 @@ static AssignmentTrackingLowering::OverlapMap buildOverlapMapAndRecordDeclares( for (auto *DDI : InstDeclares) FnVarLocs->addSingleLocVar(DebugVariable(DDI), DDI->getExpression(), DDI->getDebugLoc(), DDI->getWrappedLocation()); - for (auto *DPV : DPDeclares) - FnVarLocs->addSingleLocVar(DebugVariable(DPV), DPV->getExpression(), - DPV->getDebugLoc(), - RawLocationWrapper(DPV->getRawLocation())); + for (auto *DVR : DPDeclares) + FnVarLocs->addSingleLocVar(DebugVariable(DVR), DVR->getExpression(), + DVR->getDebugLoc(), + RawLocationWrapper(DVR->getRawLocation())); return Map; } @@ -2466,9 +2470,9 @@ bool AssignmentTrackingLowering::emitPromotedVarLocs( for (auto &BB : Fn) { for (auto &I : BB) { // Skip instructions other than dbg.values and dbg.assigns. - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) - if (DPV.isDbgValue() || DPV.isDbgAssign()) - TranslateDbgRecord(&DPV); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) + if (DVR.isDbgValue() || DVR.isDbgAssign()) + TranslateDbgRecord(&DVR); auto *DVI = dyn_cast<DbgValueInst>(&I); if (DVI) TranslateDbgRecord(DVI); @@ -2568,8 +2572,8 @@ removeRedundantDbgLocsUsingBackwardScan(const BasicBlock *BB, } }; HandleLocsForWedge(&I); - for (DPValue &DPV : reverse(filterDbgVars(I.getDbgRecordRange()))) - HandleLocsForWedge(&DPV); + for (DbgVariableRecord &DVR : reverse(filterDbgVars(I.getDbgRecordRange()))) + HandleLocsForWedge(&DVR); } return Changed; @@ -2633,8 +2637,8 @@ removeRedundantDbgLocsUsingForwardScan(const BasicBlock *BB, } }; - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) - HandleLocsForWedge(&DPV); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) + HandleLocsForWedge(&DVR); HandleLocsForWedge(&I); } @@ -2719,8 +2723,8 @@ removeUndefDbgLocsFromEntryBlock(const BasicBlock *BB, Changed = true; } }; - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) - HandleLocsForWedge(&DPV); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) + HandleLocsForWedge(&DVR); HandleLocsForWedge(&I); } @@ -2753,8 +2757,8 @@ static DenseSet<DebugAggregate> findVarsWithStackSlot(Function &Fn) { for (DbgAssignIntrinsic *DAI : at::getAssignmentMarkers(&I)) { Result.insert({DAI->getVariable(), DAI->getDebugLoc().getInlinedAt()}); } - for (DPValue *DPV : at::getDPVAssignmentMarkers(&I)) { - Result.insert({DPV->getVariable(), DPV->getDebugLoc().getInlinedAt()}); + for (DbgVariableRecord *DVR : at::getDVRAssignmentMarkers(&I)) { + Result.insert({DVR->getVariable(), DVR->getDebugLoc().getInlinedAt()}); } } } diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index e7bf656491da..9f99bb7e693f 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -445,8 +445,8 @@ private: bool optimizeExtractElementInst(Instruction *Inst); bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT); bool fixupDbgValue(Instruction *I); - bool fixupDPValue(DPValue &I); - bool fixupDPValuesOnInst(Instruction &I); + bool fixupDbgVariableRecord(DbgVariableRecord &I); + bool fixupDbgVariableRecordsOnInst(Instruction &I); bool placeDbgValues(Function &F); bool placePseudoProbes(Function &F); bool canFormExtLd(const SmallVectorImpl<Instruction *> &MovedExts, @@ -3223,7 +3223,7 @@ class TypePromotionTransaction { /// Keep track of the debug users. SmallVector<DbgValueInst *, 1> DbgValues; /// And non-instruction debug-users too. - SmallVector<DPValue *, 1> DPValues; + SmallVector<DbgVariableRecord *, 1> DbgVariableRecords; /// Keep track of the new value so that we can undo it by replacing /// instances of the new value with the original value. @@ -3244,7 +3244,7 @@ class TypePromotionTransaction { } // Record the debug uses separately. They are not in the instruction's // use list, but they are replaced by RAUW. - findDbgValues(DbgValues, Inst, &DPValues); + findDbgValues(DbgValues, Inst, &DbgVariableRecords); // Now, we can replace the uses. Inst->replaceAllUsesWith(New); @@ -3261,10 +3261,10 @@ class TypePromotionTransaction { // correctness and utility of debug value instructions. for (auto *DVI : DbgValues) DVI->replaceVariableLocationOp(New, Inst); - // Similar story with DPValues, the non-instruction representation of - // dbg.values. - for (DPValue *DPV : DPValues) // tested by transaction-test I'm adding - DPV->replaceVariableLocationOp(New, Inst); + // Similar story with DbgVariableRecords, the non-instruction + // representation of dbg.values. + for (DbgVariableRecord *DVR : DbgVariableRecords) + DVR->replaceVariableLocationOp(New, Inst); } }; @@ -7117,9 +7117,9 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { CurInstIterator = std::next(LastSI->getIterator()); // Examine debug-info attached to the consecutive select instructions. They // won't be individually optimised by optimizeInst, so we need to perform - // DPValue maintenence here instead. + // DbgVariableRecord maintenence here instead. for (SelectInst *SI : ArrayRef(ASI).drop_front()) - fixupDPValuesOnInst(*SI); + fixupDbgVariableRecordsOnInst(*SI); bool VectorCond = !SI->getCondition()->getType()->isIntegerTy(1); @@ -8275,7 +8275,7 @@ static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI, bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) { bool AnyChange = false; - AnyChange = fixupDPValuesOnInst(*I); + AnyChange = fixupDbgVariableRecordsOnInst(*I); // Bail out if we inserted the instruction to prevent optimizations from // stepping on each other's toes. @@ -8541,24 +8541,24 @@ bool CodeGenPrepare::fixupDbgValue(Instruction *I) { return AnyChange; } -bool CodeGenPrepare::fixupDPValuesOnInst(Instruction &I) { +bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &I) { bool AnyChange = false; - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) - AnyChange |= fixupDPValue(DPV); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) + AnyChange |= fixupDbgVariableRecord(DVR); return AnyChange; } // FIXME: should updating debug-info really cause the "changed" flag to fire, // which can cause a function to be reprocessed? -bool CodeGenPrepare::fixupDPValue(DPValue &DPV) { - if (DPV.Type != DPValue::LocationType::Value && - DPV.Type != DPValue::LocationType::Assign) +bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) { + if (DVR.Type != DbgVariableRecord::LocationType::Value && + DVR.Type != DbgVariableRecord::LocationType::Assign) return false; - // Does this DPValue refer to a sunk address calculation? + // Does this DbgVariableRecord refer to a sunk address calculation? bool AnyChange = false; - SmallDenseSet<Value *> LocationOps(DPV.location_ops().begin(), - DPV.location_ops().end()); + SmallDenseSet<Value *> LocationOps(DVR.location_ops().begin(), + DVR.location_ops().end()); for (Value *Location : LocationOps) { WeakTrackingVH SunkAddrVH = SunkAddrs[Location]; Value *SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr; @@ -8568,7 +8568,7 @@ bool CodeGenPrepare::fixupDPValue(DPValue &DPV) { // of pointer being referred to; however this makes no difference to // debugging information, and we can't generate bitcasts that may affect // codegen. - DPV.replaceVariableLocationOp(Location, SunkAddr); + DVR.replaceVariableLocationOp(Location, SunkAddr); AnyChange = true; } } @@ -8583,13 +8583,13 @@ static void DbgInserterHelper(DbgValueInst *DVI, Instruction *VI) { DVI->insertAfter(VI); } -static void DbgInserterHelper(DPValue *DPV, Instruction *VI) { - DPV->removeFromParent(); +static void DbgInserterHelper(DbgVariableRecord *DVR, Instruction *VI) { + DVR->removeFromParent(); BasicBlock *VIBB = VI->getParent(); if (isa<PHINode>(VI)) - VIBB->insertDbgRecordBefore(DPV, VIBB->getFirstInsertionPt()); + VIBB->insertDbgRecordBefore(DVR, VIBB->getFirstInsertionPt()); else - VIBB->insertDbgRecordAfter(DPV, VI); + VIBB->insertDbgRecordAfter(DVR, VI); } // A llvm.dbg.value may be using a value before its definition, due to @@ -8654,13 +8654,13 @@ bool CodeGenPrepare::placeDbgValues(Function &F) { continue; } - // If this isn't a dbg.value, process any attached DPValue records - // attached to this instruction. - for (DPValue &DPV : llvm::make_early_inc_range( + // If this isn't a dbg.value, process any attached DbgVariableRecord + // records attached to this instruction. + for (DbgVariableRecord &DVR : llvm::make_early_inc_range( filterDbgVars(Insn.getDbgRecordRange()))) { - if (DPV.Type != DPValue::LocationType::Value) + if (DVR.Type != DbgVariableRecord::LocationType::Value) continue; - DbgProcessor(&DPV, &Insn); + DbgProcessor(&DVR, &Insn); } } } diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 47ee2ee50713..4c1467ce1c41 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -3386,16 +3386,16 @@ void IRTranslator::translateDbgInfo(const Instruction &Inst, MIRBuilder.buildDbgLabel(DPL->getLabel()); continue; } - DPValue &DPV = cast<DPValue>(DR); - const DILocalVariable *Variable = DPV.getVariable(); - const DIExpression *Expression = DPV.getExpression(); - Value *V = DPV.getVariableLocationOp(0); - if (DPV.isDbgDeclare()) - translateDbgDeclareRecord(V, DPV.hasArgList(), Variable, - Expression, DPV.getDebugLoc(), MIRBuilder); + DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR); + const DILocalVariable *Variable = DVR.getVariable(); + const DIExpression *Expression = DVR.getExpression(); + Value *V = DVR.getVariableLocationOp(0); + if (DVR.isDbgDeclare()) + translateDbgDeclareRecord(V, DVR.hasArgList(), Variable, Expression, + DVR.getDebugLoc(), MIRBuilder); else - translateDbgValueRecord(V, DPV.hasArgList(), Variable, - Expression, DPV.getDebugLoc(), MIRBuilder); + translateDbgValueRecord(V, DVR.hasArgList(), Variable, Expression, + DVR.getDebugLoc(), MIRBuilder); } } diff --git a/llvm/lib/CodeGen/SelectOptimize.cpp b/llvm/lib/CodeGen/SelectOptimize.cpp index f65d5320bab9..2e03ae6aec94 100644 --- a/llvm/lib/CodeGen/SelectOptimize.cpp +++ b/llvm/lib/CodeGen/SelectOptimize.cpp @@ -624,8 +624,8 @@ void SelectOptimizeImpl::convertProfitableSIGroups(SelectGroups &ProfSIGroups) { // With RemoveDIs turned off, SplitPt can be a dbg.* intrinsic. With // RemoveDIs turned on, SplitPt would instead point to the next // instruction. To match existing dbg.* intrinsic behaviour with RemoveDIs, - // tell splitBasicBlock that we want to include any DPValues attached to - // SplitPt in the splice. + // tell splitBasicBlock that we want to include any DbgVariableRecords + // attached to SplitPt in the splice. SplitPt.setHeadBit(true); BasicBlock *EndBlock = StartBlock->splitBasicBlock(SplitPt, "select.end"); BFI->setBlockFreq(EndBlock, BFI->getBlockFreq(StartBlock)); diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index cce91dbd9531..8b834862fb4d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1205,27 +1205,27 @@ void FastISel::handleDbgInfo(const Instruction *II) { continue; } - DPValue &DPV = cast<DPValue>(DR); + DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR); Value *V = nullptr; - if (!DPV.hasArgList()) - V = DPV.getVariableLocationOp(0); + if (!DVR.hasArgList()) + V = DVR.getVariableLocationOp(0); bool Res = false; - if (DPV.getType() == DPValue::LocationType::Value || - DPV.getType() == DPValue::LocationType::Assign) { - Res = lowerDbgValue(V, DPV.getExpression(), DPV.getVariable(), - DPV.getDebugLoc()); + if (DVR.getType() == DbgVariableRecord::LocationType::Value || + DVR.getType() == DbgVariableRecord::LocationType::Assign) { + Res = lowerDbgValue(V, DVR.getExpression(), DVR.getVariable(), + DVR.getDebugLoc()); } else { - assert(DPV.getType() == DPValue::LocationType::Declare); - if (FuncInfo.PreprocessedDPVDeclares.contains(&DPV)) + assert(DVR.getType() == DbgVariableRecord::LocationType::Declare); + if (FuncInfo.PreprocessedDVRDeclares.contains(&DVR)) continue; - Res = lowerDbgDeclare(V, DPV.getExpression(), DPV.getVariable(), - DPV.getDebugLoc()); + Res = lowerDbgDeclare(V, DVR.getExpression(), DVR.getVariable(), + DVR.getDebugLoc()); } if (!Res) - LLVM_DEBUG(dbgs() << "Dropping debug-info for " << DPV << "\n";); + LLVM_DEBUG(dbgs() << "Dropping debug-info for " << DVR << "\n";); } } diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index e01cd8cbf925..8fb6b11b8805 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -358,7 +358,7 @@ void FunctionLoweringInfo::clear() { StatepointRelocationMaps.clear(); PreferredExtendType.clear(); PreprocessedDbgDeclares.clear(); - PreprocessedDPVDeclares.clear(); + PreprocessedDVRDeclares.clear(); } /// CreateReg - Allocate a single virtual register for the given type. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 8780f4b93148..dd19ee16d1d6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1245,14 +1245,14 @@ void SelectionDAGBuilder::visitDbgInfo(const Instruction &I) { } } - // We must skip DPValues if they've already been processed above as we - // have just emitted the debug values resulting from assignment tracking - // analysis, making any existing DPValues redundant (and probably less - // correct). We still need to process DPLabels. This does sink DPLabels + // We must skip DbgVariableRecords if they've already been processed above as + // we have just emitted the debug values resulting from assignment tracking + // analysis, making any existing DbgVariableRecords redundant (and probably + // less correct). We still need to process DPLabels. This does sink DPLabels // to the bottom of the group of debug records. That sholdn't be important - // as it does so deterministcally and ordering between DPLabels and DPValues - // is immaterial (other than for MIR/IR printing). - bool SkipDPValues = DAG.getFunctionVarLocs(); + // as it does so deterministcally and ordering between DPLabels and + // DbgVariableRecords is immaterial (other than for MIR/IR printing). + bool SkipDbgVariableRecords = DAG.getFunctionVarLocs(); // Is there is any debug-info attached to this instruction, in the form of // DbgRecord non-instruction debug-info records. for (DbgRecord &DR : I.getDbgRecordRange()) { @@ -1264,44 +1264,45 @@ void SelectionDAGBuilder::visitDbgInfo(const Instruction &I) { continue; } - if (SkipDPValues) + if (SkipDbgVariableRecords) continue; - DPValue &DPV = cast<DPValue>(DR); - DILocalVariable *Variable = DPV.getVariable(); - DIExpression *Expression = DPV.getExpression(); + DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR); + DILocalVariable *Variable = DVR.getVariable(); + DIExpression *Expression = DVR.getExpression(); dropDanglingDebugInfo(Variable, Expression); - if (DPV.getType() == DPValue::LocationType::Declare) { - if (FuncInfo.PreprocessedDPVDeclares.contains(&DPV)) + if (DVR.getType() == DbgVariableRecord::LocationType::Declare) { + if (FuncInfo.PreprocessedDVRDeclares.contains(&DVR)) continue; - LLVM_DEBUG(dbgs() << "SelectionDAG visiting dbg_declare: " << DPV + LLVM_DEBUG(dbgs() << "SelectionDAG visiting dbg_declare: " << DVR << "\n"); - handleDebugDeclare(DPV.getVariableLocationOp(0), Variable, Expression, - DPV.getDebugLoc()); + handleDebugDeclare(DVR.getVariableLocationOp(0), Variable, Expression, + DVR.getDebugLoc()); continue; } - // A DPValue with no locations is a kill location. - SmallVector<Value *, 4> Values(DPV.location_ops()); + // A DbgVariableRecord with no locations is a kill location. + SmallVector<Value *, 4> Values(DVR.location_ops()); if (Values.empty()) { - handleKillDebugValue(Variable, Expression, DPV.getDebugLoc(), + handleKillDebugValue(Variable, Expression, DVR.getDebugLoc(), SDNodeOrder); continue; } - // A DPValue with an undef or absent location is also a kill location. + // A DbgVariableRecord with an undef or absent location is also a kill + // location. if (llvm::any_of(Values, [](Value *V) { return !V || isa<UndefValue>(V); })) { - handleKillDebugValue(Variable, Expression, DPV.getDebugLoc(), + handleKillDebugValue(Variable, Expression, DVR.getDebugLoc(), SDNodeOrder); continue; } - bool IsVariadic = DPV.hasArgList(); - if (!handleDebugValue(Values, Variable, Expression, DPV.getDebugLoc(), + bool IsVariadic = DVR.hasArgList(); + if (!handleDebugValue(Values, Variable, Expression, DVR.getDebugLoc(), SDNodeOrder, IsVariadic)) { addDanglingDebugInfo(Values, Variable, Expression, IsVariadic, - DPV.getDebugLoc(), SDNodeOrder); + DVR.getDebugLoc(), SDNodeOrder); } } } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 30f67d37e2e2..d629c36bc792 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1461,12 +1461,12 @@ static void processDbgDeclares(FunctionLoweringInfo &FuncInfo) { if (DI && processDbgDeclare(FuncInfo, DI->getAddress(), DI->getExpression(), DI->getVariable(), DI->getDebugLoc())) FuncInfo.PreprocessedDbgDeclares.insert(DI); - for (const DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - if (DPV.Type == DPValue::LocationType::Declare && - processDbgDeclare(FuncInfo, DPV.getVariableLocationOp(0), - DPV.getExpression(), DPV.getVariable(), - DPV.getDebugLoc())) - FuncInfo.PreprocessedDPVDeclares.insert(&DPV); + for (const DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + if (DVR.Type == DbgVariableRecord::LocationType::Declare && + processDbgDeclare(FuncInfo, DVR.getVariableLocationOp(0), + DVR.getExpression(), DVR.getVariable(), + DVR.getDebugLoc())) + FuncInfo.PreprocessedDVRDeclares.insert(&DVR); } } } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index f65762123bf3..d7fee609a2ba 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -862,7 +862,7 @@ private: void processInstructionMetadata(const Instruction &I); /// Add all of the metadata from a DbgRecord. - void processDbgRecordMetadata(const DbgRecord &DPV); + void processDbgRecordMetadata(const DbgRecord &DVR); }; } // end namespace llvm @@ -1139,17 +1139,17 @@ void SlotTracker::processFunctionMetadata(const Function &F) { } void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) { - if (const DPValue *DPV = dyn_cast<const DPValue>(&DR)) { + if (const DbgVariableRecord *DVR = dyn_cast<const DbgVariableRecord>(&DR)) { // Process metadata used by DbgRecords; we only specifically care about the // DILocalVariable, DILocation, and DIAssignID fields, as the Value and // Expression fields should only be printed inline and so do not use a slot. // Note: The above doesn't apply for empty-metadata operands. - if (auto *Empty = dyn_cast<MDNode>(DPV->getRawLocation())) + if (auto *Empty = dyn_cast<MDNode>(DVR->getRawLocation())) CreateMetadataSlot(Empty); - CreateMetadataSlot(DPV->getRawVariable()); - if (DPV->isDbgAssign()) { - CreateMetadataSlot(cast<MDNode>(DPV->getRawAssignID())); - if (auto *Empty = dyn_cast<MDNode>(DPV->getRawAddress())) + CreateMetadataSlot(DVR->getRawVariable()); + if (DVR->isDbgAssign()) { + CreateMetadataSlot(cast<MDNode>(DVR->getRawAssignID())); + if (auto *Empty = dyn_cast<MDNode>(DVR->getRawAddress())) CreateMetadataSlot(Empty); } } else if (const DPLabel *DPL = dyn_cast<const DPLabel>(&DR)) { @@ -2719,10 +2719,10 @@ public: void printInstructionLine(const Instruction &I); void printInstruction(const Instruction &I); void printDPMarker(const DPMarker &DPI); - void printDPValue(const DPValue &DPI); + void printDbgVariableRecord(const DbgVariableRecord &DVR); void printDPLabel(const DPLabel &DPL); - void printDbgRecord(const DbgRecord &DPI); - void printDbgRecordLine(const DbgRecord &DPI); + void printDbgRecord(const DbgRecord &DR); + void printDbgRecordLine(const DbgRecord &DR); void printUseListOrder(const Value *V, const std::vector<unsigned> &Shuffle); void printUseLists(const Function *F); @@ -4620,46 +4620,47 @@ void AssemblyWriter::printDPMarker(const DPMarker &Marker) { } void AssemblyWriter::printDbgRecord(const DbgRecord &DR) { - if (auto *DPV = dyn_cast<DPValue>(&DR)) - printDPValue(*DPV); + if (auto *DVR = dyn_cast<DbgVariableRecord>(&DR)) + printDbgVariableRecord(*DVR); else if (auto *DPL = dyn_cast<DPLabel>(&DR)) printDPLabel(*DPL); else llvm_unreachable("Unexpected DbgRecord kind"); } -void AssemblyWriter::printDPValue(const DPValue &DPV) { +void AssemblyWriter::printDbgVariableRecord(const DbgVariableRecord &DVR) { auto WriterCtx = getContext(); Out << "#dbg_"; - switch (DPV.getType()) { - case DPValue::LocationType::Value: + switch (DVR.getType()) { + case DbgVariableRecord::LocationType::Value: Out << "value"; break; - case DPValue::LocationType::Declare: + case DbgVariableRecord::LocationType::Declare: Out << "declare"; break; - case DPValue::LocationType::Assign: + case DbgVariableRecord::LocationType::Assign: Out << "assign"; break; default: - llvm_unreachable("Tried to print a DPValue with an invalid LocationType!"); + llvm_unreachable( + "Tried to print a DbgVariableRecord with an invalid LocationType!"); } Out << "("; - WriteAsOperandInternal(Out, DPV.getRawLocation(), WriterCtx, true); + WriteAsOperandInternal(Out, DVR.getRawLocation(), WriterCtx, true); Out << ", "; - WriteAsOperandInternal(Out, DPV.getRawVariable(), WriterCtx, true); + WriteAsOperandInternal(Out, DVR.getRawVariable(), WriterCtx, true); Out << ", "; - WriteAsOperandInternal(Out, DPV.getRawExpression(), WriterCtx, true); + WriteAsOperandInternal(Out, DVR.getRawExpression(), WriterCtx, true); Out << ", "; - if (DPV.isDbgAssign()) { - WriteAsOperandInternal(Out, DPV.getRawAssignID(), WriterCtx, true); + if (DVR.isDbgAssign()) { + WriteAsOperandInternal(Out, DVR.getRawAssignID(), WriterCtx, true); Out << ", "; - WriteAsOperandInternal(Out, DPV.getRawAddress(), WriterCtx, true); + WriteAsOperandInternal(Out, DVR.getRawAddress(), WriterCtx, true); Out << ", "; - WriteAsOperandInternal(Out, DPV.getRawAddressExpression(), WriterCtx, true); + WriteAsOperandInternal(Out, DVR.getRawAddressExpression(), WriterCtx, true); Out << ", "; } - WriteAsOperandInternal(Out, DPV.getDebugLoc().getAsMDNode(), WriterCtx, true); + WriteAsOperandInternal(Out, DVR.getDebugLoc().getAsMDNode(), WriterCtx, true); Out << ")"; } @@ -4913,7 +4914,7 @@ void DPMarker::print(raw_ostream &ROS, bool IsForDebug) const { print(ROS, MST, IsForDebug); } -void DPValue::print(raw_ostream &ROS, bool IsForDebug) const { +void DbgVariableRecord::print(raw_ostream &ROS, bool IsForDebug) const { ModuleSlotTracker MST(getModuleFromDPI(this), true); print(ROS, MST, IsForDebug); @@ -4940,8 +4941,8 @@ void DPLabel::print(raw_ostream &ROS, bool IsForDebug) const { print(ROS, MST, IsForDebug); } -void DPValue::print(raw_ostream &ROS, ModuleSlotTracker &MST, - bool IsForDebug) const { +void DbgVariableRecord::print(raw_ostream &ROS, ModuleSlotTracker &MST, + bool IsForDebug) const { formatted_raw_ostream OS(ROS); SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr)); SlotTracker &SlotTable = @@ -4954,7 +4955,7 @@ void DPValue::print(raw_ostream &ROS, ModuleSlotTracker &MST, ? Marker->getParent()->getParent() : nullptr); AssemblyWriter W(OS, SlotTable, getModuleFromDPI(this), nullptr, IsForDebug); - W.printDPValue(*this); + W.printDbgVariableRecord(*this); } void DPLabel::print(raw_ostream &ROS, ModuleSlotTracker &MST, diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index c28a291c449c..7d954f9d09ad 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -1067,7 +1067,7 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } } // Update llvm.dbg.addr intrinsics even in "new debug mode"; they'll get - // converted to DPValues later. + // converted to DbgVariableRecords later. if (Name == "addr" || (Name == "value" && F->arg_size() == 4)) { rename(F); NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_value); @@ -2360,23 +2360,23 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) { if (Name == "label") { DR = new DPLabel(unwrapMAVOp<DILabel>(CI, 0), CI->getDebugLoc()); } else if (Name == "assign") { - DR = new DPValue( + DR = new DbgVariableRecord( unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, 1), unwrapMAVOp<DIExpression>(CI, 2), unwrapMAVOp<DIAssignID>(CI, 3), unwrapMAVOp<Metadata>(CI, 4), unwrapMAVOp<DIExpression>(CI, 5), CI->getDebugLoc()); } else if (Name == "declare") { - DR = new DPValue(unwrapMAVOp<Metadata>(CI, 0), - unwrapMAVOp<DILocalVariable>(CI, 1), - unwrapMAVOp<DIExpression>(CI, 2), CI->getDebugLoc(), - DPValue::LocationType::Declare); + DR = new DbgVariableRecord( + unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, 1), + unwrapMAVOp<DIExpression>(CI, 2), CI->getDebugLoc(), + DbgVariableRecord::LocationType::Declare); } else if (Name == "addr") { // Upgrade dbg.addr to dbg.value with DW_OP_deref. DIExpression *Expr = unwrapMAVOp<DIExpression>(CI, 2); Expr = DIExpression::append(Expr, dwarf::DW_OP_deref); - DR = new DPValue(unwrapMAVOp<Metadata>(CI, 0), - unwrapMAVOp<DILocalVariable>(CI, 1), Expr, - CI->getDebugLoc()); + DR = new DbgVariableRecord(unwrapMAVOp<Metadata>(CI, 0), + unwrapMAVOp<DILocalVariable>(CI, 1), Expr, + CI->getDebugLoc()); } else if (Name == "value") { // An old version of dbg.value had an extra offset argument. unsigned VarOp = 1; @@ -2389,9 +2389,9 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) { VarOp = 2; ExprOp = 3; } - DR = new DPValue(unwrapMAVOp<Metadata>(CI, 0), - unwrapMAVOp<DILocalVariable>(CI, VarOp), - unwrapMAVOp<DIExpression>(CI, ExprOp), CI->getDebugLoc()); + DR = new DbgVariableRecord( + unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, VarOp), + unwrapMAVOp<DIExpression>(CI, ExprOp), CI->getDebugLoc()); } assert(DR && "Unhandled intrinsic kind in upgrade to DbgRecord"); CI->getParent()->insertDbgRecordBefore(DR, CI->getIterator()); diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp index 5f0780847938..2dff6e4d6d9c 100644 --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -71,34 +71,34 @@ void BasicBlock::convertToNewDbgValues() { // Iterate over all instructions in the instruction list, collecting debug // info intrinsics and converting them to DbgRecords. Once we find a "real" // instruction, attach all those DbgRecords to a DPMarker in that instruction. - SmallVector<DbgRecord *, 4> DPVals; + SmallVector<DbgRecord *, 4> DbgVarRecs; for (Instruction &I : make_early_inc_range(InstList)) { assert(!I.DbgMarker && "DbgMarker already set on old-format instrs?"); if (DbgVariableIntrinsic *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) { - // Convert this dbg.value to a DPValue. - DPValue *Value = new DPValue(DVI); - DPVals.push_back(Value); + // Convert this dbg.value to a DbgVariableRecord. + DbgVariableRecord *Value = new DbgVariableRecord(DVI); + DbgVarRecs.push_back(Value); DVI->eraseFromParent(); continue; } if (DbgLabelInst *DLI = dyn_cast<DbgLabelInst>(&I)) { - DPVals.push_back(new DPLabel(DLI->getLabel(), DLI->getDebugLoc())); + DbgVarRecs.push_back(new DPLabel(DLI->getLabel(), DLI->getDebugLoc())); DLI->eraseFromParent(); continue; } - if (DPVals.empty()) + if (DbgVarRecs.empty()) continue; // Create a marker to store DbgRecords in. createMarker(&I); DPMarker *Marker = I.DbgMarker; - for (DbgRecord *DPV : DPVals) - Marker->insertDbgRecord(DPV, false); + for (DbgRecord *DVR : DbgVarRecs) + Marker->insertDbgRecord(DVR, false); - DPVals.clear(); + DbgVarRecs.clear(); } } @@ -1034,21 +1034,21 @@ void BasicBlock::splice(iterator Dest, BasicBlock *Src, iterator First, flushTerminatorDbgRecords(); } -void BasicBlock::insertDbgRecordAfter(DbgRecord *DPV, Instruction *I) { +void BasicBlock::insertDbgRecordAfter(DbgRecord *DR, Instruction *I) { assert(IsNewDbgInfoFormat); assert(I->getParent() == this); iterator NextIt = std::next(I->getIterator()); DPMarker *NextMarker = createMarker(NextIt); - NextMarker->insertDbgRecord(DPV, true); + NextMarker->insertDbgRecord(DR, true); } -void BasicBlock::insertDbgRecordBefore(DbgRecord *DPV, +void BasicBlock::insertDbgRecordBefore(DbgRecord *DR, InstListType::iterator Where) { assert(Where == end() || Where->getParent() == this); bool InsertAtHead = Where.getHeadBit(); DPMarker *M = createMarker(Where); - M->insertDbgRecord(DPV, InsertAtHead); + M->insertDbgRecord(DR, InsertAtHead); } DPMarker *BasicBlock::getNextMarker(Instruction *I) { diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index f484680bd6c9..f10b5acb980d 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -967,14 +967,14 @@ DbgInstPtr DIBuilder::insertDbgAssign(Instruction *LinkedInstr, Value *Val, assert(Link && "Linked instruction must have DIAssign metadata attached"); if (M.IsNewDbgInfoFormat) { - DPValue *DPV = DPValue::createDPVAssign(Val, SrcVar, ValExpr, Link, Addr, - AddrExpr, DL); + DbgVariableRecord *DVR = DbgVariableRecord::createDVRAssign( + Val, SrcVar, ValExpr, Link, Addr, AddrExpr, DL); BasicBlock *InsertBB = LinkedInstr->getParent(); // Insert after LinkedInstr. BasicBlock::iterator NextIt = std::next(LinkedInstr->getIterator()); Instruction *InsertBefore = NextIt == InsertBB->end() ? nullptr : &*NextIt; - insertDPValue(DPV, InsertBB, InsertBefore, true); - return DPV; + insertDbgVariableRecord(DVR, InsertBB, InsertBefore, true); + return DVR; } LLVMContext &Ctx = LinkedInstr->getContext(); @@ -1056,9 +1056,10 @@ DbgInstPtr DIBuilder::insertDbgValueIntrinsic( llvm::Value *Val, DILocalVariable *VarInfo, DIExpression *Expr, const DILocation *DL, BasicBlock *InsertBB, Instruction *InsertBefore) { if (M.IsNewDbgInfoFormat) { - DPValue *DPV = DPValue::createDPValue(Val, VarInfo, Expr, DL); - insertDPValue(DPV, InsertBB, InsertBefore); - return DPV; + DbgVariableRecord *DVR = + DbgVariableRecord::createDbgVariableRecord(Val, VarInfo, Expr, DL); + insertDbgVariableRecord(DVR, InsertBB, InsertBefore); + return DVR; } if (!ValueFn) @@ -1078,9 +1079,10 @@ DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo, "Expected matching subprograms"); if (M.IsNewDbgInfoFormat) { - DPValue *DPV = DPValue::createDPVDeclare(Storage, VarInfo, Expr, DL); - insertDPValue(DPV, InsertBB, InsertBefore); - return DPV; + DbgVariableRecord *DVR = + DbgVariableRecord::createDVRDeclare(Storage, VarInfo, Expr, DL); + insertDbgVariableRecord(DVR, InsertBB, InsertBefore); + return DVR; } if (!DeclareFn) @@ -1097,13 +1099,15 @@ DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo, return B.CreateCall(DeclareFn, Args); } -void DIBuilder::insertDPValue(DPValue *DPV, BasicBlock *InsertBB, - Instruction *InsertBefore, bool InsertAtHead) { +void DIBuilder::insertDbgVariableRecord(DbgVariableRecord *DVR, + BasicBlock *InsertBB, + Instruction *InsertBefore, + bool InsertAtHead) { assert(InsertBefore || InsertBB); - trackIfUnresolved(DPV->getVariable()); - trackIfUnresolved(DPV->getExpression()); - if (DPV->isDbgAssign()) - trackIfUnresolved(DPV->getAddressExpression()); + trackIfUnresolved(DVR->getVariable()); + trackIfUnresolved(DVR->getExpression()); + if (DVR->isDbgAssign()) + trackIfUnresolved(DVR->getAddressExpression()); BasicBlock::iterator InsertPt; if (InsertBB && InsertBefore) @@ -1111,7 +1115,7 @@ void DIBuilder::insertDPValue(DPValue *DPV, BasicBlock *InsertBB, else if (InsertBB) InsertPt = InsertBB->end(); InsertPt.setHeadBit(InsertAtHead); - InsertBB->insertDbgRecordBefore(DPV, InsertPt); + InsertBB->insertDbgRecordBefore(DVR, InsertPt); } Instruction *DIBuilder::insertDbgIntrinsic(llvm::Function *IntrinsicFn, diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 173696146299..09bce9df1f33 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -63,7 +63,7 @@ TinyPtrVector<DbgDeclareInst *> llvm::findDbgDeclares(Value *V) { return Declares; } -TinyPtrVector<DPValue *> llvm::findDPVDeclares(Value *V) { +TinyPtrVector<DbgVariableRecord *> llvm::findDVRDeclares(Value *V) { // This function is hot. Check whether the value has any metadata to avoid a // DenseMap lookup. if (!V->isUsedByMetadata()) @@ -72,18 +72,19 @@ TinyPtrVector<DPValue *> llvm::findDPVDeclares(Value *V) { if (!L) return {}; - TinyPtrVector<DPValue *> Declares; - for (DPValue *DPV : L->getAllDPValueUsers()) - if (DPV->getType() == DPValue::LocationType::Declare) - Declares.push_back(DPV); + TinyPtrVector<DbgVariableRecord *> Declares; + for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers()) + if (DVR->getType() == DbgVariableRecord::LocationType::Declare) + Declares.push_back(DVR); return Declares; } -template <typename IntrinsicT, - DPValue::LocationType Type = DPValue::LocationType::Any> -static void findDbgIntrinsics(SmallVectorImpl<IntrinsicT *> &Result, Value *V, - SmallVectorImpl<DPValue *> *DPValues) { +template <typename IntrinsicT, DbgVariableRecord::LocationType Type = + DbgVariableRecord::LocationType::Any> +static void +findDbgIntrinsics(SmallVectorImpl<IntrinsicT *> &Result, Value *V, + SmallVectorImpl<DbgVariableRecord *> *DbgVariableRecords) { // This function is hot. Check whether the value has any metadata to avoid a // DenseMap lookup. if (!V->isUsedByMetadata()) @@ -96,25 +97,27 @@ static void findDbgIntrinsics(SmallVectorImpl<IntrinsicT *> &Result, Value *V, // V will also appear twice in a dbg.assign if its used in the both the value // and address components. SmallPtrSet<IntrinsicT *, 4> EncounteredIntrinsics; - SmallPtrSet<DPValue *, 4> EncounteredDPValues; + SmallPtrSet<DbgVariableRecord *, 4> EncounteredDbgVariableRecords; /// Append IntrinsicT users of MetadataAsValue(MD). - auto AppendUsers = [&Ctx, &EncounteredIntrinsics, &EncounteredDPValues, - &Result, DPValues](Metadata *MD) { + auto AppendUsers = [&Ctx, &EncounteredIntrinsics, + &EncounteredDbgVariableRecords, &Result, + DbgVariableRecords](Metadata *MD) { if (auto *MDV = MetadataAsValue::getIfExists(Ctx, MD)) { for (User *U : MDV->users()) if (IntrinsicT *DVI = dyn_cast<IntrinsicT>(U)) if (EncounteredIntrinsics.insert(DVI).second) Result.push_back(DVI); } - if (!DPValues) + if (!DbgVariableRecords) return; - // Get DPValues that use this as a single value. + // Get DbgVariableRecords that use this as a single value. if (LocalAsMetadata *L = dyn_cast<LocalAsMetadata>(MD)) { - for (DPValue *DPV : L->getAllDPValueUsers()) { - if (Type == DPValue::LocationType::Any || DPV->getType() == Type) - if (EncounteredDPValues.insert(DPV).second) - DPValues->push_back(DPV); + for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers()) { + if (Type == DbgVariableRecord::LocationType::Any || + DVR->getType() == Type) + if (EncounteredDbgVariableRecords.insert(DVR).second) + DbgVariableRecords->push_back(DVR); } } }; @@ -123,27 +126,30 @@ static void findDbgIntrinsics(SmallVectorImpl<IntrinsicT *> &Result, Value *V, AppendUsers(L); for (Metadata *AL : L->getAllArgListUsers()) { AppendUsers(AL); - if (!DPValues) + if (!DbgVariableRecords) continue; DIArgList *DI = cast<DIArgList>(AL); - for (DPValue *DPV : DI->getAllDPValueUsers()) - if (Type == DPValue::LocationType::Any || DPV->getType() == Type) - if (EncounteredDPValues.insert(DPV).second) - DPValues->push_back(DPV); + for (DbgVariableRecord *DVR : DI->getAllDbgVariableRecordUsers()) + if (Type == DbgVariableRecord::LocationType::Any || + DVR->getType() == Type) + if (EncounteredDbgVariableRecords.insert(DVR).second) + DbgVariableRecords->push_back(DVR); } } } -void llvm::findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, - Value *V, SmallVectorImpl<DPValue *> *DPValues) { - findDbgIntrinsics<DbgValueInst, DPValue::LocationType::Value>(DbgValues, V, - DPValues); +void llvm::findDbgValues( + SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V, + SmallVectorImpl<DbgVariableRecord *> *DbgVariableRecords) { + findDbgIntrinsics<DbgValueInst, DbgVariableRecord::LocationType::Value>( + DbgValues, V, DbgVariableRecords); } -void llvm::findDbgUsers(SmallVectorImpl<DbgVariableIntrinsic *> &DbgUsers, - Value *V, SmallVectorImpl<DPValue *> *DPValues) { - findDbgIntrinsics<DbgVariableIntrinsic, DPValue::LocationType::Any>( - DbgUsers, V, DPValues); +void llvm::findDbgUsers( + SmallVectorImpl<DbgVariableIntrinsic *> &DbgUsers, Value *V, + SmallVectorImpl<DbgVariableRecord *> *DbgVariableRecords) { + findDbgIntrinsics<DbgVariableIntrinsic, DbgVariableRecord::LocationType::Any>( + DbgUsers, V, DbgVariableRecords); } DISubprogram *llvm::getDISubprogram(const MDNode *Scope) { @@ -164,16 +170,16 @@ DebugLoc llvm::getDebugValueLoc(DbgVariableIntrinsic *DII) { return DILocation::get(DII->getContext(), 0, 0, Scope, InlinedAt); } -DebugLoc llvm::getDebugValueLoc(DPValue *DPV) { +DebugLoc llvm::getDebugValueLoc(DbgVariableRecord *DVR) { // Original dbg.declare must have a location. - const DebugLoc &DeclareLoc = DPV->getDebugLoc(); + const DebugLoc &DeclareLoc = DVR->getDebugLoc(); MDNode *Scope = DeclareLoc.getScope(); DILocation *InlinedAt = DeclareLoc.getInlinedAt(); // Because no machine insts can come from debug intrinsics, only the scope // and inlinedAt is significant. Zero line numbers are used in case this // DebugLoc leaks into any adjacent instructions. Produce an unknown location // with the correct scope / inlinedAt fields. - return DILocation::get(DPV->getContext(), 0, 0, Scope, InlinedAt); + return DILocation::get(DVR->getContext(), 0, 0, Scope, InlinedAt); } //===----------------------------------------------------------------------===// @@ -253,8 +259,8 @@ void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) { } void DebugInfoFinder::processDbgRecord(const Module &M, const DbgRecord &DR) { - if (const DPValue *DPV = dyn_cast<const DPValue>(&DR)) - processVariable(M, DPV->getVariable()); + if (const DbgVariableRecord *DVR = dyn_cast<const DbgVariableRecord>(&DR)) + processVariable(M, DVR->getVariable()); processLocation(M, DR.getDebugLoc().get()); } @@ -1864,14 +1870,14 @@ AssignmentMarkerRange at::getAssignmentMarkers(DIAssignID *ID) { void at::deleteAssignmentMarkers(const Instruction *Inst) { auto Range = getAssignmentMarkers(Inst); - SmallVector<DPValue *> DPVAssigns = getDPVAssignmentMarkers(Inst); - if (Range.empty() && DPVAssigns.empty()) + SmallVector<DbgVariableRecord *> DVRAssigns = getDVRAssignmentMarkers(Inst); + if (Range.empty() && DVRAssigns.empty()) return; SmallVector<DbgAssignIntrinsic *> ToDelete(Range.begin(), Range.end()); for (auto *DAI : ToDelete) DAI->eraseFromParent(); - for (auto *DPV : DPVAssigns) - DPV->eraseFromParent(); + for (auto *DVR : DVRAssigns) + DVR->eraseFromParent(); } void at::RAUW(DIAssignID *Old, DIAssignID *New) { @@ -1889,12 +1895,12 @@ void at::RAUW(DIAssignID *Old, DIAssignID *New) { void at::deleteAll(Function *F) { SmallVector<DbgAssignIntrinsic *, 12> ToDelete; - SmallVector<DPValue *, 12> DPToDelete; + SmallVector<DbgVariableRecord *, 12> DPToDelete; for (BasicBlock &BB : *F) { for (Instruction &I : BB) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) - if (DPV.isDbgAssign()) - DPToDelete.push_back(&DPV); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) + if (DVR.isDbgAssign()) + DPToDelete.push_back(&DVR); if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(&I)) ToDelete.push_back(DAI); else @@ -1903,20 +1909,20 @@ void at::deleteAll(Function *F) { } for (auto *DAI : ToDelete) DAI->eraseFromParent(); - for (auto *DPV : DPToDelete) - DPV->eraseFromParent(); + for (auto *DVR : DPToDelete) + DVR->eraseFromParent(); } /// Get the FragmentInfo for the variable if it exists, otherwise return a /// FragmentInfo that covers the entire variable if the variable size is /// known, otherwise return a zero-sized fragment. static DIExpression::FragmentInfo -getFragmentOrEntireVariable(const DPValue *DPV) { +getFragmentOrEntireVariable(const DbgVariableRecord *DVR) { DIExpression::FragmentInfo VariableSlice(0, 0); // Get the fragment or variable size, or zero. - if (auto Sz = DPV->getFragmentSizeInBits()) + if (auto Sz = DVR->getFragmentSizeInBits()) VariableSlice.SizeInBits = *Sz; - if (auto Frag = DPV->getExpression()->getFragmentInfo()) + if (auto Frag = DVR->getExpression()->getFragmentInfo()) VariableSlice.OffsetInBits = Frag->OffsetInBits; return VariableSlice; } @@ -2080,10 +2086,10 @@ bool at::calculateFragmentIntersect( } bool at::calculateFragmentIntersect( const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits, - uint64_t SliceSizeInBits, const DPValue *DPVAssign, + uint64_t SliceSizeInBits, const DbgVariableRecord *DVRAssign, std::optional<DIExpression::FragmentInfo> &Result) { return calculateFragmentIntersectImpl(DL, Dest, SliceOffsetInBits, - SliceSizeInBits, DPVAssign, Result); + SliceSizeInBits, DVRAssign, Result); } /// Collect constant properies (base, size, offset) of \p StoreDest. @@ -2177,7 +2183,7 @@ static void emitDbgAssign(AssignmentInfo Info, Value *Val, Value *Dest, DIExpression *AddrExpr = DIExpression::get(StoreLikeInst.getContext(), std::nullopt); if (StoreLikeInst.getParent()->IsNewDbgInfoFormat) { - auto *Assign = DPValue::createLinkedDPVAssign( + auto *Assign = DbgVariableRecord::createLinkedDVRAssign( &StoreLikeInst, Val, VarRec.Var, Expr, Dest, AddrExpr, VarRec.DL); (void)Assign; LLVM_DEBUG(if (Assign) errs() << " > INSERT: " << *Assign << "\n"); @@ -2295,7 +2301,7 @@ bool AssignmentTrackingPass::runOnFunction(Function &F) { // storage" is limited to Allocas). We'll use this to find dbg.declares to // delete after running `trackAssignments`. DenseMap<const AllocaInst *, SmallPtrSet<DbgDeclareInst *, 2>> DbgDeclares; - DenseMap<const AllocaInst *, SmallPtrSet<DPValue *, 2>> DPVDeclares; + DenseMap<const AllocaInst *, SmallPtrSet<DbgVariableRecord *, 2>> DVRDeclares; // Create another similar map of {storage : variables} that we'll pass to // trackAssignments. StorageToVarsMap Vars; @@ -2321,9 +2327,9 @@ bool AssignmentTrackingPass::runOnFunction(Function &F) { }; for (auto &BB : F) { for (auto &I : BB) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - if (DPV.isDbgDeclare()) - ProcessDeclare(&DPV, DPVDeclares); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + if (DVR.isDbgDeclare()) + ProcessDeclare(&DVR, DVRDeclares); } if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(&I)) ProcessDeclare(DDI, DbgDeclares); @@ -2364,8 +2370,8 @@ bool AssignmentTrackingPass::runOnFunction(Function &F) { }; for (auto &P : DbgDeclares) DeleteSubsumedDeclare(at::getAssignmentMarkers(P.first), P.second); - for (auto &P : DPVDeclares) - DeleteSubsumedDeclare(at::getDPVAssignmentMarkers(P.first), P.second); + for (auto &P : DVRDeclares) + DeleteSubsumedDeclare(at::getDVRAssignmentMarkers(P.first), P.second); return Changed; } diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 6e9cc51afcc1..570515505607 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -46,10 +46,10 @@ DebugVariable::DebugVariable(const DbgVariableIntrinsic *DII) Fragment(DII->getExpression()->getFragmentInfo()), InlinedAt(DII->getDebugLoc().getInlinedAt()) {} -DebugVariable::DebugVariable(const DPValue *DPV) - : Variable(DPV->getVariable()), - Fragment(DPV->getExpression()->getFragmentInfo()), - InlinedAt(DPV->getDebugLoc().getInlinedAt()) {} +DebugVariable::DebugVariable(const DbgVariableRecord *DVR) + : Variable(DVR->getVariable()), + Fragment(DVR->getExpression()->getFragmentInfo()), + InlinedAt(DVR->getDebugLoc().getInlinedAt()) {} DebugVariableAggregate::DebugVariableAggregate(const DbgVariableIntrinsic *DVI) : DebugVariable(DVI->getVariable(), std::nullopt, diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp index f34d3aecfa0a..1fb435f46a5f 100644 --- a/llvm/lib/IR/DebugProgramInstruction.cpp +++ b/llvm/lib/IR/DebugProgramInstruction.cpp @@ -28,7 +28,7 @@ template class DbgRecordParamRef<DIExpression>; template class DbgRecordParamRef<DILabel>; template class DbgRecordParamRef<DILocalVariable>; -DPValue::DPValue(const DbgVariableIntrinsic *DVI) +DbgVariableRecord::DbgVariableRecord(const DbgVariableIntrinsic *DVI) : DbgRecord(ValueKind, DVI->getDebugLoc()), DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}), Variable(DVI->getVariable()), Expression(DVI->getExpression()), @@ -51,25 +51,27 @@ DPValue::DPValue(const DbgVariableIntrinsic *DVI) } default: llvm_unreachable( - "Trying to create a DPValue with an invalid intrinsic type!"); + "Trying to create a DbgVariableRecord with an invalid intrinsic type!"); } } -DPValue::DPValue(const DPValue &DPV) - : DbgRecord(ValueKind, DPV.getDebugLoc()), DebugValueUser(DPV.DebugValues), - Type(DPV.getType()), Variable(DPV.getVariable()), - Expression(DPV.getExpression()), - AddressExpression(DPV.AddressExpression) {} +DbgVariableRecord::DbgVariableRecord(const DbgVariableRecord &DVR) + : DbgRecord(ValueKind, DVR.getDebugLoc()), DebugValueUser(DVR.DebugValues), + Type(DVR.getType()), Variable(DVR.getVariable()), + Expression(DVR.getExpression()), + AddressExpression(DVR.AddressExpression) {} -DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr, - const DILocation *DI, LocationType Type) +DbgVariableRecord::DbgVariableRecord(Metadata *Location, DILocalVariable *DV, + DIExpression *Expr, const DILocation *DI, + LocationType Type) : DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}), Type(Type), Variable(DV), Expression(Expr) {} -DPValue::DPValue(Metadata *Value, DILocalVariable *Variable, - DIExpression *Expression, DIAssignID *AssignID, - Metadata *Address, DIExpression *AddressExpression, - const DILocation *DI) +DbgVariableRecord::DbgVariableRecord(Metadata *Value, DILocalVariable *Variable, + DIExpression *Expression, + DIAssignID *AssignID, Metadata *Address, + DIExpression *AddressExpression, + const DILocation *DI) : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}), Type(LocationType::Assign), Variable(Variable), Expression(Expression), AddressExpression(AddressExpression) {} @@ -77,7 +79,7 @@ DPValue::DPValue(Metadata *Value, DILocalVariable *Variable, void DbgRecord::deleteRecord() { switch (RecordKind) { case ValueKind: - delete cast<DPValue>(this); + delete cast<DbgVariableRecord>(this); return; case LabelKind: delete cast<DPLabel>(this); @@ -89,7 +91,7 @@ void DbgRecord::deleteRecord() { void DbgRecord::print(raw_ostream &O, bool IsForDebug) const { switch (RecordKind) { case ValueKind: - cast<DPValue>(this)->print(O, IsForDebug); + cast<DbgVariableRecord>(this)->print(O, IsForDebug); return; case LabelKind: cast<DPLabel>(this)->print(O, IsForDebug); @@ -102,7 +104,7 @@ void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST, bool IsForDebug) const { switch (RecordKind) { case ValueKind: - cast<DPValue>(this)->print(O, MST, IsForDebug); + cast<DbgVariableRecord>(this)->print(O, MST, IsForDebug); return; case LabelKind: cast<DPLabel>(this)->print(O, MST, IsForDebug); @@ -116,7 +118,8 @@ bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const { return false; switch (RecordKind) { case ValueKind: - return cast<DPValue>(this)->isIdenticalToWhenDefined(*cast<DPValue>(&R)); + return cast<DbgVariableRecord>(this)->isIdenticalToWhenDefined( + *cast<DbgVariableRecord>(&R)); case LabelKind: return cast<DPLabel>(this)->getLabel() == cast<DPLabel>(R).getLabel(); }; @@ -131,7 +134,7 @@ DbgInfoIntrinsic * DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const { switch (RecordKind) { case ValueKind: - return cast<DPValue>(this)->createDebugIntrinsic(M, InsertBefore); + return cast<DbgVariableRecord>(this)->createDebugIntrinsic(M, InsertBefore); case LabelKind: return cast<DPLabel>(this)->createDebugIntrinsic(M, InsertBefore); }; @@ -153,79 +156,83 @@ DPLabel *DPLabel::createUnresolvedDPLabel(MDNode *Label, MDNode *DL) { return new DPLabel(Label, DL); } -DPValue::DPValue(DPValue::LocationType Type, Metadata *Val, MDNode *Variable, - MDNode *Expression, MDNode *AssignID, Metadata *Address, - MDNode *AddressExpression, MDNode *DI) +DbgVariableRecord::DbgVariableRecord(DbgVariableRecord::LocationType Type, + Metadata *Val, MDNode *Variable, + MDNode *Expression, MDNode *AssignID, + Metadata *Address, + MDNode *AddressExpression, MDNode *DI) : DbgRecord(ValueKind, DebugLoc(DI)), DebugValueUser({Val, Address, AssignID}), Type(Type), Variable(Variable), Expression(Expression), AddressExpression(AddressExpression) {} -DPValue *DPValue::createUnresolvedDPValue(DPValue::LocationType Type, - Metadata *Val, MDNode *Variable, - MDNode *Expression, MDNode *AssignID, - Metadata *Address, - MDNode *AddressExpression, - MDNode *DI) { - return new DPValue(Type, Val, Variable, Expression, AssignID, Address, - AddressExpression, DI); +DbgVariableRecord *DbgVariableRecord::createUnresolvedDbgVariableRecord( + DbgVariableRecord::LocationType Type, Metadata *Val, MDNode *Variable, + MDNode *Expression, MDNode *AssignID, Metadata *Address, + MDNode *AddressExpression, MDNode *DI) { + return new DbgVariableRecord(Type, Val, Variable, Expression, AssignID, + Address, AddressExpression, DI); } -DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV, - DIExpression *Expr, const DILocation *DI) { - return new DPValue(ValueAsMetadata::get(Location), DV, Expr, DI, - LocationType::Value); +DbgVariableRecord * +DbgVariableRecord::createDbgVariableRecord(Value *Location, DILocalVariable *DV, + DIExpression *Expr, + const DILocation *DI) { + return new DbgVariableRecord(ValueAsMetadata::get(Location), DV, Expr, DI, + LocationType::Value); } -DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV, - DIExpression *Expr, const DILocation *DI, - DPValue &InsertBefore) { - auto *NewDPValue = createDPValue(Location, DV, Expr, DI); - NewDPValue->insertBefore(&InsertBefore); - return NewDPValue; +DbgVariableRecord *DbgVariableRecord::createDbgVariableRecord( + Value *Location, DILocalVariable *DV, DIExpression *Expr, + const DILocation *DI, DbgVariableRecord &InsertBefore) { + auto *NewDbgVariableRecord = createDbgVariableRecord(Location, DV, Expr, DI); + NewDbgVariableRecord->insertBefore(&InsertBefore); + return NewDbgVariableRecord; } -DPValue *DPValue::createDPVDeclare(Value *Address, DILocalVariable *DV, - DIExpression *Expr, const DILocation *DI) { - return new DPValue(ValueAsMetadata::get(Address), DV, Expr, DI, - LocationType::Declare); +DbgVariableRecord *DbgVariableRecord::createDVRDeclare(Value *Address, + DILocalVariable *DV, + DIExpression *Expr, + const DILocation *DI) { + return new DbgVariableRecord(ValueAsMetadata::get(Address), DV, Expr, DI, + LocationType::Declare); } -DPValue *DPValue::createDPVDeclare(Value *Address, DILocalVariable *DV, - DIExpression *Expr, const DILocation *DI, - DPValue &InsertBefore) { - auto *NewDPVDeclare = createDPVDeclare(Address, DV, Expr, DI); - NewDPVDeclare->insertBefore(&InsertBefore); - return NewDPVDeclare; +DbgVariableRecord * +DbgVariableRecord::createDVRDeclare(Value *Address, DILocalVariable *DV, + DIExpression *Expr, const DILocation *DI, + DbgVariableRecord &InsertBefore) { + auto *NewDVRDeclare = createDVRDeclare(Address, DV, Expr, DI); + NewDVRDeclare->insertBefore(&InsertBefore); + return NewDVRDeclare; } -DPValue *DPValue::createDPVAssign(Value *Val, DILocalVariable *Variable, - DIExpression *Expression, - DIAssignID *AssignID, Value *Address, - DIExpression *AddressExpression, - const DILocation *DI) { - return new DPValue(ValueAsMetadata::get(Val), Variable, Expression, AssignID, - ValueAsMetadata::get(Address), AddressExpression, DI); +DbgVariableRecord *DbgVariableRecord::createDVRAssign( + Value *Val, DILocalVariable *Variable, DIExpression *Expression, + DIAssignID *AssignID, Value *Address, DIExpression *AddressExpression, + const DILocation *DI) { + return new DbgVariableRecord(ValueAsMetadata::get(Val), Variable, Expression, + AssignID, ValueAsMetadata::get(Address), + AddressExpression, DI); } -DPValue *DPValue::createLinkedDPVAssign(Instruction *LinkedInstr, Value *Val, - DILocalVariable *Variable, - DIExpression *Expression, - Value *Address, - DIExpression *AddressExpression, - const DILocation *DI) { +DbgVariableRecord *DbgVariableRecord::createLinkedDVRAssign( + Instruction *LinkedInstr, Value *Val, DILocalVariable *Variable, + DIExpression *Expression, Value *Address, DIExpression *AddressExpression, + const DILocation *DI) { auto *Link = LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID); assert(Link && "Linked instruction must have DIAssign metadata attached"); - auto *NewDPVAssign = DPValue::createDPVAssign(Val, Variable, Expression, - cast<DIAssignID>(Link), Address, - AddressExpression, DI); - LinkedInstr->getParent()->insertDbgRecordAfter(NewDPVAssign, LinkedInstr); - return NewDPVAssign; + auto *NewDVRAssign = DbgVariableRecord::createDVRAssign( + Val, Variable, Expression, cast<DIAssignID>(Link), Address, + AddressExpression, DI); + LinkedInstr->getParent()->insertDbgRecordAfter(NewDVRAssign, LinkedInstr); + return NewDVRAssign; } -iterator_range<DPValue::location_op_iterator> DPValue::location_ops() const { +iterator_range<DbgVariableRecord::location_op_iterator> +DbgVariableRecord::location_ops() const { auto *MD = getRawLocation(); - // If a Value has been deleted, the "location" for this DPValue will be - // replaced by nullptr. Return an empty range. + // If a Value has been deleted, the "location" for this DbgVariableRecord will + // be replaced by nullptr. Return an empty range. if (!MD) return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)), location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))}; @@ -245,13 +252,13 @@ iterator_range<DPValue::location_op_iterator> DPValue::location_ops() const { location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))}; } -unsigned DPValue::getNumVariableLocationOps() const { +unsigned DbgVariableRecord::getNumVariableLocationOps() const { if (hasArgList()) return cast<DIArgList>(getRawLocation())->getArgs().size(); return 1; } -Value *DPValue::getVariableLocationOp(unsigned OpIdx) const { +Value *DbgVariableRecord::getVariableLocationOp(unsigned OpIdx) const { auto *MD = getRawLocation(); if (!MD) return nullptr; @@ -261,7 +268,7 @@ Value *DPValue::getVariableLocationOp(unsigned OpIdx) const { if (isa<MDNode>(MD)) return nullptr; assert(isa<ValueAsMetadata>(MD) && - "Attempted to get location operand from DPValue with none."); + "Attempted to get location operand from DbgVariableRecord with none."); auto *V = cast<ValueAsMetadata>(MD); assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a " "single location operand."); @@ -274,8 +281,9 @@ static ValueAsMetadata *getAsMetadata(Value *V) { : ValueAsMetadata::get(V); } -void DPValue::replaceVariableLocationOp(Value *OldValue, Value *NewValue, - bool AllowEmpty) { +void DbgVariableRecord::replaceVariableLocationOp(Value *OldValue, + Value *NewValue, + bool AllowEmpty) { assert(NewValue && "Values must be non-null"); bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress(); @@ -307,7 +315,8 @@ void DPValue::replaceVariableLocationOp(Value *OldValue, Value *NewValue, setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs)); } -void DPValue::replaceVariableLocationOp(unsigned OpIdx, Value *NewValue) { +void DbgVariableRecord::replaceVariableLocationOp(unsigned OpIdx, + Value *NewValue) { assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index"); if (!hasArgList()) { @@ -326,8 +335,8 @@ void DPValue::replaceVariableLocationOp(unsigned OpIdx, Value *NewValue) { setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs)); } -void DPValue::addVariableLocationOps(ArrayRef<Value *> NewValues, - DIExpression *NewExpr) { +void DbgVariableRecord::addVariableLocationOps(ArrayRef<Value *> NewValues, + DIExpression *NewExpr) { assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() + NewValues.size()) && "NewExpr for debug variable intrinsic does not reference every " @@ -342,7 +351,7 @@ void DPValue::addVariableLocationOps(ArrayRef<Value *> NewValues, setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs)); } -void DPValue::setKillLocation() { +void DbgVariableRecord::setKillLocation() { // TODO: When/if we remove duplicate values from DIArgLists, we don't need // this set anymore. SmallPtrSet<Value *, 4> RemovedValues; @@ -354,13 +363,13 @@ void DPValue::setKillLocation() { } } -bool DPValue::isKillLocation() const { +bool DbgVariableRecord::isKillLocation() const { return (getNumVariableLocationOps() == 0 && !getExpression()->isComplex()) || any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); }); } -std::optional<uint64_t> DPValue::getFragmentSizeInBits() const { +std::optional<uint64_t> DbgVariableRecord::getFragmentSizeInBits() const { if (auto Fragment = getExpression()->getFragmentInfo()) return Fragment->SizeInBits; return getVariable()->getSizeInBits(); @@ -369,21 +378,24 @@ std::optional<uint64_t> DPValue::getFragmentSizeInBits() const { DbgRecord *DbgRecord::clone() const { switch (RecordKind) { case ValueKind: - return cast<DPValue>(this)->clone(); + return cast<DbgVariableRecord>(this)->clone(); case LabelKind: return cast<DPLabel>(this)->clone(); }; llvm_unreachable("unsupported DbgRecord kind"); } -DPValue *DPValue::clone() const { return new DPValue(*this); } +DbgVariableRecord *DbgVariableRecord::clone() const { + return new DbgVariableRecord(*this); +} DPLabel *DPLabel::clone() const { return new DPLabel(getLabel(), getDebugLoc()); } DbgVariableIntrinsic * -DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const { +DbgVariableRecord::createDebugIntrinsic(Module *M, + Instruction *InsertBefore) const { [[maybe_unused]] DICompileUnit *Unit = getDebugLoc().get()->getScope()->getSubprogram()->getUnit(); assert(M && Unit && @@ -394,24 +406,25 @@ DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const { // Work out what sort of intrinsic we're going to produce. switch (getType()) { - case DPValue::LocationType::Declare: + case DbgVariableRecord::LocationType::Declare: IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare); break; - case DPValue::LocationType::Value: + case DbgVariableRecord::LocationType::Value: IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value); break; - case DPValue::LocationType::Assign: + case DbgVariableRecord::LocationType::Assign: IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign); break; - case DPValue::LocationType::End: - case DPValue::LocationType::Any: + case DbgVariableRecord::LocationType::End: + case DbgVariableRecord::LocationType::Any: llvm_unreachable("Invalid LocationType"); } - // Create the intrinsic from this DPValue's information, optionally insert - // into the target location. + // Create the intrinsic from this DbgVariableRecord's information, optionally + // insert into the target location. DbgVariableIntrinsic *DVI; - assert(getRawLocation() && "DPValue's RawLocation should be non-null."); + assert(getRawLocation() && + "DbgVariableRecord's RawLocation should be non-null."); if (isDbgAssign()) { Value *AssignArgs[] = { MetadataAsValue::get(Context, getRawLocation()), @@ -451,7 +464,7 @@ DbgLabelInst *DPLabel::createDebugIntrinsic(Module *M, return DbgLabel; } -Value *DPValue::getAddress() const { +Value *DbgVariableRecord::getAddress() const { auto *MD = getRawAddress(); if (auto *V = dyn_cast<ValueAsMetadata>(MD)) return V->getValue(); @@ -461,18 +474,20 @@ Value *DPValue::getAddress() const { return nullptr; } -DIAssignID *DPValue::getAssignID() const { +DIAssignID *DbgVariableRecord::getAssignID() const { return cast<DIAssignID>(DebugValues[2]); } -void DPValue::setAssignId(DIAssignID *New) { resetDebugValue(2, New); } +void DbgVariableRecord::setAssignId(DIAssignID *New) { + resetDebugValue(2, New); +} -void DPValue::setKillAddress() { +void DbgVariableRecord::setKillAddress() { resetDebugValue( 1, ValueAsMetadata::get(UndefValue::get(getAddress()->getType()))); } -bool DPValue::isKillAddress() const { +bool DbgVariableRecord::isKillAddress() const { Value *Addr = getAddress(); return !Addr || isa<UndefValue>(Addr); } @@ -647,8 +662,8 @@ void DPMarker::insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter) { void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) { auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end(); - for (DbgRecord &DPV : Src.StoredDbgRecords) - DPV.setMarker(this); + for (DbgRecord &DVR : Src.StoredDbgRecords) + DVR.setMarker(this); StoredDbgRecords.splice(It, Src.StoredDbgRecords); } @@ -677,8 +692,8 @@ iterator_range<simple_ilist<DbgRecord>::iterator> DPMarker::cloneDebugInfoFrom( if (from_here.has_value()) Range = make_range(*from_here, From->StoredDbgRecords.end()); - // Clone each DPValue and insert into StoreDPValues; optionally place them at - // the start or the end of the list. + // Clone each DbgVariableRecord and insert into StoreDbgVariableRecords; + // optionally place them at the start or the end of the list. auto Pos = (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end(); for (DbgRecord &DR : Range) { DbgRecord *New = DR.clone(); diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 7a677d7f3c2b..9744eb32d27a 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -143,8 +143,8 @@ void Instruction::insertBefore(BasicBlock &BB, return; // We've inserted "this": if InsertAtHead is set then it comes before any - // DPValues attached to InsertPos. But if it's not set, then any DbgRecords - // should now come before "this". + // DbgVariableRecords attached to InsertPos. But if it's not set, then any + // DbgRecords should now come before "this". bool InsertAtHead = InsertPos.getHeadBit(); if (!InsertAtHead) { DPMarker *SrcMarker = BB.getMarker(InsertPos); @@ -217,7 +217,7 @@ void Instruction::moveBeforeImpl(BasicBlock &BB, InstListType::iterator I, if (BB.IsNewDbgInfoFormat && DbgMarker && !Preserve) { if (I != this->getIterator() || InsertAtHead) { // "this" is definitely moving in the list, or it's moving ahead of its - // attached DPValues. Detach any existing DbgRecords. + // attached DbgVariableRecords. Detach any existing DbgRecords. handleMarkerRemoval(); } } @@ -320,8 +320,8 @@ void Instruction::dropDbgRecords() { DbgMarker->dropDbgRecords(); } -void Instruction::dropOneDbgRecord(DbgRecord *DPV) { - DbgMarker->dropOneDbgRecord(DPV); +void Instruction::dropOneDbgRecord(DbgRecord *DVR) { + DbgMarker->dropOneDbgRecord(DVR); } bool Instruction::comesBefore(const Instruction *Other) const { diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp index a471314ccb94..72fedd8d6739 100644 --- a/llvm/lib/IR/LLVMContextImpl.cpp +++ b/llvm/lib/IR/LLVMContextImpl.cpp @@ -48,8 +48,8 @@ LLVMContextImpl::~LLVMContextImpl() { #ifndef NDEBUG // Check that any variable location records that fell off the end of a block // when it's terminator was removed were eventually replaced. This assertion - // firing indicates that DPValues went missing during the lifetime of the - // LLVMContext. + // firing indicates that DbgVariableRecords went missing during the lifetime + // of the LLVMContext. assert(TrailingDbgRecords.empty() && "DbgRecords in blocks not cleaned"); #endif diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 00af694e553f..4542e16e59fd 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -1675,20 +1675,20 @@ public: /// LLVMContext is used by compilation. void setOptPassGate(OptPassGate &); - /// Mapping of blocks to collections of "trailing" DPValues. As part of the - /// "RemoveDIs" project, debug-info variable location records are going to - /// cease being instructions... which raises the problem of where should they - /// be recorded when we remove the terminator of a blocks, such as: + /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part + /// of the "RemoveDIs" project, debug-info variable location records are going + /// to cease being instructions... which raises the problem of where should + /// they be recorded when we remove the terminator of a blocks, such as: /// /// %foo = add i32 0, 0 /// br label %bar /// /// If the branch is removed, a legitimate transient state while editing a /// block, any debug-records between those two instructions will not have a - /// location. Each block thus records any DPValue records that "trail" in - /// such a way. These are stored in LLVMContext because typically LLVM only - /// edits a small number of blocks at a time, so there's no need to bloat - /// BasicBlock with such a data structure. + /// location. Each block thus records any DbgVariableRecord records that + /// "trail" in such a way. These are stored in LLVMContext because typically + /// LLVM only edits a small number of blocks at a time, so there's no need to + /// bloat BasicBlock with such a data structure. SmallDenseMap<BasicBlock *, DPMarker *> TrailingDbgRecords; // Set, get and delete operations for TrailingDbgRecords. diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp index 8945c6dbc8d8..953f21ce7405 100644 --- a/llvm/lib/IR/LegacyPassManager.cpp +++ b/llvm/lib/IR/LegacyPassManager.cpp @@ -528,8 +528,9 @@ bool PassManagerImpl::run(Module &M) { dumpArguments(); dumpPasses(); - // RemoveDIs: if a command line flag is given, convert to the DPValue - // representation of debug-info for the duration of these passes. + // RemoveDIs: if a command line flag is given, convert to the + // DbgVariableRecord representation of debug-info for the duration of these + // passes. bool shouldConvertDbgInfo = UseNewDbgInfoFormat && !M.IsNewDbgInfoFormat; if (shouldConvertDbgInfo) M.convertToNewDbgValues(); diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index 06db91fe4f8e..4472bf128c32 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -148,9 +148,11 @@ void MetadataAsValue::untrack() { MetadataTracking::untrack(MD); } -DPValue *DebugValueUser::getUser() { return static_cast<DPValue *>(this); } -const DPValue *DebugValueUser::getUser() const { - return static_cast<const DPValue *>(this); +DbgVariableRecord *DebugValueUser::getUser() { + return static_cast<DbgVariableRecord *>(this); +} +const DbgVariableRecord *DebugValueUser::getUser() const { + return static_cast<const DbgVariableRecord *>(this); } void DebugValueUser::handleChangedValue(void *Old, Metadata *New) { @@ -266,28 +268,29 @@ SmallVector<Metadata *> ReplaceableMetadataImpl::getAllArgListUsers() { return MDUsers; } -SmallVector<DPValue *> ReplaceableMetadataImpl::getAllDPValueUsers() { - SmallVector<std::pair<OwnerTy, uint64_t> *> DPVUsersWithID; +SmallVector<DbgVariableRecord *> +ReplaceableMetadataImpl::getAllDbgVariableRecordUsers() { + SmallVector<std::pair<OwnerTy, uint64_t> *> DVRUsersWithID; for (auto Pair : UseMap) { OwnerTy Owner = Pair.second.first; if (Owner.isNull()) continue; if (!Owner.is<DebugValueUser *>()) continue; - DPVUsersWithID.push_back(&UseMap[Pair.first]); + DVRUsersWithID.push_back(&UseMap[Pair.first]); } - // Order DPValue users in reverse-creation order. Normal dbg.value users - // of MetadataAsValues are ordered by their UseList, i.e. reverse order of - // when they were added: we need to replicate that here. The structure of + // Order DbgVariableRecord users in reverse-creation order. Normal dbg.value + // users of MetadataAsValues are ordered by their UseList, i.e. reverse order + // of when they were added: we need to replicate that here. The structure of // debug-info output depends on the ordering of intrinsics, thus we need // to keep them consistent for comparisons sake. - llvm::sort(DPVUsersWithID, [](auto UserA, auto UserB) { + llvm::sort(DVRUsersWithID, [](auto UserA, auto UserB) { return UserA->second > UserB->second; }); - SmallVector<DPValue *> DPVUsers; - for (auto UserWithID : DPVUsersWithID) - DPVUsers.push_back(UserWithID->first.get<DebugValueUser *>()->getUser()); - return DPVUsers; + SmallVector<DbgVariableRecord *> DVRUsers; + for (auto UserWithID : DVRUsersWithID) + DVRUsers.push_back(UserWithID->first.get<DebugValueUser *>()->getUser()); + return DVRUsers; } void ReplaceableMetadataImpl::addRef(void *Ref, OwnerTy Owner) { diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index c4e47975b182..61e1c35ba4a3 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -574,16 +574,16 @@ void Value::replaceUsesWithIf(Value *New, /// with New. static void replaceDbgUsesOutsideBlock(Value *V, Value *New, BasicBlock *BB) { SmallVector<DbgVariableIntrinsic *> DbgUsers; - SmallVector<DPValue *> DPUsers; + SmallVector<DbgVariableRecord *> DPUsers; findDbgUsers(DbgUsers, V, &DPUsers); for (auto *DVI : DbgUsers) { if (DVI->getParent() != BB) DVI->replaceVariableLocationOp(V, New); } - for (auto *DPV : DPUsers) { - DPMarker *Marker = DPV->getMarker(); + for (auto *DVR : DPUsers) { + DPMarker *Marker = DVR->getMarker(); if (Marker->getParent() != BB) - DPV->replaceVariableLocationOp(V, New); + DVR->replaceVariableLocationOp(V, New); } } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index a923f5e2a34e..1e16e8648462 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -180,21 +180,21 @@ private: } } - void Write(DPValue::LocationType Type) { + void Write(DbgVariableRecord::LocationType Type) { switch (Type) { - case DPValue::LocationType::Value: + case DbgVariableRecord::LocationType::Value: *OS << "value"; break; - case DPValue::LocationType::Declare: + case DbgVariableRecord::LocationType::Declare: *OS << "declare"; break; - case DPValue::LocationType::Assign: + case DbgVariableRecord::LocationType::Assign: *OS << "assign"; break; - case DPValue::LocationType::End: + case DbgVariableRecord::LocationType::End: *OS << "end"; break; - case DPValue::LocationType::Any: + case DbgVariableRecord::LocationType::Any: *OS << "any"; break; }; @@ -545,7 +545,7 @@ private: void visitTemplateParams(const MDNode &N, const Metadata &RawParams); void visit(DPLabel &DPL); - void visit(DPValue &DPV); + void visit(DbgVariableRecord &DVR); // InstVisitor overrides... using InstVisitor<Verifier>::visit; void visitDbgRecords(Instruction &I); @@ -632,15 +632,15 @@ private: void verifySiblingFuncletUnwinds(); void verifyFragmentExpression(const DbgVariableIntrinsic &I); - void verifyFragmentExpression(const DPValue &I); + void verifyFragmentExpression(const DbgVariableRecord &I); template <typename ValueOrMetadata> void verifyFragmentExpression(const DIVariable &V, DIExpression::FragmentInfo Fragment, ValueOrMetadata *Desc); void verifyFnArgs(const DbgVariableIntrinsic &I); - void verifyFnArgs(const DPValue &DPV); + void verifyFnArgs(const DbgVariableRecord &DVR); void verifyNotEntryValue(const DbgVariableIntrinsic &I); - void verifyNotEntryValue(const DPValue &I); + void verifyNotEntryValue(const DbgVariableRecord &I); /// Module-level debug info verification... void verifyCompileUnits(); @@ -690,12 +690,12 @@ void Verifier::visitDbgRecords(Instruction &I) { if (auto *Loc = dyn_cast_or_null<DILocation>(DR.getDebugLoc().getAsMDNode())) visitMDNode(*Loc, AreDebugLocsAllowed::Yes); - if (auto *DPV = dyn_cast<DPValue>(&DR)) { - visit(*DPV); + if (auto *DVR = dyn_cast<DbgVariableRecord>(&DR)) { + visit(*DVR); // These have to appear after `visit` for consistency with existing // intrinsic behaviour. - verifyFragmentExpression(*DPV); - verifyNotEntryValue(*DPV); + verifyFragmentExpression(*DVR); + verifyNotEntryValue(*DVR); } else if (auto *DPL = dyn_cast<DPLabel>(&DR)) { visit(*DPL); } @@ -4808,11 +4808,12 @@ void Verifier::visitDIAssignIDMetadata(Instruction &I, MDNode *MD) { "dbg.assign not in same function as inst", DAI, &I); } } - for (DPValue *DPV : cast<DIAssignID>(MD)->getAllDPValueUsers()) { - CheckDI(DPV->isDbgAssign(), - "!DIAssignID should only be used by Assign DPVs.", MD, DPV); - CheckDI(DPV->getFunction() == I.getFunction(), - "DPVAssign not in same function as inst", DPV, &I); + for (DbgVariableRecord *DVR : + cast<DIAssignID>(MD)->getAllDbgVariableRecordUsers()) { + CheckDI(DVR->isDbgAssign(), + "!DIAssignID should only be used by Assign DVRs.", MD, DVR); + CheckDI(DVR->getFunction() == I.getFunction(), + "DVRAssign not in same function as inst", DVR, &I); } } @@ -6271,71 +6272,72 @@ void Verifier::visit(DPLabel &DPL) { Loc->getScope()->getSubprogram()); } -void Verifier::visit(DPValue &DPV) { - BasicBlock *BB = DPV.getParent(); +void Verifier::visit(DbgVariableRecord &DVR) { + BasicBlock *BB = DVR.getParent(); Function *F = BB->getParent(); - CheckDI(DPV.getType() == DPValue::LocationType::Value || - DPV.getType() == DPValue::LocationType::Declare || - DPV.getType() == DPValue::LocationType::Assign, - "invalid #dbg record type", &DPV, DPV.getType()); + CheckDI(DVR.getType() == DbgVariableRecord::LocationType::Value || + DVR.getType() == DbgVariableRecord::LocationType::Declare || + DVR.getType() == DbgVariableRecord::LocationType::Assign, + "invalid #dbg record type", &DVR, DVR.getType()); - // The location for a DPValue must be either a ValueAsMetadata, DIArgList, or - // an empty MDNode (which is a legacy representation for an "undef" location). - auto *MD = DPV.getRawLocation(); + // The location for a DbgVariableRecord must be either a ValueAsMetadata, + // DIArgList, or an empty MDNode (which is a legacy representation for an + // "undef" location). + auto *MD = DVR.getRawLocation(); CheckDI(MD && (isa<ValueAsMetadata>(MD) || isa<DIArgList>(MD) || (isa<MDNode>(MD) && !cast<MDNode>(MD)->getNumOperands())), - "invalid #dbg record address/value", &DPV, MD); + "invalid #dbg record address/value", &DVR, MD); if (auto *VAM = dyn_cast<ValueAsMetadata>(MD)) visitValueAsMetadata(*VAM, F); else if (auto *AL = dyn_cast<DIArgList>(MD)) visitDIArgList(*AL, F); - CheckDI(isa_and_nonnull<DILocalVariable>(DPV.getRawVariable()), - "invalid #dbg record variable", &DPV, DPV.getRawVariable()); - visitMDNode(*DPV.getRawVariable(), AreDebugLocsAllowed::No); + CheckDI(isa_and_nonnull<DILocalVariable>(DVR.getRawVariable()), + "invalid #dbg record variable", &DVR, DVR.getRawVariable()); + visitMDNode(*DVR.getRawVariable(), AreDebugLocsAllowed::No); - CheckDI(isa_and_nonnull<DIExpression>(DPV.getRawExpression()), - "invalid #dbg record expression", &DPV, DPV.getRawExpression()); - visitMDNode(*DPV.getExpression(), AreDebugLocsAllowed::No); + CheckDI(isa_and_nonnull<DIExpression>(DVR.getRawExpression()), + "invalid #dbg record expression", &DVR, DVR.getRawExpression()); + visitMDNode(*DVR.getExpression(), AreDebugLocsAllowed::No); - if (DPV.isDbgAssign()) { - CheckDI(isa_and_nonnull<DIAssignID>(DPV.getRawAssignID()), - "invalid #dbg_assign DIAssignID", &DPV, DPV.getRawAssignID()); - visitMDNode(*cast<DIAssignID>(DPV.getRawAssignID()), + if (DVR.isDbgAssign()) { + CheckDI(isa_and_nonnull<DIAssignID>(DVR.getRawAssignID()), + "invalid #dbg_assign DIAssignID", &DVR, DVR.getRawAssignID()); + visitMDNode(*cast<DIAssignID>(DVR.getRawAssignID()), AreDebugLocsAllowed::No); - const auto *RawAddr = DPV.getRawAddress(); - // Similarly to the location above, the address for an assign DPValue must - // be a ValueAsMetadata or an empty MDNode, which represents an undef - // address. + const auto *RawAddr = DVR.getRawAddress(); + // Similarly to the location above, the address for an assign + // DbgVariableRecord must be a ValueAsMetadata or an empty MDNode, which + // represents an undef address. CheckDI( isa<ValueAsMetadata>(RawAddr) || (isa<MDNode>(RawAddr) && !cast<MDNode>(RawAddr)->getNumOperands()), - "invalid #dbg_assign address", &DPV, DPV.getRawAddress()); + "invalid #dbg_assign address", &DVR, DVR.getRawAddress()); if (auto *VAM = dyn_cast<ValueAsMetadata>(RawAddr)) visitValueAsMetadata(*VAM, F); - CheckDI(isa_and_nonnull<DIExpression>(DPV.getRawAddressExpression()), - "invalid #dbg_assign address expression", &DPV, - DPV.getRawAddressExpression()); - visitMDNode(*DPV.getAddressExpression(), AreDebugLocsAllowed::No); + CheckDI(isa_and_nonnull<DIExpression>(DVR.getRawAddressExpression()), + "invalid #dbg_assign address expression", &DVR, + DVR.getRawAddressExpression()); + visitMDNode(*DVR.getAddressExpression(), AreDebugLocsAllowed::No); - // All of the linked instructions should be in the same function as DPV. - for (Instruction *I : at::getAssignmentInsts(&DPV)) - CheckDI(DPV.getFunction() == I->getFunction(), - "inst not in same function as #dbg_assign", I, &DPV); + // All of the linked instructions should be in the same function as DVR. + for (Instruction *I : at::getAssignmentInsts(&DVR)) + CheckDI(DVR.getFunction() == I->getFunction(), + "inst not in same function as #dbg_assign", I, &DVR); } // This check is redundant with one in visitLocalVariable(). - DILocalVariable *Var = DPV.getVariable(); + DILocalVariable *Var = DVR.getVariable(); CheckDI(isType(Var->getRawType()), "invalid type ref", Var, Var->getRawType()); - auto *DLNode = DPV.getDebugLoc().getAsMDNode(); + auto *DLNode = DVR.getDebugLoc().getAsMDNode(); CheckDI(isa_and_nonnull<DILocation>(DLNode), "invalid #dbg record DILocation", - &DPV, DLNode); - DILocation *Loc = DPV.getDebugLoc(); + &DVR, DLNode); + DILocation *Loc = DVR.getDebugLoc(); // The scopes for variables and !dbg attachments must agree. DISubprogram *VarSP = getSubprogram(Var->getRawScope()); @@ -6345,10 +6347,10 @@ void Verifier::visit(DPValue &DPV) { CheckDI(VarSP == LocSP, "mismatched subprogram between #dbg record variable and DILocation", - &DPV, BB, F, Var, Var->getScope()->getSubprogram(), Loc, + &DVR, BB, F, Var, Var->getScope()->getSubprogram(), Loc, Loc->getScope()->getSubprogram()); - verifyFnArgs(DPV); + verifyFnArgs(DVR); } void Verifier::visitVPIntrinsic(VPIntrinsic &VPI) { @@ -6709,9 +6711,9 @@ void Verifier::verifyFragmentExpression(const DbgVariableIntrinsic &I) { verifyFragmentExpression(*V, *Fragment, &I); } -void Verifier::verifyFragmentExpression(const DPValue &DPV) { - DILocalVariable *V = dyn_cast_or_null<DILocalVariable>(DPV.getRawVariable()); - DIExpression *E = dyn_cast_or_null<DIExpression>(DPV.getRawExpression()); +void Verifier::verifyFragmentExpression(const DbgVariableRecord &DVR) { + DILocalVariable *V = dyn_cast_or_null<DILocalVariable>(DVR.getRawVariable()); + DIExpression *E = dyn_cast_or_null<DIExpression>(DVR.getRawExpression()); // We don't know whether this intrinsic verified correctly. if (!V || !E || !E->isValid()) @@ -6731,7 +6733,7 @@ void Verifier::verifyFragmentExpression(const DPValue &DPV) { if (V->isArtificial()) return; - verifyFragmentExpression(*V, *Fragment, &DPV); + verifyFragmentExpression(*V, *Fragment, &DVR); } template <typename ValueOrMetadata> @@ -6779,7 +6781,7 @@ void Verifier::verifyFnArgs(const DbgVariableIntrinsic &I) { CheckDI(!Prev || (Prev == Var), "conflicting debug info for argument", &I, Prev, Var); } -void Verifier::verifyFnArgs(const DPValue &DPV) { +void Verifier::verifyFnArgs(const DbgVariableRecord &DVR) { // This function does not take the scope of noninlined function arguments into // account. Don't run it if current function is nodebug, because it may // contain inlined debug intrinsics. @@ -6787,10 +6789,10 @@ void Verifier::verifyFnArgs(const DPValue &DPV) { return; // For performance reasons only check non-inlined ones. - if (DPV.getDebugLoc()->getInlinedAt()) + if (DVR.getDebugLoc()->getInlinedAt()) return; - DILocalVariable *Var = DPV.getVariable(); + DILocalVariable *Var = DVR.getVariable(); CheckDI(Var, "#dbg record without variable"); unsigned ArgNo = Var->getArg(); @@ -6804,7 +6806,7 @@ void Verifier::verifyFnArgs(const DPValue &DPV) { auto *Prev = DebugFnArgs[ArgNo - 1]; DebugFnArgs[ArgNo - 1] = Var; - CheckDI(!Prev || (Prev == Var), "conflicting debug info for argument", &DPV, + CheckDI(!Prev || (Prev == Var), "conflicting debug info for argument", &DVR, Prev, Var); } @@ -6831,15 +6833,15 @@ void Verifier::verifyNotEntryValue(const DbgVariableIntrinsic &I) { "swiftasync Argument", &I); } -void Verifier::verifyNotEntryValue(const DPValue &DPV) { - DIExpression *E = dyn_cast_or_null<DIExpression>(DPV.getRawExpression()); +void Verifier::verifyNotEntryValue(const DbgVariableRecord &DVR) { + DIExpression *E = dyn_cast_or_null<DIExpression>(DVR.getRawExpression()); // We don't know whether this intrinsic verified correctly. if (!E || !E->isValid()) return; - if (isa<ValueAsMetadata>(DPV.getRawLocation())) { - Value *VarValue = DPV.getVariableLocationOp(0); + if (isa<ValueAsMetadata>(DVR.getRawLocation())) { + Value *VarValue = DVR.getVariableLocationOp(0); if (isa<UndefValue>(VarValue) || isa<PoisonValue>(VarValue)) return; // We allow EntryValues for swift async arguments, as they have an @@ -6852,7 +6854,7 @@ void Verifier::verifyNotEntryValue(const DPValue &DPV) { CheckDI(!E->isEntryValue(), "Entry values are only allowed in MIR unless they target a " "swiftasync Argument", - &DPV); + &DVR); } void Verifier::verifyCompileUnits() { diff --git a/llvm/lib/Target/AArch64/AArch64StackTagging.cpp b/llvm/lib/Target/AArch64/AArch64StackTagging.cpp index f2812d2b49bc..aabc5d5d22e2 100644 --- a/llvm/lib/Target/AArch64/AArch64StackTagging.cpp +++ b/llvm/lib/Target/AArch64/AArch64StackTagging.cpp @@ -532,7 +532,7 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) { ConstantInt::get(IRB.getInt64Ty(), Tag)}); if (Info.AI->hasName()) TagPCall->setName(Info.AI->getName() + ".tag"); - // Does not replace metadata, so we don't have to handle DPValues. + // Does not replace metadata, so we don't have to handle DbgVariableRecords. Info.AI->replaceUsesWithIf(TagPCall, [&](const Use &U) { return !memtag::isLifetimeIntrinsic(U.getUser()); }); diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index ae2a06a1d474..08a4522e3fac 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -971,7 +971,7 @@ static void cacheDIVar(FrameDataInfo &FrameData, DIVarCache.insert({V, (*I)->getVariable()}); }; CacheIt(findDbgDeclares(V)); - CacheIt(findDPVDeclares(V)); + CacheIt(findDVRDeclares(V)); } } @@ -1123,7 +1123,7 @@ static void buildFrameDebugInfo(Function &F, coro::Shape &Shape, "Coroutine with switch ABI should own Promise alloca"); TinyPtrVector<DbgDeclareInst *> DIs = findDbgDeclares(PromiseAlloca); - TinyPtrVector<DPValue *> DPVs = findDPVDeclares(PromiseAlloca); + TinyPtrVector<DbgVariableRecord *> DVRs = findDVRDeclares(PromiseAlloca); DILocalVariable *PromiseDIVariable = nullptr; DILocation *DILoc = nullptr; @@ -1131,10 +1131,10 @@ static void buildFrameDebugInfo(Function &F, coro::Shape &Shape, DbgDeclareInst *PromiseDDI = DIs.front(); PromiseDIVariable = PromiseDDI->getVariable(); DILoc = PromiseDDI->getDebugLoc().get(); - } else if (!DPVs.empty()) { - DPValue *PromiseDPV = DPVs.front(); - PromiseDIVariable = PromiseDPV->getVariable(); - DILoc = PromiseDPV->getDebugLoc().get(); + } else if (!DVRs.empty()) { + DbgVariableRecord *PromiseDVR = DVRs.front(); + PromiseDIVariable = PromiseDVR->getVariable(); + DILoc = PromiseDVR->getDebugLoc().get(); } else { return; } @@ -1273,11 +1273,12 @@ static void buildFrameDebugInfo(Function &F, coro::Shape &Shape, } if (UseNewDbgInfoFormat) { - DPValue *NewDPV = new DPValue(ValueAsMetadata::get(Shape.FramePtr), - FrameDIVar, DBuilder.createExpression(), - DILoc, DPValue::LocationType::Declare); + DbgVariableRecord *NewDVR = + new DbgVariableRecord(ValueAsMetadata::get(Shape.FramePtr), FrameDIVar, + DBuilder.createExpression(), DILoc, + DbgVariableRecord::LocationType::Declare); BasicBlock::iterator It = Shape.getInsertPtAfterFramePtr(); - It->getParent()->insertDbgRecordBefore(NewDPV, It); + It->getParent()->insertDbgRecordBefore(NewDVR, It); } else { DBuilder.insertDeclare(Shape.FramePtr, FrameDIVar, DBuilder.createExpression(), DILoc, @@ -1862,13 +1863,13 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { SpillAlignment, E.first->getName() + Twine(".reload")); TinyPtrVector<DbgDeclareInst *> DIs = findDbgDeclares(Def); - TinyPtrVector<DPValue *> DPVs = findDPVDeclares(Def); + TinyPtrVector<DbgVariableRecord *> DVRs = findDVRDeclares(Def); // Try best to find dbg.declare. If the spill is a temp, there may not // be a direct dbg.declare. Walk up the load chain to find one from an // alias. if (F->getSubprogram()) { auto *CurDef = Def; - while (DIs.empty() && DPVs.empty() && isa<LoadInst>(CurDef)) { + while (DIs.empty() && DVRs.empty() && isa<LoadInst>(CurDef)) { auto *LdInst = cast<LoadInst>(CurDef); // Only consider ptr to ptr same type load. if (LdInst->getPointerOperandType() != LdInst->getType()) @@ -1877,7 +1878,7 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { if (!isa<AllocaInst, LoadInst>(CurDef)) break; DIs = findDbgDeclares(CurDef); - DPVs = findDPVDeclares(CurDef); + DVRs = findDVRDeclares(CurDef); } } @@ -1887,12 +1888,12 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { // fragments. It will be unreachable in the main function, and // processed by coro::salvageDebugInfo() by CoroCloner. if (UseNewDbgInfoFormat) { - DPValue *NewDPV = - new DPValue(ValueAsMetadata::get(CurrentReload), - DDI->getVariable(), DDI->getExpression(), - DDI->getDebugLoc(), DPValue::LocationType::Declare); + DbgVariableRecord *NewDVR = new DbgVariableRecord( + ValueAsMetadata::get(CurrentReload), DDI->getVariable(), + DDI->getExpression(), DDI->getDebugLoc(), + DbgVariableRecord::LocationType::Declare); Builder.GetInsertPoint()->getParent()->insertDbgRecordBefore( - NewDPV, Builder.GetInsertPoint()); + NewDVR, Builder.GetInsertPoint()); } else { DIBuilder(*CurrentBlock->getParent()->getParent(), AllowUnresolved) .insertDeclare(CurrentReload, DDI->getVariable(), @@ -1905,7 +1906,7 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { false /*UseEntryValue*/); }; for_each(DIs, SalvageOne); - for_each(DPVs, SalvageOne); + for_each(DVRs, SalvageOne); } // If we have a single edge PHINode, remove it and replace it with a @@ -1925,8 +1926,8 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { U->replaceUsesOfWith(Def, CurrentReload); // Instructions are added to Def's user list if the attached // debug records use Def. Update those now. - for (DPValue &DPV : filterDbgVars(U->getDbgRecordRange())) - DPV.replaceVariableLocationOp(Def, CurrentReload, true); + for (DbgVariableRecord &DVR : filterDbgVars(U->getDbgRecordRange())) + DVR.replaceVariableLocationOp(Def, CurrentReload, true); } } @@ -1977,12 +1978,12 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { G->setName(Alloca->getName() + Twine(".reload.addr")); SmallVector<DbgVariableIntrinsic *, 4> DIs; - SmallVector<DPValue *> DPValues; - findDbgUsers(DIs, Alloca, &DPValues); + SmallVector<DbgVariableRecord *> DbgVariableRecords; + findDbgUsers(DIs, Alloca, &DbgVariableRecords); for (auto *DVI : DIs) DVI->replaceUsesOfWith(Alloca, G); - for (auto *DPV : DPValues) - DPV->replaceVariableLocationOp(Alloca, G); + for (auto *DVR : DbgVariableRecords) + DVR->replaceVariableLocationOp(Alloca, G); for (Instruction *I : UsersToUpdate) { // It is meaningless to retain the lifetime intrinsics refer for the @@ -2960,30 +2961,30 @@ void coro::salvageDebugInfo( } void coro::salvageDebugInfo( - SmallDenseMap<Argument *, AllocaInst *, 4> &ArgToAllocaMap, DPValue &DPV, - bool OptimizeFrame, bool UseEntryValue) { + SmallDenseMap<Argument *, AllocaInst *, 4> &ArgToAllocaMap, + DbgVariableRecord &DVR, bool OptimizeFrame, bool UseEntryValue) { - Function *F = DPV.getFunction(); + Function *F = DVR.getFunction(); // Follow the pointer arithmetic all the way to the incoming // function argument and convert into a DIExpression. - bool SkipOutermostLoad = DPV.isDbgDeclare(); - Value *OriginalStorage = DPV.getVariableLocationOp(0); + bool SkipOutermostLoad = DVR.isDbgDeclare(); + Value *OriginalStorage = DVR.getVariableLocationOp(0); auto SalvagedInfo = ::salvageDebugInfoImpl( ArgToAllocaMap, OptimizeFrame, UseEntryValue, F, OriginalStorage, - DPV.getExpression(), SkipOutermostLoad); + DVR.getExpression(), SkipOutermostLoad); if (!SalvagedInfo) return; Value *Storage = &SalvagedInfo->first; DIExpression *Expr = &SalvagedInfo->second; - DPV.replaceVariableLocationOp(OriginalStorage, Storage); - DPV.setExpression(Expr); + DVR.replaceVariableLocationOp(OriginalStorage, Storage); + DVR.setExpression(Expr); // We only hoist dbg.declare today since it doesn't make sense to hoist // dbg.value since it does not have the same function wide guarantees that // dbg.declare does. - if (DPV.getType() == DPValue::LocationType::Declare) { + if (DVR.getType() == DbgVariableRecord::LocationType::Declare) { std::optional<BasicBlock::iterator> InsertPt; if (auto *I = dyn_cast<Instruction>(Storage)) { InsertPt = I->getInsertionPointAfterDef(); @@ -2991,12 +2992,12 @@ void coro::salvageDebugInfo( // optimizations. See https://github.com/llvm/llvm-project/pull/75104 for // an example. if (!OptimizeFrame && I->getDebugLoc()) - DPV.setDebugLoc(I->getDebugLoc()); + DVR.setDebugLoc(I->getDebugLoc()); } else if (isa<Argument>(Storage)) InsertPt = F->getEntryBlock().begin(); if (InsertPt) { - DPV.removeFromParent(); - (*InsertPt)->getParent()->insertDbgRecordBefore(&DPV, *InsertPt); + DVR.removeFromParent(); + (*InsertPt)->getParent()->insertDbgRecordBefore(&DVR, *InsertPt); } } } @@ -3188,15 +3189,15 @@ void coro::buildCoroutineFrame( for (auto &Iter : FrameData.Spills) { auto *V = Iter.first; SmallVector<DbgValueInst *, 16> DVIs; - SmallVector<DPValue *, 16> DPVs; - findDbgValues(DVIs, V, &DPVs); + SmallVector<DbgVariableRecord *, 16> DVRs; + findDbgValues(DVIs, V, &DVRs); for (DbgValueInst *DVI : DVIs) if (Checker.isDefinitionAcrossSuspend(*V, DVI)) FrameData.Spills[V].push_back(DVI); // Add the instructions which carry debug info that is in the frame. - for (DPValue *DPV : DPVs) - if (Checker.isDefinitionAcrossSuspend(*V, DPV->Marker->MarkedInstr)) - FrameData.Spills[V].push_back(DPV->Marker->MarkedInstr); + for (DbgVariableRecord *DVR : DVRs) + if (Checker.isDefinitionAcrossSuspend(*V, DVR->Marker->MarkedInstr)) + FrameData.Spills[V].push_back(DVR->Marker->MarkedInstr); } LLVM_DEBUG(dumpSpills("Spills", FrameData.Spills)); diff --git a/llvm/lib/Transforms/Coroutines/CoroInternal.h b/llvm/lib/Transforms/Coroutines/CoroInternal.h index 09d1430b4c55..84fd88806154 100644 --- a/llvm/lib/Transforms/Coroutines/CoroInternal.h +++ b/llvm/lib/Transforms/Coroutines/CoroInternal.h @@ -35,8 +35,8 @@ void salvageDebugInfo( SmallDenseMap<Argument *, AllocaInst *, 4> &ArgToAllocaMap, DbgVariableIntrinsic &DVI, bool OptimizeFrame, bool IsEntryPoint); void salvageDebugInfo( - SmallDenseMap<Argument *, AllocaInst *, 4> &ArgToAllocaMap, DPValue &DPV, - bool OptimizeFrame, bool UseEntryValue); + SmallDenseMap<Argument *, AllocaInst *, 4> &ArgToAllocaMap, + DbgVariableRecord &DVR, bool OptimizeFrame, bool UseEntryValue); // Keeps data and helper functions for lowering coroutine intrinsics. struct LowererBase { diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp index 0fce596d3e2c..3f3d81474faf 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -679,17 +679,18 @@ static void replaceSwiftErrorOps(Function &F, coro::Shape &Shape, } /// Returns all DbgVariableIntrinsic in F. -static std::pair<SmallVector<DbgVariableIntrinsic *, 8>, SmallVector<DPValue *>> +static std::pair<SmallVector<DbgVariableIntrinsic *, 8>, + SmallVector<DbgVariableRecord *>> collectDbgVariableIntrinsics(Function &F) { SmallVector<DbgVariableIntrinsic *, 8> Intrinsics; - SmallVector<DPValue *> DPValues; + SmallVector<DbgVariableRecord *> DbgVariableRecords; for (auto &I : instructions(F)) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) - DPValues.push_back(&DPV); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) + DbgVariableRecords.push_back(&DVR); if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) Intrinsics.push_back(DVI); } - return {Intrinsics, DPValues}; + return {Intrinsics, DbgVariableRecords}; } void CoroCloner::replaceSwiftErrorOps() { @@ -697,7 +698,7 @@ void CoroCloner::replaceSwiftErrorOps() { } void CoroCloner::salvageDebugInfo() { - auto [Worklist, DPValues] = collectDbgVariableIntrinsics(*NewF); + auto [Worklist, DbgVariableRecords] = collectDbgVariableIntrinsics(*NewF); SmallDenseMap<Argument *, AllocaInst *, 4> ArgToAllocaMap; // Only 64-bit ABIs have a register we can refer to with the entry value. @@ -706,8 +707,8 @@ void CoroCloner::salvageDebugInfo() { for (DbgVariableIntrinsic *DVI : Worklist) coro::salvageDebugInfo(ArgToAllocaMap, *DVI, Shape.OptimizeFrame, UseEntryValue); - for (DPValue *DPV : DPValues) - coro::salvageDebugInfo(ArgToAllocaMap, *DPV, Shape.OptimizeFrame, + for (DbgVariableRecord *DVR : DbgVariableRecords) + coro::salvageDebugInfo(ArgToAllocaMap, *DVR, Shape.OptimizeFrame, UseEntryValue); // Remove all salvaged dbg.declare intrinsics that became @@ -732,7 +733,7 @@ void CoroCloner::salvageDebugInfo() { } }; for_each(Worklist, RemoveOne); - for_each(DPValues, RemoveOne); + for_each(DbgVariableRecords, RemoveOne); } void CoroCloner::replaceEntryBlock() { @@ -2107,12 +2108,12 @@ splitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones, // original function. The Cloner has already salvaged debug info in the new // coroutine funclets. SmallDenseMap<Argument *, AllocaInst *, 4> ArgToAllocaMap; - auto [DbgInsts, DPValues] = collectDbgVariableIntrinsics(F); + auto [DbgInsts, DbgVariableRecords] = collectDbgVariableIntrinsics(F); for (auto *DDI : DbgInsts) coro::salvageDebugInfo(ArgToAllocaMap, *DDI, Shape.OptimizeFrame, false /*UseEntryValue*/); - for (DPValue *DPV : DPValues) - coro::salvageDebugInfo(ArgToAllocaMap, *DPV, Shape.OptimizeFrame, + for (DbgVariableRecord *DVR : DbgVariableRecords) + coro::salvageDebugInfo(ArgToAllocaMap, *DVR, Shape.OptimizeFrame, false /*UseEntryValue*/); return Shape; } diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index 37f4a8749fd8..29f9264f2fc2 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -723,8 +723,8 @@ static void moveFunctionData(Function &Old, Function &New, for (Instruction &Val : CurrBB) { // Since debug-info originates from many different locations in the // program, it will cause incorrect reporting from a debugger if we keep - // the same debug instructions. Drop non-intrinsic DPValues here, - // collect intrinsics for removal later. + // the same debug instructions. Drop non-intrinsic DbgVariableRecords + // here, collect intrinsics for removal later. Val.dropDbgRecords(); // We must handle the scoping of called functions differently than diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp index 4ff14b671af6..05a3b169aaaf 100644 --- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp +++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp @@ -256,20 +256,22 @@ private: /// Fill PDIUnrelatedWL with instructions from the entry block that are /// unrelated to parameter related debug info. - /// \param PDPVUnrelatedWL The equivalent non-intrinsic debug records. - void filterInstsUnrelatedToPDI(BasicBlock *GEntryBlock, - std::vector<Instruction *> &PDIUnrelatedWL, - std::vector<DPValue *> &PDPVUnrelatedWL); + /// \param PDVRUnrelatedWL The equivalent non-intrinsic debug records. + void + filterInstsUnrelatedToPDI(BasicBlock *GEntryBlock, + std::vector<Instruction *> &PDIUnrelatedWL, + std::vector<DbgVariableRecord *> &PDVRUnrelatedWL); /// Erase the rest of the CFG (i.e. barring the entry block). void eraseTail(Function *G); /// Erase the instructions in PDIUnrelatedWL as they are unrelated to the /// parameter debug info, from the entry block. - /// \param PDPVUnrelatedWL contains the equivalent set of non-instruction + /// \param PDVRUnrelatedWL contains the equivalent set of non-instruction /// debug-info records. - void eraseInstsUnrelatedToPDI(std::vector<Instruction *> &PDIUnrelatedWL, - std::vector<DPValue *> &PDPVUnrelatedWL); + void + eraseInstsUnrelatedToPDI(std::vector<Instruction *> &PDIUnrelatedWL, + std::vector<DbgVariableRecord *> &PDVRUnrelatedWL); /// Replace G with a simple tail call to bitcast(F). Also (unless /// MergeFunctionsPDI holds) replace direct uses of G with bitcast(F), @@ -512,7 +514,7 @@ static Value *createCast(IRBuilder<> &Builder, Value *V, Type *DestTy) { // parameter debug info, from the entry block. void MergeFunctions::eraseInstsUnrelatedToPDI( std::vector<Instruction *> &PDIUnrelatedWL, - std::vector<DPValue *> &PDPVUnrelatedWL) { + std::vector<DbgVariableRecord *> &PDVRUnrelatedWL) { LLVM_DEBUG( dbgs() << " Erasing instructions (in reverse order of appearance in " "entry block) unrelated to parameter debug info from entry " @@ -526,13 +528,13 @@ void MergeFunctions::eraseInstsUnrelatedToPDI( PDIUnrelatedWL.pop_back(); } - while (!PDPVUnrelatedWL.empty()) { - DPValue *DPV = PDPVUnrelatedWL.back(); - LLVM_DEBUG(dbgs() << " Deleting DPValue "); - LLVM_DEBUG(DPV->print(dbgs())); + while (!PDVRUnrelatedWL.empty()) { + DbgVariableRecord *DVR = PDVRUnrelatedWL.back(); + LLVM_DEBUG(dbgs() << " Deleting DbgVariableRecord "); + LLVM_DEBUG(DVR->print(dbgs())); LLVM_DEBUG(dbgs() << "\n"); - DPV->eraseFromParent(); - PDPVUnrelatedWL.pop_back(); + DVR->eraseFromParent(); + PDVRUnrelatedWL.pop_back(); } LLVM_DEBUG(dbgs() << " } // Done erasing instructions unrelated to parameter " @@ -564,12 +566,12 @@ void MergeFunctions::eraseTail(Function *G) { // PDIUnrelatedWL with such instructions. void MergeFunctions::filterInstsUnrelatedToPDI( BasicBlock *GEntryBlock, std::vector<Instruction *> &PDIUnrelatedWL, - std::vector<DPValue *> &PDPVUnrelatedWL) { + std::vector<DbgVariableRecord *> &PDVRUnrelatedWL) { std::set<Instruction *> PDIRelated; - std::set<DPValue *> PDPVRelated; + std::set<DbgVariableRecord *> PDVRRelated; - // Work out whether a dbg.value intrinsic or an equivalent DPValue is a - // parameter to be preserved. + // Work out whether a dbg.value intrinsic or an equivalent DbgVariableRecord + // is a parameter to be preserved. auto ExamineDbgValue = [](auto *DbgVal, auto &Container) { LLVM_DEBUG(dbgs() << " Deciding: "); LLVM_DEBUG(DbgVal->print(dbgs())); @@ -641,14 +643,14 @@ void MergeFunctions::filterInstsUnrelatedToPDI( for (BasicBlock::iterator BI = GEntryBlock->begin(), BIE = GEntryBlock->end(); BI != BIE; ++BI) { - // Examine DPValues as they happen "before" the instruction. Are they - // connected to parameters? - for (DPValue &DPV : filterDbgVars(BI->getDbgRecordRange())) { - if (DPV.isDbgValue() || DPV.isDbgAssign()) { - ExamineDbgValue(&DPV, PDPVRelated); + // Examine DbgVariableRecords as they happen "before" the instruction. Are + // they connected to parameters? + for (DbgVariableRecord &DVR : filterDbgVars(BI->getDbgRecordRange())) { + if (DVR.isDbgValue() || DVR.isDbgAssign()) { + ExamineDbgValue(&DVR, PDVRRelated); } else { - assert(DPV.isDbgDeclare()); - ExamineDbgDeclare(&DPV, PDPVRelated); + assert(DVR.isDbgDeclare()); + ExamineDbgDeclare(&DVR, PDVRRelated); } } @@ -686,8 +688,8 @@ void MergeFunctions::filterInstsUnrelatedToPDI( // Collect the set of unrelated instructions and debug records. for (Instruction &I : *GEntryBlock) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) - IsPDIRelated(&DPV, PDPVRelated, PDPVUnrelatedWL); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) + IsPDIRelated(&DVR, PDVRRelated, PDVRUnrelatedWL); IsPDIRelated(&I, PDIRelated, PDIUnrelatedWL); } LLVM_DEBUG(dbgs() << " }\n"); @@ -728,7 +730,7 @@ static void copyMetadataIfPresent(Function *From, Function *To, StringRef Key) { void MergeFunctions::writeThunk(Function *F, Function *G) { BasicBlock *GEntryBlock = nullptr; std::vector<Instruction *> PDIUnrelatedWL; - std::vector<DPValue *> PDPVUnrelatedWL; + std::vector<DbgVariableRecord *> PDVRUnrelatedWL; BasicBlock *BB = nullptr; Function *NewG = nullptr; if (MergeFunctionsPDI) { @@ -740,7 +742,7 @@ void MergeFunctions::writeThunk(Function *F, Function *G) { dbgs() << "writeThunk: (MergeFunctionsPDI) filter parameter related " "debug info for " << G->getName() << "() {\n"); - filterInstsUnrelatedToPDI(GEntryBlock, PDIUnrelatedWL, PDPVUnrelatedWL); + filterInstsUnrelatedToPDI(GEntryBlock, PDIUnrelatedWL, PDVRUnrelatedWL); GEntryBlock->getTerminator()->eraseFromParent(); BB = GEntryBlock; } else { @@ -790,7 +792,7 @@ void MergeFunctions::writeThunk(Function *F, Function *G) { << G->getName() << "()\n"); } eraseTail(G); - eraseInstsUnrelatedToPDI(PDIUnrelatedWL, PDPVUnrelatedWL); + eraseInstsUnrelatedToPDI(PDIUnrelatedWL, PDVRUnrelatedWL); LLVM_DEBUG( dbgs() << "} // End of parameter related debug info filtering for: " << G->getName() << "()\n"); diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp index 6b9a1f6777fc..3986359b6a5a 100644 --- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp +++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp @@ -581,8 +581,8 @@ llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) { FunctionAnalysisManager &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); - // RemoveDIs: there's no bitcode representation of the DPValue debug-info, - // convert to dbg.values before writing out. + // RemoveDIs: there's no bitcode representation of the DbgVariableRecord + // debug-info, convert to dbg.values before writing out. bool ConvertToOldDbgFormatForWrite = M.IsNewDbgInfoFormat && !WriteNewDbgInfoFormatToBitcode; if (ConvertToOldDbgFormatForWrite) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 3eafcb03644e..426b548c074a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -274,7 +274,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) { DbgAssign->replaceVariableLocationOp(FillC, FillVal); }; for_each(at::getAssignmentMarkers(S), replaceOpForAssignmentMarkers); - for_each(at::getDPVAssignmentMarkers(S), replaceOpForAssignmentMarkers); + for_each(at::getDVRAssignmentMarkers(S), replaceOpForAssignmentMarkers); S->setAlignment(Alignment); if (isa<AtomicMemSetInst>(MI)) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h index e2b744ba66f2..b9ad3a740079 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -758,10 +758,9 @@ public: void tryToSinkInstructionDbgValues( Instruction *I, BasicBlock::iterator InsertPos, BasicBlock *SrcBlock, BasicBlock *DestBlock, SmallVectorImpl<DbgVariableIntrinsic *> &DbgUsers); - void tryToSinkInstructionDPValues(Instruction *I, - BasicBlock::iterator InsertPos, - BasicBlock *SrcBlock, BasicBlock *DestBlock, - SmallVectorImpl<DPValue *> &DPUsers); + void tryToSinkInstructionDbgVariableRecords( + Instruction *I, BasicBlock::iterator InsertPos, BasicBlock *SrcBlock, + BasicBlock *DestBlock, SmallVectorImpl<DbgVariableRecord *> &DPUsers); bool removeInstructionsBeforeUnreachable(Instruction &I); void addDeadEdge(BasicBlock *From, BasicBlock *To, diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 5d3e41fb5f29..7c40fb4fc860 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3120,10 +3120,10 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) { // If we are removing an alloca with a dbg.declare, insert dbg.value calls // before each store. SmallVector<DbgVariableIntrinsic *, 8> DVIs; - SmallVector<DPValue *, 8> DPVs; + SmallVector<DbgVariableRecord *, 8> DVRs; std::unique_ptr<DIBuilder> DIB; if (isa<AllocaInst>(MI)) { - findDbgUsers(DVIs, &MI, &DPVs); + findDbgUsers(DVIs, &MI, &DVRs); DIB.reset(new DIBuilder(*MI.getModule(), /*AllowUnresolved=*/false)); } @@ -3163,9 +3163,9 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) { for (auto *DVI : DVIs) if (DVI->isAddressOfVariable()) ConvertDebugDeclareToDebugValue(DVI, SI, *DIB); - for (auto *DPV : DPVs) - if (DPV->isAddressOfVariable()) - ConvertDebugDeclareToDebugValue(DPV, SI, *DIB); + for (auto *DVR : DVRs) + if (DVR->isAddressOfVariable()) + ConvertDebugDeclareToDebugValue(DVR, SI, *DIB); } else { // Casts, GEP, or anything else: we're about to delete this instruction, // so it can not have any valid uses. @@ -3210,9 +3210,9 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) { for (auto *DVI : DVIs) if (DVI->isAddressOfVariable() || DVI->getExpression()->startsWithDeref()) DVI->eraseFromParent(); - for (auto *DPV : DPVs) - if (DPV->isAddressOfVariable() || DPV->getExpression()->startsWithDeref()) - DPV->eraseFromParent(); + for (auto *DVR : DVRs) + if (DVR->isAddressOfVariable() || DVR->getExpression()->startsWithDeref()) + DVR->eraseFromParent(); return eraseInstFromFunction(MI); } @@ -4613,12 +4613,13 @@ bool InstCombinerImpl::tryToSinkInstruction(Instruction *I, // mark the location undef: we know it was supposed to receive a new location // here, but that computation has been sunk. SmallVector<DbgVariableIntrinsic *, 2> DbgUsers; - SmallVector<DPValue *, 2> DPValues; - findDbgUsers(DbgUsers, I, &DPValues); + SmallVector<DbgVariableRecord *, 2> DbgVariableRecords; + findDbgUsers(DbgUsers, I, &DbgVariableRecords); if (!DbgUsers.empty()) tryToSinkInstructionDbgValues(I, InsertPos, SrcBlock, DestBlock, DbgUsers); - if (!DPValues.empty()) - tryToSinkInstructionDPValues(I, InsertPos, SrcBlock, DestBlock, DPValues); + if (!DbgVariableRecords.empty()) + tryToSinkInstructionDbgVariableRecords(I, InsertPos, SrcBlock, DestBlock, + DbgVariableRecords); // PS: there are numerous flaws with this behaviour, not least that right now // assignments can be re-ordered past other assignments to the same variable @@ -4691,47 +4692,48 @@ void InstCombinerImpl::tryToSinkInstructionDbgValues( } } -void InstCombinerImpl::tryToSinkInstructionDPValues( +void InstCombinerImpl::tryToSinkInstructionDbgVariableRecords( Instruction *I, BasicBlock::iterator InsertPos, BasicBlock *SrcBlock, - BasicBlock *DestBlock, SmallVectorImpl<DPValue *> &DPValues) { - // Implementation of tryToSinkInstructionDbgValues, but for the DPValue of - // variable assignments rather than dbg.values. - - // Fetch all DPValues not already in the destination. - SmallVector<DPValue *, 2> DPValuesToSalvage; - for (auto &DPV : DPValues) - if (DPV->getParent() != DestBlock) - DPValuesToSalvage.push_back(DPV); - - // Fetch a second collection, of DPValues in the source block that we're going - // to sink. - SmallVector<DPValue *> DPValuesToSink; - for (DPValue *DPV : DPValuesToSalvage) - if (DPV->getParent() == SrcBlock) - DPValuesToSink.push_back(DPV); - - // Sort DPValues according to their position in the block. This is a partial - // order: DPValues attached to different instructions will be ordered by the - // instruction order, but DPValues attached to the same instruction won't - // have an order. - auto Order = [](DPValue *A, DPValue *B) -> bool { + BasicBlock *DestBlock, + SmallVectorImpl<DbgVariableRecord *> &DbgVariableRecords) { + // Implementation of tryToSinkInstructionDbgValues, but for the + // DbgVariableRecord of variable assignments rather than dbg.values. + + // Fetch all DbgVariableRecords not already in the destination. + SmallVector<DbgVariableRecord *, 2> DbgVariableRecordsToSalvage; + for (auto &DVR : DbgVariableRecords) + if (DVR->getParent() != DestBlock) + DbgVariableRecordsToSalvage.push_back(DVR); + + // Fetch a second collection, of DbgVariableRecords in the source block that + // we're going to sink. + SmallVector<DbgVariableRecord *> DbgVariableRecordsToSink; + for (DbgVariableRecord *DVR : DbgVariableRecordsToSalvage) + if (DVR->getParent() == SrcBlock) + DbgVariableRecordsToSink.push_back(DVR); + + // Sort DbgVariableRecords according to their position in the block. This is a + // partial order: DbgVariableRecords attached to different instructions will + // be ordered by the instruction order, but DbgVariableRecords attached to the + // same instruction won't have an order. + auto Order = [](DbgVariableRecord *A, DbgVariableRecord *B) -> bool { return B->getInstruction()->comesBefore(A->getInstruction()); }; - llvm::stable_sort(DPValuesToSink, Order); + llvm::stable_sort(DbgVariableRecordsToSink, Order); // If there are two assignments to the same variable attached to the same // instruction, the ordering between the two assignments is important. Scan // for this (rare) case and establish which is the last assignment. using InstVarPair = std::pair<const Instruction *, DebugVariable>; - SmallDenseMap<InstVarPair, DPValue *> FilterOutMap; - if (DPValuesToSink.size() > 1) { + SmallDenseMap<InstVarPair, DbgVariableRecord *> FilterOutMap; + if (DbgVariableRecordsToSink.size() > 1) { SmallDenseMap<InstVarPair, unsigned> CountMap; // Count how many assignments to each variable there is per instruction. - for (DPValue *DPV : DPValuesToSink) { + for (DbgVariableRecord *DVR : DbgVariableRecordsToSink) { DebugVariable DbgUserVariable = - DebugVariable(DPV->getVariable(), DPV->getExpression(), - DPV->getDebugLoc()->getInlinedAt()); - CountMap[std::make_pair(DPV->getInstruction(), DbgUserVariable)] += 1; + DebugVariable(DVR->getVariable(), DVR->getExpression(), + DVR->getDebugLoc()->getInlinedAt()); + CountMap[std::make_pair(DVR->getInstruction(), DbgUserVariable)] += 1; } // If there are any instructions with two assignments, add them to the @@ -4747,74 +4749,74 @@ void InstCombinerImpl::tryToSinkInstructionDPValues( // For all instruction/variable pairs needing extra filtering, find the // latest assignment. for (const Instruction *Inst : DupSet) { - for (DPValue &DPV : + for (DbgVariableRecord &DVR : llvm::reverse(filterDbgVars(Inst->getDbgRecordRange()))) { DebugVariable DbgUserVariable = - DebugVariable(DPV.getVariable(), DPV.getExpression(), - DPV.getDebugLoc()->getInlinedAt()); + DebugVariable(DVR.getVariable(), DVR.getExpression(), + DVR.getDebugLoc()->getInlinedAt()); auto FilterIt = FilterOutMap.find(std::make_pair(Inst, DbgUserVariable)); if (FilterIt == FilterOutMap.end()) continue; if (FilterIt->second != nullptr) continue; - FilterIt->second = &DPV; + FilterIt->second = &DVR; } } } - // Perform cloning of the DPValues that we plan on sinking, filter out any - // duplicate assignments identified above. - SmallVector<DPValue *, 2> DPVClones; + // Perform cloning of the DbgVariableRecords that we plan on sinking, filter + // out any duplicate assignments identified above. + SmallVector<DbgVariableRecord *, 2> DVRClones; SmallSet<DebugVariable, 4> SunkVariables; - for (DPValue *DPV : DPValuesToSink) { - if (DPV->Type == DPValue::LocationType::Declare) + for (DbgVariableRecord *DVR : DbgVariableRecordsToSink) { + if (DVR->Type == DbgVariableRecord::LocationType::Declare) continue; DebugVariable DbgUserVariable = - DebugVariable(DPV->getVariable(), DPV->getExpression(), - DPV->getDebugLoc()->getInlinedAt()); + DebugVariable(DVR->getVariable(), DVR->getExpression(), + DVR->getDebugLoc()->getInlinedAt()); // For any variable where there were multiple assignments in the same place, // ignore all but the last assignment. if (!FilterOutMap.empty()) { - InstVarPair IVP = std::make_pair(DPV->getInstruction(), DbgUserVariable); + InstVarPair IVP = std::make_pair(DVR->getInstruction(), DbgUserVariable); auto It = FilterOutMap.find(IVP); // Filter out. - if (It != FilterOutMap.end() && It->second != DPV) + if (It != FilterOutMap.end() && It->second != DVR) continue; } if (!SunkVariables.insert(DbgUserVariable).second) continue; - if (DPV->isDbgAssign()) + if (DVR->isDbgAssign()) continue; - DPVClones.emplace_back(DPV->clone()); - LLVM_DEBUG(dbgs() << "CLONE: " << *DPVClones.back() << '\n'); + DVRClones.emplace_back(DVR->clone()); + LLVM_DEBUG(dbgs() << "CLONE: " << *DVRClones.back() << '\n'); } // Perform salvaging without the clones, then sink the clones. - if (DPVClones.empty()) + if (DVRClones.empty()) return; - salvageDebugInfoForDbgValues(*I, {}, DPValuesToSalvage); + salvageDebugInfoForDbgValues(*I, {}, DbgVariableRecordsToSalvage); // The clones are in reverse order of original appearance. Assert that the // head bit is set on the iterator as we _should_ have received it via // getFirstInsertionPt. Inserting like this will reverse the clone order as // we'll repeatedly insert at the head, such as: - // DPV-3 (third insertion goes here) - // DPV-2 (second insertion goes here) - // DPV-1 (first insertion goes here) - // Any-Prior-DPVs + // DVR-3 (third insertion goes here) + // DVR-2 (second insertion goes here) + // DVR-1 (first insertion goes here) + // Any-Prior-DVRs // InsertPtInst assert(InsertPos.getHeadBit()); - for (DPValue *DPVClone : DPVClones) { - InsertPos->getParent()->insertDbgRecordBefore(DPVClone, InsertPos); - LLVM_DEBUG(dbgs() << "SINK: " << *DPVClone << '\n'); + for (DbgVariableRecord *DVRClone : DVRClones) { + InsertPos->getParent()->insertDbgRecordBefore(DVRClone, InsertPos); + LLVM_DEBUG(dbgs() << "SINK: " << *DVRClone << '\n'); } } diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 469cb1c2de2d..d2e3471d5600 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -1381,8 +1381,8 @@ static DbgAssignIntrinsic *DynCastToDbgAssign(DbgVariableIntrinsic *DVI) { return dyn_cast<DbgAssignIntrinsic>(DVI); } -static DPValue *DynCastToDbgAssign(DPValue *DPV) { - return DPV->isDbgAssign() ? DPV : nullptr; +static DbgVariableRecord *DynCastToDbgAssign(DbgVariableRecord *DVR) { + return DVR->isDbgAssign() ? DVR : nullptr; } bool HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo, @@ -1441,7 +1441,8 @@ bool HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo, }); // Helper utility for adding DW_OP_LLVM_tag_offset to debug-info records, - // abstracted over whether they're intrinsic-stored or DPValue stored. + // abstracted over whether they're intrinsic-stored or DbgVariableRecord + // stored. auto AnnotateDbgRecord = [&](auto *DPtr) { // Prepend "tag_offset, N" to the dwarf expression. // Tag offset logically applies to the alloca pointer, and it makes sense diff --git a/llvm/lib/Transforms/Scalar/ADCE.cpp b/llvm/lib/Transforms/Scalar/ADCE.cpp index 4d901310efe5..96ecd7f368a0 100644 --- a/llvm/lib/Transforms/Scalar/ADCE.cpp +++ b/llvm/lib/Transforms/Scalar/ADCE.cpp @@ -544,15 +544,16 @@ ADCEChanged AggressiveDeadCodeElimination::removeDeadInstructions() { // value of the function, and may therefore be deleted safely. // NOTE: We reuse the Worklist vector here for memory efficiency. for (Instruction &I : llvm::reverse(instructions(F))) { - // With "RemoveDIs" debug-info stored in DPValue objects, debug-info - // attached to this instruction, and drop any for scopes that aren't alive, - // like the rest of this loop does. Extending support to assignment tracking - // is future work. + // With "RemoveDIs" debug-info stored in DbgVariableRecord objects, + // debug-info attached to this instruction, and drop any for scopes that + // aren't alive, like the rest of this loop does. Extending support to + // assignment tracking is future work. for (DbgRecord &DR : make_early_inc_range(I.getDbgRecordRange())) { - // Avoid removing a DPV that is linked to instructions because it holds + // Avoid removing a DVR that is linked to instructions because it holds // information about an existing store. - if (DPValue *DPV = dyn_cast<DPValue>(&DR); DPV && DPV->isDbgAssign()) - if (!at::getAssignmentInsts(DPV).empty()) + if (DbgVariableRecord *DVR = dyn_cast<DbgVariableRecord>(&DR); + DVR && DVR->isDbgAssign()) + if (!at::getAssignmentInsts(DVR).empty()) continue; if (AliveScopes.count(DR.getDebugLoc()->getScope())) continue; diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 392e6ad5a66b..bfc8bd5970bf 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -526,7 +526,8 @@ static void shortenAssignment(Instruction *Inst, Value *OriginalDest, // returned by getAssignmentMarkers so save a copy of the markers to iterate // over. auto LinkedRange = at::getAssignmentMarkers(Inst); - SmallVector<DPValue *> LinkedDPVAssigns = at::getDPVAssignmentMarkers(Inst); + SmallVector<DbgVariableRecord *> LinkedDVRAssigns = + at::getDVRAssignmentMarkers(Inst); SmallVector<DbgAssignIntrinsic *> Linked(LinkedRange.begin(), LinkedRange.end()); auto InsertAssignForOverlap = [&](auto *Assign) { @@ -554,7 +555,7 @@ static void shortenAssignment(Instruction *Inst, Value *OriginalDest, NewAssign->setKillAddress(); }; for_each(Linked, InsertAssignForOverlap); - for_each(LinkedDPVAssigns, InsertAssignForOverlap); + for_each(LinkedDVRAssigns, InsertAssignForOverlap); } static bool tryToShorten(Instruction *DeadI, int64_t &DeadStart, diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 5d7b050ed5b2..fd6835952570 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -401,8 +401,8 @@ static bool replaceFoldableUses(Instruction *Cond, Value *ToVal, Changed |= replaceNonLocalUsesWith(Cond, ToVal); for (Instruction &I : reverse(*KnownAtEndOfBB)) { // Replace any debug-info record users of Cond with ToVal. - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) - DPV.replaceVariableLocationOp(Cond, ToVal, true); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) + DVR.replaceVariableLocationOp(Cond, ToVal, true); // Reached the Cond whose uses we are trying to replace, so there are no // more uses. @@ -1955,7 +1955,7 @@ void JumpThreadingPass::updateSSA( SSAUpdater SSAUpdate; SmallVector<Use *, 16> UsesToRename; SmallVector<DbgValueInst *, 4> DbgValues; - SmallVector<DPValue *, 4> DPValues; + SmallVector<DbgVariableRecord *, 4> DbgVariableRecords; for (Instruction &I : *BB) { // Scan all uses of this instruction to see if it is used outside of its @@ -1972,16 +1972,16 @@ void JumpThreadingPass::updateSSA( } // Find debug values outside of the block - findDbgValues(DbgValues, &I, &DPValues); + findDbgValues(DbgValues, &I, &DbgVariableRecords); llvm::erase_if(DbgValues, [&](const DbgValueInst *DbgVal) { return DbgVal->getParent() == BB; }); - llvm::erase_if(DPValues, [&](const DPValue *DPVal) { - return DPVal->getParent() == BB; + llvm::erase_if(DbgVariableRecords, [&](const DbgVariableRecord *DbgVarRec) { + return DbgVarRec->getParent() == BB; }); // If there are no uses outside the block, we're done with this instruction. - if (UsesToRename.empty() && DbgValues.empty() && DPValues.empty()) + if (UsesToRename.empty() && DbgValues.empty() && DbgVariableRecords.empty()) continue; LLVM_DEBUG(dbgs() << "JT: Renaming non-local uses of: " << I << "\n"); @@ -1994,11 +1994,11 @@ void JumpThreadingPass::updateSSA( while (!UsesToRename.empty()) SSAUpdate.RewriteUse(*UsesToRename.pop_back_val()); - if (!DbgValues.empty() || !DPValues.empty()) { + if (!DbgValues.empty() || !DbgVariableRecords.empty()) { SSAUpdate.UpdateDebugValues(&I, DbgValues); - SSAUpdate.UpdateDebugValues(&I, DPValues); + SSAUpdate.UpdateDebugValues(&I, DbgVariableRecords); DbgValues.clear(); - DPValues.clear(); + DbgVariableRecords.clear(); } LLVM_DEBUG(dbgs() << "\n"); @@ -2041,11 +2041,11 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI, return true; }; - // Duplicate implementation of the above dbg.value code, using DPValues - // instead. - auto RetargetDPValueIfPossible = [&](DPValue *DPV) { + // Duplicate implementation of the above dbg.value code, using + // DbgVariableRecords instead. + auto RetargetDbgVariableRecordIfPossible = [&](DbgVariableRecord *DVR) { SmallSet<std::pair<Value *, Value *>, 16> OperandsToRemap; - for (auto *Op : DPV->location_ops()) { + for (auto *Op : DVR->location_ops()) { Instruction *OpInst = dyn_cast<Instruction>(Op); if (!OpInst) continue; @@ -2056,7 +2056,7 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI, } for (auto &[OldOp, MappedOp] : OperandsToRemap) - DPV->replaceVariableLocationOp(OldOp, MappedOp); + DVR->replaceVariableLocationOp(OldOp, MappedOp); }; BasicBlock *RangeBB = BI->getParent(); @@ -2080,9 +2080,9 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI, cloneNoAliasScopes(NoAliasScopes, ClonedScopes, "thread", Context); auto CloneAndRemapDbgInfo = [&](Instruction *NewInst, Instruction *From) { - auto DPVRange = NewInst->cloneDebugInfoFrom(From); - for (DPValue &DPV : filterDbgVars(DPVRange)) - RetargetDPValueIfPossible(&DPV); + auto DVRRange = NewInst->cloneDebugInfoFrom(From); + for (DbgVariableRecord &DVR : filterDbgVars(DVRRange)) + RetargetDbgVariableRecordIfPossible(&DVR); }; // Clone the non-phi instructions of the source basic block into NewBB, @@ -2109,15 +2109,15 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI, } } - // There may be DPValues on the terminator, clone directly from marker - // to marker as there isn't an instruction there. + // There may be DbgVariableRecords on the terminator, clone directly from + // marker to marker as there isn't an instruction there. if (BE != RangeBB->end() && BE->hasDbgRecords()) { // Dump them at the end. DPMarker *Marker = RangeBB->getMarker(BE); DPMarker *EndMarker = NewBB->createMarker(NewBB->end()); - auto DPVRange = EndMarker->cloneDebugInfoFrom(Marker, std::nullopt); - for (DPValue &DPV : filterDbgVars(DPVRange)) - RetargetDPValueIfPossible(&DPV); + auto DVRRange = EndMarker->cloneDebugInfoFrom(Marker, std::nullopt); + for (DbgVariableRecord &DVR : filterDbgVars(DVRRange)) + RetargetDbgVariableRecordIfPossible(&DVR); } return ValueMapping; diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 7641ba2a219c..ec42e2d6e193 100644 --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -6367,10 +6367,10 @@ struct DVIRecoveryRec { DVIRecoveryRec(DbgValueInst *DbgValue) : DbgRef(DbgValue), Expr(DbgValue->getExpression()), HadLocationArgList(false) {} - DVIRecoveryRec(DPValue *DPV) - : DbgRef(DPV), Expr(DPV->getExpression()), HadLocationArgList(false) {} + DVIRecoveryRec(DbgVariableRecord *DVR) + : DbgRef(DVR), Expr(DVR->getExpression()), HadLocationArgList(false) {} - PointerUnion<DbgValueInst *, DPValue *> DbgRef; + PointerUnion<DbgValueInst *, DbgVariableRecord *> DbgRef; DIExpression *Expr; bool HadLocationArgList; SmallVector<WeakVH, 2> LocationOps; @@ -6466,7 +6466,7 @@ static void UpdateDbgValueInst(DVIRecoveryRec &DVIRec, if (isa<DbgValueInst *>(DVIRec.DbgRef)) UpdateDbgValueInstImpl(cast<DbgValueInst *>(DVIRec.DbgRef)); else - UpdateDbgValueInstImpl(cast<DPValue *>(DVIRec.DbgRef)); + UpdateDbgValueInstImpl(cast<DbgVariableRecord *>(DVIRec.DbgRef)); } /// Cached location ops may be erased during LSR, in which case a poison is @@ -6512,7 +6512,7 @@ static void restorePreTransformState(DVIRecoveryRec &DVIRec) { if (isa<DbgValueInst *>(DVIRec.DbgRef)) RestorePreTransformStateImpl(cast<DbgValueInst *>(DVIRec.DbgRef)); else - RestorePreTransformStateImpl(cast<DPValue *>(DVIRec.DbgRef)); + RestorePreTransformStateImpl(cast<DbgVariableRecord *>(DVIRec.DbgRef)); } static bool SalvageDVI(llvm::Loop *L, ScalarEvolution &SE, @@ -6522,7 +6522,7 @@ static bool SalvageDVI(llvm::Loop *L, ScalarEvolution &SE, if (isa<DbgValueInst *>(DVIRec.DbgRef) ? !cast<DbgValueInst *>(DVIRec.DbgRef)->isKillLocation() - : !cast<DPValue *>(DVIRec.DbgRef)->isKillLocation()) + : !cast<DbgVariableRecord *>(DVIRec.DbgRef)->isKillLocation()) return false; // LSR may have caused several changes to the dbg.value in the failed salvage @@ -6620,7 +6620,7 @@ static bool SalvageDVI(llvm::Loop *L, ScalarEvolution &SE, << *cast<DbgValueInst *>(DVIRec.DbgRef) << "\n"); else LLVM_DEBUG(dbgs() << "scev-salvage: Updated DVI: " - << *cast<DPValue *>(DVIRec.DbgRef) << "\n"); + << *cast<DbgVariableRecord *>(DVIRec.DbgRef) << "\n"); return true; } @@ -6711,9 +6711,9 @@ static void DbgGatherSalvagableDVI( SalvageableDVISCEVs.push_back(std::move(NewRec)); return true; }; - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - if (DPV.isDbgValue() || DPV.isDbgAssign()) - ProcessDbgValue(&DPV); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + if (DVR.isDbgValue() || DVR.isDbgAssign()) + ProcessDbgValue(&DVR); } auto DVI = dyn_cast<DbgValueInst>(&I); if (!DVI) diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index e238f311a15b..096c6d1b1fad 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -319,17 +319,17 @@ static DebugVariable getAggregateVariable(DbgVariableIntrinsic *DVI) { return DebugVariable(DVI->getVariable(), std::nullopt, DVI->getDebugLoc().getInlinedAt()); } -static DebugVariable getAggregateVariable(DPValue *DPV) { - return DebugVariable(DPV->getVariable(), std::nullopt, - DPV->getDebugLoc().getInlinedAt()); +static DebugVariable getAggregateVariable(DbgVariableRecord *DVR) { + return DebugVariable(DVR->getVariable(), std::nullopt, + DVR->getDebugLoc().getInlinedAt()); } /// Helpers for handling new and old debug info modes in migrateDebugInfo. /// These overloads unwrap a DbgInstPtr {Instruction* | DbgRecord*} union based /// on the \p Unused parameter type. -DPValue *UnwrapDbgInstPtr(DbgInstPtr P, DPValue *Unused) { +DbgVariableRecord *UnwrapDbgInstPtr(DbgInstPtr P, DbgVariableRecord *Unused) { (void)Unused; - return static_cast<DPValue *>(cast<DbgRecord *>(P)); + return static_cast<DbgVariableRecord *>(cast<DbgRecord *>(P)); } DbgAssignIntrinsic *UnwrapDbgInstPtr(DbgInstPtr P, DbgAssignIntrinsic *Unused) { (void)Unused; @@ -356,9 +356,9 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit, Instruction *Inst, Value *Dest, Value *Value, const DataLayout &DL) { auto MarkerRange = at::getAssignmentMarkers(OldInst); - auto DPVAssignMarkerRange = at::getDPVAssignmentMarkers(OldInst); + auto DVRAssignMarkerRange = at::getDVRAssignmentMarkers(OldInst); // Nothing to do if OldInst has no linked dbg.assign intrinsics. - if (MarkerRange.empty() && DPVAssignMarkerRange.empty()) + if (MarkerRange.empty() && DVRAssignMarkerRange.empty()) return; LLVM_DEBUG(dbgs() << " migrateDebugInfo\n"); @@ -379,9 +379,9 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit, for (auto *DAI : at::getAssignmentMarkers(OldAlloca)) BaseFragments[getAggregateVariable(DAI)] = DAI->getExpression()->getFragmentInfo(); - for (auto *DPV : at::getDPVAssignmentMarkers(OldAlloca)) - BaseFragments[getAggregateVariable(DPV)] = - DPV->getExpression()->getFragmentInfo(); + for (auto *DVR : at::getDVRAssignmentMarkers(OldAlloca)) + BaseFragments[getAggregateVariable(DVR)] = + DVR->getExpression()->getFragmentInfo(); // The new inst needs a DIAssignID unique metadata tag (if OldInst has // one). It shouldn't already have one: assert this assumption. @@ -488,7 +488,7 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit, }; for_each(MarkerRange, MigrateDbgAssign); - for_each(DPVAssignMarkerRange, MigrateDbgAssign); + for_each(DVRAssignMarkerRange, MigrateDbgAssign); } namespace { @@ -3195,7 +3195,7 @@ private: // emit dbg.assign intrinsics for mem intrinsics storing through non- // constant geps, or storing a variable number of bytes. assert(at::getAssignmentMarkers(&II).empty() && - at::getDPVAssignmentMarkers(&II).empty() && + at::getDVRAssignmentMarkers(&II).empty() && "AT: Unexpected link to non-const GEP"); deleteIfTriviallyDead(OldPtr); return false; @@ -3350,7 +3350,7 @@ private: DbgAssign->replaceVariableLocationOp(II.getDest(), AdjustedPtr); }; for_each(at::getAssignmentMarkers(&II), UpdateAssignAddress); - for_each(at::getDPVAssignmentMarkers(&II), UpdateAssignAddress); + for_each(at::getDVRAssignmentMarkers(&II), UpdateAssignAddress); II.setDest(AdjustedPtr); II.setDestAlignment(SliceAlign); } else { @@ -3939,7 +3939,7 @@ private: DL); } else { assert(at::getAssignmentMarkers(Store).empty() && - at::getDPVAssignmentMarkers(Store).empty() && + at::getDVRAssignmentMarkers(Store).empty() && "AT: unexpected debug.assign linked to store through " "unbounded GEP"); } @@ -5034,14 +5034,14 @@ static void insertNewDbgInst(DIBuilder &DIB, DbgAssignIntrinsic *Orig, LLVM_DEBUG(dbgs() << "Created new assign intrinsic: " << *NewAssign << "\n"); (void)NewAssign; } -static void insertNewDbgInst(DIBuilder &DIB, DPValue *Orig, AllocaInst *NewAddr, - DIExpression *NewFragmentExpr, +static void insertNewDbgInst(DIBuilder &DIB, DbgVariableRecord *Orig, + AllocaInst *NewAddr, DIExpression *NewFragmentExpr, Instruction *BeforeInst) { (void)DIB; if (Orig->isDbgDeclare()) { - DPValue *DPV = DPValue::createDPVDeclare( + DbgVariableRecord *DVR = DbgVariableRecord::createDVRDeclare( NewAddr, Orig->getVariable(), NewFragmentExpr, Orig->getDebugLoc()); - BeforeInst->getParent()->insertDbgRecordBefore(DPV, + BeforeInst->getParent()->insertDbgRecordBefore(DVR, BeforeInst->getIterator()); return; } @@ -5049,10 +5049,10 @@ static void insertNewDbgInst(DIBuilder &DIB, DPValue *Orig, AllocaInst *NewAddr, NewAddr->setMetadata(LLVMContext::MD_DIAssignID, DIAssignID::getDistinct(NewAddr->getContext())); } - DPValue *NewAssign = DPValue::createLinkedDPVAssign( + DbgVariableRecord *NewAssign = DbgVariableRecord::createLinkedDVRAssign( NewAddr, Orig->getValue(), Orig->getVariable(), NewFragmentExpr, NewAddr, Orig->getAddressExpression(), Orig->getDebugLoc()); - LLVM_DEBUG(dbgs() << "Created new DPVAssign: " << *NewAssign << "\n"); + LLVM_DEBUG(dbgs() << "Created new DVRAssign: " << *NewAssign << "\n"); (void)NewAssign; } @@ -5220,7 +5220,7 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) { OldDII->eraseFromParent(); }; for_each(findDbgDeclares(Fragment.Alloca), RemoveOne); - for_each(findDPVDeclares(Fragment.Alloca), RemoveOne); + for_each(findDVRDeclares(Fragment.Alloca), RemoveOne); insertNewDbgInst(DIB, DbgVariable, Fragment.Alloca, FragmentExpr, &AI); } @@ -5229,9 +5229,9 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) { // Migrate debug information from the old alloca to the new alloca(s) // and the individual partitions. for_each(findDbgDeclares(&AI), MigrateOne); - for_each(findDPVDeclares(&AI), MigrateOne); + for_each(findDVRDeclares(&AI), MigrateOne); for_each(at::getAssignmentMarkers(&AI), MigrateOne); - for_each(at::getDPVAssignmentMarkers(&AI), MigrateOne); + for_each(at::getDVRAssignmentMarkers(&AI), MigrateOne); return Changed; } @@ -5355,7 +5355,7 @@ bool SROA::deleteDeadInstructions( DeletedAllocas.insert(AI); for (DbgDeclareInst *OldDII : findDbgDeclares(AI)) OldDII->eraseFromParent(); - for (DPValue *OldDII : findDPVDeclares(AI)) + for (DbgVariableRecord *OldDII : findDVRDeclares(AI)) OldDII->eraseFromParent(); } diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp index 9fcaf2a89e56..64b850a6a5c2 100644 --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -1260,8 +1260,9 @@ static BasicBlock *buildClonedLoopBlocks( Module *M = ClonedPH->getParent()->getParent(); for (auto *ClonedBB : NewBlocks) for (Instruction &I : *ClonedBB) { - RemapDPValueRange(M, I.getDbgRecordRange(), VMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + RemapDbgVariableRecordRange(M, I.getDbgRecordRange(), VMap, + RF_NoModuleLevelChanges | + RF_IgnoreMissingLocals); RemapInstruction(&I, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); if (auto *II = dyn_cast<AssumeInst>(&I)) diff --git a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp index 44ea6e9ffefa..400b56894174 100644 --- a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp +++ b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp @@ -263,7 +263,8 @@ static InstructionCost ComputeSpeculationCost(const Instruction *I, bool SpeculativeExecutionPass::considerHoistingFromTo( BasicBlock &FromBlock, BasicBlock &ToBlock) { SmallPtrSet<const Instruction *, 8> NotHoisted; - SmallDenseMap<const Instruction *, SmallVector<DPValue *>> DPValuesToHoist; + SmallDenseMap<const Instruction *, SmallVector<DbgVariableRecord *>> + DbgVariableRecordsToHoist; auto HasNoUnhoistedInstr = [&NotHoisted](auto Values) { for (const Value *V : Values) { if (const auto *I = dyn_cast_or_null<Instruction>(V)) @@ -291,11 +292,11 @@ bool SpeculativeExecutionPass::considerHoistingFromTo( InstructionCost TotalSpeculationCost = 0; unsigned NotHoistedInstCount = 0; for (const auto &I : FromBlock) { - // Make note of any DPValues that need hoisting. DPLabels + // Make note of any DbgVariableRecords that need hoisting. DPLabels // get left behind just like llvm.dbg.labels. - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - if (HasNoUnhoistedInstr(DPV.location_ops())) - DPValuesToHoist[DPV.getInstruction()].push_back(&DPV); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + if (HasNoUnhoistedInstr(DVR.location_ops())) + DbgVariableRecordsToHoist[DVR.getInstruction()].push_back(&DVR); } const InstructionCost Cost = ComputeSpeculationCost(&I, *TTI); if (Cost.isValid() && isSafeToSpeculativelyExecute(&I) && @@ -314,13 +315,13 @@ bool SpeculativeExecutionPass::considerHoistingFromTo( } for (auto I = FromBlock.begin(); I != FromBlock.end();) { - // If any DPValues attached to this instruction should be hoisted, hoist - // them now - they will end up attached to either the next hoisted + // If any DbgVariableRecords attached to this instruction should be hoisted, + // hoist them now - they will end up attached to either the next hoisted // instruction or the ToBlock terminator. - if (DPValuesToHoist.contains(&*I)) { - for (auto *DPV : DPValuesToHoist[&*I]) { - DPV->removeFromParent(); - ToBlock.insertDbgRecordBefore(DPV, + if (DbgVariableRecordsToHoist.contains(&*I)) { + for (auto *DVR : DbgVariableRecordsToHoist[&*I]) { + DVR->removeFromParent(); + ToBlock.insertDbgRecordBefore(DVR, ToBlock.getTerminator()->getIterator()); } } diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index e7ad18df106d..bf1de05a647d 100644 --- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -382,8 +382,9 @@ bool llvm::MergeBlockSuccessorsIntoGivenBlocks( /// - Check fully overlapping fragments and not only identical fragments. /// - Support dbg.declare. dbg.label, and possibly other meta instructions being /// part of the sequence of consecutive instructions. -static bool DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { - SmallVector<DPValue *, 8> ToBeRemoved; +static bool +DbgVariableRecordsRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { + SmallVector<DbgVariableRecord *, 8> ToBeRemoved; SmallDenseSet<DebugVariable> VariableSet; for (auto &I : reverse(*BB)) { for (DbgRecord &DR : reverse(I.getDbgRecordRange())) { @@ -394,10 +395,10 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { continue; } - DPValue &DPV = cast<DPValue>(DR); + DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR); // Skip declare-type records, as the debug intrinsic method only works // on dbg.value intrinsics. - if (DPV.getType() == DPValue::LocationType::Declare) { + if (DVR.getType() == DbgVariableRecord::LocationType::Declare) { // The debug intrinsic method treats dbg.declares are "non-debug" // instructions (i.e., a break in a consecutive range of debug // intrinsics). Emulate that to create identical outputs. See @@ -407,8 +408,8 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { continue; } - DebugVariable Key(DPV.getVariable(), DPV.getExpression(), - DPV.getDebugLoc()->getInlinedAt()); + DebugVariable Key(DVR.getVariable(), DVR.getExpression(), + DVR.getDebugLoc()->getInlinedAt()); auto R = VariableSet.insert(Key); // If the same variable fragment is described more than once it is enough // to keep the last one (i.e. the first found since we for reverse @@ -416,14 +417,14 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { if (R.second) continue; - if (DPV.isDbgAssign()) { + if (DVR.isDbgAssign()) { // Don't delete dbg.assign intrinsics that are linked to instructions. - if (!at::getAssignmentInsts(&DPV).empty()) + if (!at::getAssignmentInsts(&DVR).empty()) continue; // Unlinked dbg.assign intrinsics can be treated like dbg.values. } - ToBeRemoved.push_back(&DPV); + ToBeRemoved.push_back(&DVR); continue; } // Sequence with consecutive dbg.value instrs ended. Clear the map to @@ -432,15 +433,15 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { VariableSet.clear(); } - for (auto &DPV : ToBeRemoved) - DPV->eraseFromParent(); + for (auto &DVR : ToBeRemoved) + DVR->eraseFromParent(); return !ToBeRemoved.empty(); } static bool removeRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { if (BB->IsNewDbgInfoFormat) - return DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BB); + return DbgVariableRecordsRemoveRedundantDbgInstrsUsingBackwardScan(BB); SmallVector<DbgValueInst *, 8> ToBeRemoved; SmallDenseSet<DebugVariable> VariableSet; @@ -499,29 +500,30 @@ static bool removeRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { /// /// Possible improvements: /// - Keep track of non-overlapping fragments. -static bool DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { - SmallVector<DPValue *, 8> ToBeRemoved; +static bool +DbgVariableRecordsRemoveRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { + SmallVector<DbgVariableRecord *, 8> ToBeRemoved; DenseMap<DebugVariable, std::pair<SmallVector<Value *, 4>, DIExpression *>> VariableMap; for (auto &I : *BB) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - if (DPV.getType() == DPValue::LocationType::Declare) + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + if (DVR.getType() == DbgVariableRecord::LocationType::Declare) continue; - DebugVariable Key(DPV.getVariable(), std::nullopt, - DPV.getDebugLoc()->getInlinedAt()); + DebugVariable Key(DVR.getVariable(), std::nullopt, + DVR.getDebugLoc()->getInlinedAt()); auto VMI = VariableMap.find(Key); // A dbg.assign with no linked instructions can be treated like a // dbg.value (i.e. can be deleted). bool IsDbgValueKind = - (!DPV.isDbgAssign() || at::getAssignmentInsts(&DPV).empty()); + (!DVR.isDbgAssign() || at::getAssignmentInsts(&DVR).empty()); // Update the map if we found a new value/expression describing the // variable, or if the variable wasn't mapped already. - SmallVector<Value *, 4> Values(DPV.location_ops()); + SmallVector<Value *, 4> Values(DVR.location_ops()); if (VMI == VariableMap.end() || VMI->second.first != Values || - VMI->second.second != DPV.getExpression()) { + VMI->second.second != DVR.getExpression()) { if (IsDbgValueKind) - VariableMap[Key] = {Values, DPV.getExpression()}; + VariableMap[Key] = {Values, DVR.getExpression()}; else VariableMap[Key] = {Values, nullptr}; continue; @@ -530,55 +532,56 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { if (!IsDbgValueKind) continue; // Found an identical mapping. Remember the instruction for later removal. - ToBeRemoved.push_back(&DPV); + ToBeRemoved.push_back(&DVR); } } - for (auto *DPV : ToBeRemoved) - DPV->eraseFromParent(); + for (auto *DVR : ToBeRemoved) + DVR->eraseFromParent(); return !ToBeRemoved.empty(); } -static bool DPValuesRemoveUndefDbgAssignsFromEntryBlock(BasicBlock *BB) { +static bool +DbgVariableRecordsRemoveUndefDbgAssignsFromEntryBlock(BasicBlock *BB) { assert(BB->isEntryBlock() && "expected entry block"); - SmallVector<DPValue *, 8> ToBeRemoved; + SmallVector<DbgVariableRecord *, 8> ToBeRemoved; DenseSet<DebugVariable> SeenDefForAggregate; // Returns the DebugVariable for DVI with no fragment info. - auto GetAggregateVariable = [](const DPValue &DPV) { - return DebugVariable(DPV.getVariable(), std::nullopt, - DPV.getDebugLoc().getInlinedAt()); + auto GetAggregateVariable = [](const DbgVariableRecord &DVR) { + return DebugVariable(DVR.getVariable(), std::nullopt, + DVR.getDebugLoc().getInlinedAt()); }; // Remove undef dbg.assign intrinsics that are encountered before // any non-undef intrinsics from the entry block. for (auto &I : *BB) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - if (!DPV.isDbgValue() && !DPV.isDbgAssign()) + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + if (!DVR.isDbgValue() && !DVR.isDbgAssign()) continue; bool IsDbgValueKind = - (DPV.isDbgValue() || at::getAssignmentInsts(&DPV).empty()); - DebugVariable Aggregate = GetAggregateVariable(DPV); + (DVR.isDbgValue() || at::getAssignmentInsts(&DVR).empty()); + DebugVariable Aggregate = GetAggregateVariable(DVR); if (!SeenDefForAggregate.contains(Aggregate)) { - bool IsKill = DPV.isKillLocation() && IsDbgValueKind; + bool IsKill = DVR.isKillLocation() && IsDbgValueKind; if (!IsKill) { SeenDefForAggregate.insert(Aggregate); - } else if (DPV.isDbgAssign()) { - ToBeRemoved.push_back(&DPV); + } else if (DVR.isDbgAssign()) { + ToBeRemoved.push_back(&DVR); } } } } - for (DPValue *DPV : ToBeRemoved) - DPV->eraseFromParent(); + for (DbgVariableRecord *DVR : ToBeRemoved) + DVR->eraseFromParent(); return !ToBeRemoved.empty(); } static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { if (BB->IsNewDbgInfoFormat) - return DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BB); + return DbgVariableRecordsRemoveRedundantDbgInstrsUsingForwardScan(BB); SmallVector<DbgValueInst *, 8> ToBeRemoved; DenseMap<DebugVariable, std::pair<SmallVector<Value *, 4>, DIExpression *>> @@ -642,7 +645,7 @@ static bool removeRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { /// - Keep track of non-overlapping fragments. static bool removeUndefDbgAssignsFromEntryBlock(BasicBlock *BB) { if (BB->IsNewDbgInfoFormat) - return DPValuesRemoveUndefDbgAssignsFromEntryBlock(BB); + return DbgVariableRecordsRemoveUndefDbgAssignsFromEntryBlock(BB); assert(BB->isEntryBlock() && "expected entry block"); SmallVector<DbgAssignIntrinsic *, 8> ToBeRemoved; diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index 6931d1997aa6..3eac726994ae 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -276,8 +276,8 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, // attached debug-info records. for (Instruction &II : *BB) { RemapInstruction(&II, VMap, RemapFlag, TypeMapper, Materializer); - RemapDPValueRange(II.getModule(), II.getDbgRecordRange(), VMap, RemapFlag, - TypeMapper, Materializer); + RemapDbgVariableRecordRange(II.getModule(), II.getDbgRecordRange(), VMap, + RemapFlag, TypeMapper, Materializer); } // Only update !llvm.dbg.cu for DifferentModule (not CloneModule). In the @@ -641,8 +641,8 @@ void PruningFunctionCloner::CloneBlock( // Recursively clone any reachable successor blocks. append_range(ToClone, successors(BB->getTerminator())); } else { - // If we didn't create a new terminator, clone DPValues from the old - // terminator onto the new terminator. + // If we didn't create a new terminator, clone DbgVariableRecords from the + // old terminator onto the new terminator. Instruction *NewInst = NewBB->getTerminator(); assert(NewInst); @@ -884,14 +884,15 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, TypeMapper, Materializer); } - // Do the same for DPValues, touching all the instructions in the cloned - // range of blocks. + // Do the same for DbgVariableRecords, touching all the instructions in the + // cloned range of blocks. Function::iterator Begin = cast<BasicBlock>(VMap[StartingBB])->getIterator(); for (BasicBlock &BB : make_range(Begin, NewFunc->end())) { for (Instruction &I : BB) { - RemapDPValueRange(I.getModule(), I.getDbgRecordRange(), VMap, - ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges, - TypeMapper, Materializer); + RemapDbgVariableRecordRange(I.getModule(), I.getDbgRecordRange(), VMap, + ModuleLevelChanges ? RF_None + : RF_NoModuleLevelChanges, + TypeMapper, Materializer); } } @@ -990,8 +991,9 @@ void llvm::remapInstructionsInBlocks(ArrayRef<BasicBlock *> Blocks, // Rewrite the code to refer to itself. for (auto *BB : Blocks) { for (auto &Inst : *BB) { - RemapDPValueRange(Inst.getModule(), Inst.getDbgRecordRange(), VMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + RemapDbgVariableRecordRange( + Inst.getModule(), Inst.getDbgRecordRange(), VMap, + RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); RemapInstruction(&Inst, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); } diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index a43e2ce3d4d3..122b7a9747b6 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -1524,14 +1524,14 @@ void CodeExtractor::calculateNewCallTerminatorWeights( static void eraseDebugIntrinsicsWithNonLocalRefs(Function &F) { for (Instruction &I : instructions(F)) { SmallVector<DbgVariableIntrinsic *, 4> DbgUsers; - SmallVector<DPValue *, 4> DPValues; - findDbgUsers(DbgUsers, &I, &DPValues); + SmallVector<DbgVariableRecord *, 4> DbgVariableRecords; + findDbgUsers(DbgUsers, &I, &DbgVariableRecords); for (DbgVariableIntrinsic *DVI : DbgUsers) if (DVI->getFunction() != &F) DVI->eraseFromParent(); - for (DPValue *DPV : DPValues) - if (DPV->getFunction() != &F) - DPV->eraseFromParent(); + for (DbgVariableRecord *DVR : DbgVariableRecords) + if (DVR->getFunction() != &F) + DVR->eraseFromParent(); } } @@ -1585,7 +1585,7 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc, // point to a variable in the wrong scope. SmallDenseMap<DINode *, DINode *> RemappedMetadata; SmallVector<Instruction *, 4> DebugIntrinsicsToDelete; - SmallVector<DPValue *, 4> DPVsToDelete; + SmallVector<DbgVariableRecord *, 4> DVRsToDelete; DenseMap<const MDNode *, MDNode *> Cache; auto GetUpdatedDIVariable = [&](DILocalVariable *OldVar) { @@ -1624,19 +1624,19 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc, continue; } - DPValue &DPV = cast<DPValue>(DR); + DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR); // Apply the two updates that dbg.values get: invalid operands, and // variable metadata fixup. - if (any_of(DPV.location_ops(), IsInvalidLocation)) { - DPVsToDelete.push_back(&DPV); + if (any_of(DVR.location_ops(), IsInvalidLocation)) { + DVRsToDelete.push_back(&DVR); continue; } - if (DPV.isDbgAssign() && IsInvalidLocation(DPV.getAddress())) { - DPVsToDelete.push_back(&DPV); + if (DVR.isDbgAssign() && IsInvalidLocation(DVR.getAddress())) { + DVRsToDelete.push_back(&DVR); continue; } - if (!DPV.getDebugLoc().getInlinedAt()) - DPV.setVariable(GetUpdatedDIVariable(DPV.getVariable())); + if (!DVR.getDebugLoc().getInlinedAt()) + DVR.setVariable(GetUpdatedDIVariable(DVR.getVariable())); } }; @@ -1674,8 +1674,8 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc, for (auto *DII : DebugIntrinsicsToDelete) DII->eraseFromParent(); - for (auto *DPV : DPVsToDelete) - DPV->getMarker()->MarkedInstr->dropOneDbgRecord(DPV); + for (auto *DVR : DVRsToDelete) + DVR->getMarker()->MarkedInstr->dropOneDbgRecord(DVR); DIB.finalizeSubprogram(NewSP); // Fix up the scope information attached to the line locations in the new diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 33d32720a333..833dcbec228b 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1710,17 +1710,17 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI, }; // Helper-util for updating debug-info records attached to instructions. - auto UpdateDPV = [&](DbgRecord *DPV) { - assert(DPV->getDebugLoc() && "Debug Value must have debug loc"); + auto UpdateDVR = [&](DbgRecord *DVR) { + assert(DVR->getDebugLoc() && "Debug Value must have debug loc"); if (NoInlineLineTables) { - DPV->setDebugLoc(TheCallDL); + DVR->setDebugLoc(TheCallDL); return; } - DebugLoc DL = DPV->getDebugLoc(); + DebugLoc DL = DVR->getDebugLoc(); DebugLoc IDL = inlineDebugLoc(DL, InlinedAtNode, - DPV->getMarker()->getParent()->getContext(), IANodes); - DPV->setDebugLoc(IDL); + DVR->getMarker()->getParent()->getContext(), IANodes); + DVR->setDebugLoc(IDL); }; // Iterate over all instructions, updating metadata and debug-info records. @@ -1728,8 +1728,8 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI, for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { UpdateInst(*BI); - for (DbgRecord &DPV : BI->getDbgRecordRange()) { - UpdateDPV(&DPV); + for (DbgRecord &DVR : BI->getDbgRecordRange()) { + UpdateDVR(&DVR); } } @@ -1797,7 +1797,7 @@ static at::StorageToVarsMap collectEscapedLocals(const DataLayout &DL, EscapedLocals[Base].insert(at::VarRecord(DbgAssign)); }; for_each(at::getAssignmentMarkers(Base), CollectAssignsForStorage); - for_each(at::getDPVAssignmentMarkers(Base), CollectAssignsForStorage); + for_each(at::getDVRAssignmentMarkers(Base), CollectAssignsForStorage); } return EscapedLocals; } @@ -1829,9 +1829,9 @@ static void fixupAssignments(Function::iterator Start, Function::iterator End) { // attachment or use, replace it with a new version. for (auto BBI = Start; BBI != End; ++BBI) { for (Instruction &I : *BBI) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - if (DPV.isDbgAssign()) - DPV.setAssignId(GetNewID(DPV.getAssignID())); + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + if (DVR.isDbgAssign()) + DVR.setAssignId(GetNewID(DVR.getAssignID())); } if (auto *ID = I.getMetadata(LLVMContext::MD_DIAssignID)) I.setMetadata(LLVMContext::MD_DIAssignID, GetNewID(ID)); diff --git a/llvm/lib/Transforms/Utils/LCSSA.cpp b/llvm/lib/Transforms/Utils/LCSSA.cpp index 5e0c312fe149..ab1edf47d8db 100644 --- a/llvm/lib/Transforms/Utils/LCSSA.cpp +++ b/llvm/lib/Transforms/Utils/LCSSA.cpp @@ -242,8 +242,8 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist, } SmallVector<DbgValueInst *, 4> DbgValues; - SmallVector<DPValue *, 4> DPValues; - llvm::findDbgValues(DbgValues, I, &DPValues); + SmallVector<DbgVariableRecord *, 4> DbgVariableRecords; + llvm::findDbgValues(DbgValues, I, &DbgVariableRecords); // Update pre-existing debug value uses that reside outside the loop. for (auto *DVI : DbgValues) { @@ -261,8 +261,8 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist, // RemoveDIs: copy-paste of block above, using non-instruction debug-info // records. - for (DPValue *DPV : DPValues) { - BasicBlock *UserBB = DPV->getMarker()->getParent(); + for (DbgVariableRecord *DVR : DbgVariableRecords) { + BasicBlock *UserBB = DVR->getMarker()->getParent(); if (InstBB == UserBB || L->contains(UserBB)) continue; // We currently only handle debug values residing in blocks that were @@ -271,7 +271,7 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist, Value *V = AddedPHIs.size() == 1 ? AddedPHIs[0] : SSAUpdate.FindValueForBlock(UserBB); if (V) - DPV->replaceVariableLocationOp(I, V); + DVR->replaceVariableLocationOp(I, V); } // SSAUpdater might have inserted phi-nodes inside other loops. We'll need diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 422319eb1851..3d3b97eca92b 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -609,12 +609,12 @@ void llvm::RecursivelyDeleteTriviallyDeadInstructions( bool llvm::replaceDbgUsesWithUndef(Instruction *I) { SmallVector<DbgVariableIntrinsic *, 1> DbgUsers; - SmallVector<DPValue *, 1> DPUsers; + SmallVector<DbgVariableRecord *, 1> DPUsers; findDbgUsers(DbgUsers, I, &DPUsers); for (auto *DII : DbgUsers) DII->setKillLocation(); - for (auto *DPV : DPUsers) - DPV->setKillLocation(); + for (auto *DVR : DPUsers) + DVR->setKillLocation(); return !DbgUsers.empty() || !DPUsers.empty(); } @@ -1570,16 +1570,16 @@ static bool PhiHasDebugValue(DILocalVariable *DIVar, // is removed by LowerDbgDeclare(), we need to make sure that we are // not inserting the same dbg.value intrinsic over and over. SmallVector<DbgValueInst *, 1> DbgValues; - SmallVector<DPValue *, 1> DPValues; - findDbgValues(DbgValues, APN, &DPValues); + SmallVector<DbgVariableRecord *, 1> DbgVariableRecords; + findDbgValues(DbgValues, APN, &DbgVariableRecords); for (auto *DVI : DbgValues) { assert(is_contained(DVI->getValues(), APN)); if ((DVI->getVariable() == DIVar) && (DVI->getExpression() == DIExpr)) return true; } - for (auto *DPV : DPValues) { - assert(is_contained(DPV->location_ops(), APN)); - if ((DPV->getVariable() == DIVar) && (DPV->getExpression() == DIExpr)) + for (auto *DVR : DbgVariableRecords) { + assert(is_contained(DVR->location_ops(), APN)); + if ((DVR->getVariable() == DIVar) && (DVR->getExpression() == DIExpr)) return true; } return false; @@ -1617,23 +1617,23 @@ static bool valueCoversEntireFragment(Type *ValTy, DbgVariableIntrinsic *DII) { // Could not determine size of variable. Conservatively return false. return false; } -// RemoveDIs: duplicate implementation of the above, using DPValues, the -// replacement for dbg.values. -static bool valueCoversEntireFragment(Type *ValTy, DPValue *DPV) { - const DataLayout &DL = DPV->getModule()->getDataLayout(); +// RemoveDIs: duplicate implementation of the above, using DbgVariableRecords, +// the replacement for dbg.values. +static bool valueCoversEntireFragment(Type *ValTy, DbgVariableRecord *DVR) { + const DataLayout &DL = DVR->getModule()->getDataLayout(); TypeSize ValueSize = DL.getTypeAllocSizeInBits(ValTy); - if (std::optional<uint64_t> FragmentSize = DPV->getFragmentSizeInBits()) + if (std::optional<uint64_t> FragmentSize = DVR->getFragmentSizeInBits()) return TypeSize::isKnownGE(ValueSize, TypeSize::getFixed(*FragmentSize)); // We can't always calculate the size of the DI variable (e.g. if it is a // VLA). Try to use the size of the alloca that the dbg intrinsic describes // intead. - if (DPV->isAddressOfVariable()) { - // DPV should have exactly 1 location when it is an address. - assert(DPV->getNumVariableLocationOps() == 1 && + if (DVR->isAddressOfVariable()) { + // DVR should have exactly 1 location when it is an address. + assert(DVR->getNumVariableLocationOps() == 1 && "address of variable must have exactly 1 location operand."); if (auto *AI = - dyn_cast_or_null<AllocaInst>(DPV->getVariableLocationOp(0))) { + dyn_cast_or_null<AllocaInst>(DVR->getVariableLocationOp(0))) { if (std::optional<TypeSize> FragmentSize = AI->getAllocationSizeInBits(DL)) { return TypeSize::isKnownGE(ValueSize, *FragmentSize); } @@ -1643,38 +1643,38 @@ static bool valueCoversEntireFragment(Type *ValTy, DPValue *DPV) { return false; } -static void insertDbgValueOrDPValue(DIBuilder &Builder, Value *DV, - DILocalVariable *DIVar, - DIExpression *DIExpr, - const DebugLoc &NewLoc, - BasicBlock::iterator Instr) { +static void insertDbgValueOrDbgVariableRecord(DIBuilder &Builder, Value *DV, + DILocalVariable *DIVar, + DIExpression *DIExpr, + const DebugLoc &NewLoc, + BasicBlock::iterator Instr) { if (!UseNewDbgInfoFormat) { auto DbgVal = Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc, (Instruction *)nullptr); DbgVal.get<Instruction *>()->insertBefore(Instr); } else { // RemoveDIs: if we're using the new debug-info format, allocate a - // DPValue directly instead of a dbg.value intrinsic. + // DbgVariableRecord directly instead of a dbg.value intrinsic. ValueAsMetadata *DVAM = ValueAsMetadata::get(DV); - DPValue *DV = new DPValue(DVAM, DIVar, DIExpr, NewLoc.get()); + DbgVariableRecord *DV = + new DbgVariableRecord(DVAM, DIVar, DIExpr, NewLoc.get()); Instr->getParent()->insertDbgRecordBefore(DV, Instr); } } -static void insertDbgValueOrDPValueAfter(DIBuilder &Builder, Value *DV, - DILocalVariable *DIVar, - DIExpression *DIExpr, - const DebugLoc &NewLoc, - BasicBlock::iterator Instr) { +static void insertDbgValueOrDbgVariableRecordAfter( + DIBuilder &Builder, Value *DV, DILocalVariable *DIVar, DIExpression *DIExpr, + const DebugLoc &NewLoc, BasicBlock::iterator Instr) { if (!UseNewDbgInfoFormat) { auto DbgVal = Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc, (Instruction *)nullptr); DbgVal.get<Instruction *>()->insertAfter(&*Instr); } else { // RemoveDIs: if we're using the new debug-info format, allocate a - // DPValue directly instead of a dbg.value intrinsic. + // DbgVariableRecord directly instead of a dbg.value intrinsic. ValueAsMetadata *DVAM = ValueAsMetadata::get(DV); - DPValue *DV = new DPValue(DVAM, DIVar, DIExpr, NewLoc.get()); + DbgVariableRecord *DV = + new DbgVariableRecord(DVAM, DIVar, DIExpr, NewLoc.get()); Instr->getParent()->insertDbgRecordAfter(DV, &*Instr); } } @@ -1707,8 +1707,8 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, DIExpr->isDeref() || (!DIExpr->startsWithDeref() && valueCoversEntireFragment(DV->getType(), DII)); if (CanConvert) { - insertDbgValueOrDPValue(Builder, DV, DIVar, DIExpr, NewLoc, - SI->getIterator()); + insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc, + SI->getIterator()); return; } @@ -1720,8 +1720,8 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, // know which part) we insert an dbg.value intrinsic to indicate that we // know nothing about the variable's content. DV = UndefValue::get(DV->getType()); - insertDbgValueOrDPValue(Builder, DV, DIVar, DIExpr, NewLoc, - SI->getIterator()); + insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc, + SI->getIterator()); } /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value @@ -1747,19 +1747,19 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, // future if multi-location support is added to the IR, it might be // preferable to keep tracking both the loaded value and the original // address in case the alloca can not be elided. - insertDbgValueOrDPValueAfter(Builder, LI, DIVar, DIExpr, NewLoc, - LI->getIterator()); + insertDbgValueOrDbgVariableRecordAfter(Builder, LI, DIVar, DIExpr, NewLoc, + LI->getIterator()); } -void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV, StoreInst *SI, - DIBuilder &Builder) { - assert(DPV->isAddressOfVariable() || DPV->isDbgAssign()); - auto *DIVar = DPV->getVariable(); +void llvm::ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, + StoreInst *SI, DIBuilder &Builder) { + assert(DVR->isAddressOfVariable() || DVR->isDbgAssign()); + auto *DIVar = DVR->getVariable(); assert(DIVar && "Missing variable"); - auto *DIExpr = DPV->getExpression(); + auto *DIExpr = DVR->getExpression(); Value *DV = SI->getValueOperand(); - DebugLoc NewLoc = getDebugValueLoc(DPV); + DebugLoc NewLoc = getDebugValueLoc(DVR); // If the alloca describes the variable itself, i.e. the expression in the // dbg.declare doesn't start with a dereference, we can perform the @@ -1775,16 +1775,16 @@ void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV, StoreInst *SI, // deref expression. bool CanConvert = DIExpr->isDeref() || (!DIExpr->startsWithDeref() && - valueCoversEntireFragment(DV->getType(), DPV)); + valueCoversEntireFragment(DV->getType(), DVR)); if (CanConvert) { - insertDbgValueOrDPValue(Builder, DV, DIVar, DIExpr, NewLoc, - SI->getIterator()); + insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc, + SI->getIterator()); return; } // FIXME: If storing to a part of the variable described by the dbg.declare, // then we want to insert a dbg.value for the corresponding fragment. - LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to dbg.value: " << *DPV + LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to dbg.value: " << *DVR << '\n'); assert(UseNewDbgInfoFormat); @@ -1793,8 +1793,9 @@ void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV, StoreInst *SI, // know nothing about the variable's content. DV = UndefValue::get(DV->getType()); ValueAsMetadata *DVAM = ValueAsMetadata::get(DV); - DPValue *NewDPV = new DPValue(DVAM, DIVar, DIExpr, NewLoc.get()); - SI->getParent()->insertDbgRecordBefore(NewDPV, SI->getIterator()); + DbgVariableRecord *NewDVR = + new DbgVariableRecord(DVAM, DIVar, DIExpr, NewLoc.get()); + SI->getParent()->insertDbgRecordBefore(NewDVR, SI->getIterator()); } /// Inserts a llvm.dbg.value intrinsic after a phi that has an associated @@ -1826,26 +1827,27 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, // insertion point. // FIXME: Insert dbg.value markers in the successors when appropriate. if (InsertionPt != BB->end()) { - insertDbgValueOrDPValue(Builder, APN, DIVar, DIExpr, NewLoc, InsertionPt); + insertDbgValueOrDbgVariableRecord(Builder, APN, DIVar, DIExpr, NewLoc, + InsertionPt); } } -void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV, LoadInst *LI, +void llvm::ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, LoadInst *LI, DIBuilder &Builder) { - auto *DIVar = DPV->getVariable(); - auto *DIExpr = DPV->getExpression(); + auto *DIVar = DVR->getVariable(); + auto *DIExpr = DVR->getExpression(); assert(DIVar && "Missing variable"); - if (!valueCoversEntireFragment(LI->getType(), DPV)) { + if (!valueCoversEntireFragment(LI->getType(), DVR)) { // FIXME: If only referring to a part of the variable described by the - // dbg.declare, then we want to insert a DPValue for the corresponding - // fragment. - LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DPValue: " << *DPV - << '\n'); + // dbg.declare, then we want to insert a DbgVariableRecord for the + // corresponding fragment. + LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DbgVariableRecord: " + << *DVR << '\n'); return; } - DebugLoc NewLoc = getDebugValueLoc(DPV); + DebugLoc NewLoc = getDebugValueLoc(DVR); // We are now tracking the loaded value instead of the address. In the // future if multi-location support is added to the IR, it might be @@ -1853,9 +1855,10 @@ void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV, LoadInst *LI, // address in case the alloca can not be elided. assert(UseNewDbgInfoFormat); - // Create a DPValue directly and insert. + // Create a DbgVariableRecord directly and insert. ValueAsMetadata *LIVAM = ValueAsMetadata::get(LI); - DPValue *DV = new DPValue(LIVAM, DIVar, DIExpr, NewLoc.get()); + DbgVariableRecord *DV = + new DbgVariableRecord(LIVAM, DIVar, DIExpr, NewLoc.get()); LI->getParent()->insertDbgRecordAfter(DV, LI); } @@ -1869,34 +1872,35 @@ static bool isArray(AllocaInst *AI) { static bool isStructure(AllocaInst *AI) { return AI->getAllocatedType() && AI->getAllocatedType()->isStructTy(); } -void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV, PHINode *APN, +void llvm::ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, PHINode *APN, DIBuilder &Builder) { - auto *DIVar = DPV->getVariable(); - auto *DIExpr = DPV->getExpression(); + auto *DIVar = DVR->getVariable(); + auto *DIExpr = DVR->getExpression(); assert(DIVar && "Missing variable"); if (PhiHasDebugValue(DIVar, DIExpr, APN)) return; - if (!valueCoversEntireFragment(APN->getType(), DPV)) { + if (!valueCoversEntireFragment(APN->getType(), DVR)) { // FIXME: If only referring to a part of the variable described by the - // dbg.declare, then we want to insert a DPValue for the corresponding - // fragment. - LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DPValue: " << *DPV - << '\n'); + // dbg.declare, then we want to insert a DbgVariableRecord for the + // corresponding fragment. + LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DbgVariableRecord: " + << *DVR << '\n'); return; } BasicBlock *BB = APN->getParent(); auto InsertionPt = BB->getFirstInsertionPt(); - DebugLoc NewLoc = getDebugValueLoc(DPV); + DebugLoc NewLoc = getDebugValueLoc(DVR); // The block may be a catchswitch block, which does not have a valid // insertion point. - // FIXME: Insert DPValue markers in the successors when appropriate. + // FIXME: Insert DbgVariableRecord markers in the successors when appropriate. if (InsertionPt != BB->end()) { - insertDbgValueOrDPValue(Builder, APN, DIVar, DIExpr, NewLoc, InsertionPt); + insertDbgValueOrDbgVariableRecord(Builder, APN, DIVar, DIExpr, NewLoc, + InsertionPt); } } @@ -1906,19 +1910,19 @@ bool llvm::LowerDbgDeclare(Function &F) { bool Changed = false; DIBuilder DIB(*F.getParent(), /*AllowUnresolved*/ false); SmallVector<DbgDeclareInst *, 4> Dbgs; - SmallVector<DPValue *> DPVs; + SmallVector<DbgVariableRecord *> DVRs; for (auto &FI : F) { for (Instruction &BI : FI) { if (auto *DDI = dyn_cast<DbgDeclareInst>(&BI)) Dbgs.push_back(DDI); - for (DPValue &DPV : filterDbgVars(BI.getDbgRecordRange())) { - if (DPV.getType() == DPValue::LocationType::Declare) - DPVs.push_back(&DPV); + for (DbgVariableRecord &DVR : filterDbgVars(BI.getDbgRecordRange())) { + if (DVR.getType() == DbgVariableRecord::LocationType::Declare) + DVRs.push_back(&DVR); } } } - if (Dbgs.empty() && DPVs.empty()) + if (Dbgs.empty() && DVRs.empty()) return Changed; auto LowerOne = [&](auto *DDI) { @@ -1962,8 +1966,9 @@ bool llvm::LowerDbgDeclare(Function &F) { DebugLoc NewLoc = getDebugValueLoc(DDI); auto *DerefExpr = DIExpression::append(DDI->getExpression(), dwarf::DW_OP_deref); - insertDbgValueOrDPValue(DIB, AI, DDI->getVariable(), DerefExpr, - NewLoc, CI->getIterator()); + insertDbgValueOrDbgVariableRecord(DIB, AI, DDI->getVariable(), + DerefExpr, NewLoc, + CI->getIterator()); } } else if (BitCastInst *BI = dyn_cast<BitCastInst>(U)) { if (BI->getType()->isPointerTy()) @@ -1976,7 +1981,7 @@ bool llvm::LowerDbgDeclare(Function &F) { }; for_each(Dbgs, LowerOne); - for_each(DPVs, LowerOne); + for_each(DVRs, LowerOne); if (Changed) for (BasicBlock &BB : F) @@ -1986,35 +1991,39 @@ bool llvm::LowerDbgDeclare(Function &F) { } // RemoveDIs: re-implementation of insertDebugValuesForPHIs, but which pulls the -// debug-info out of the block's DPValues rather than dbg.value intrinsics. -static void insertDPValuesForPHIs(BasicBlock *BB, - SmallVectorImpl<PHINode *> &InsertedPHIs) { - assert(BB && "No BasicBlock to clone DPValue(s) from."); +// debug-info out of the block's DbgVariableRecords rather than dbg.value +// intrinsics. +static void +insertDbgVariableRecordsForPHIs(BasicBlock *BB, + SmallVectorImpl<PHINode *> &InsertedPHIs) { + assert(BB && "No BasicBlock to clone DbgVariableRecord(s) from."); if (InsertedPHIs.size() == 0) return; - // Map existing PHI nodes to their DPValues. - DenseMap<Value *, DPValue *> DbgValueMap; + // Map existing PHI nodes to their DbgVariableRecords. + DenseMap<Value *, DbgVariableRecord *> DbgValueMap; for (auto &I : *BB) { - for (DPValue &DPV : filterDbgVars(I.getDbgRecordRange())) { - for (Value *V : DPV.location_ops()) + for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { + for (Value *V : DVR.location_ops()) if (auto *Loc = dyn_cast_or_null<PHINode>(V)) - DbgValueMap.insert({Loc, &DPV}); + DbgValueMap.insert({Loc, &DVR}); } } if (DbgValueMap.size() == 0) return; - // Map a pair of the destination BB and old DPValue to the new DPValue, - // so that if a DPValue is being rewritten to use more than one of the - // inserted PHIs in the same destination BB, we can update the same DPValue - // with all the new PHIs instead of creating one copy for each. - MapVector<std::pair<BasicBlock *, DPValue *>, DPValue *> NewDbgValueMap; + // Map a pair of the destination BB and old DbgVariableRecord to the new + // DbgVariableRecord, so that if a DbgVariableRecord is being rewritten to use + // more than one of the inserted PHIs in the same destination BB, we can + // update the same DbgVariableRecord with all the new PHIs instead of creating + // one copy for each. + MapVector<std::pair<BasicBlock *, DbgVariableRecord *>, DbgVariableRecord *> + NewDbgValueMap; // Then iterate through the new PHIs and look to see if they use one of the - // previously mapped PHIs. If so, create a new DPValue that will propagate - // the info through the new PHI. If we use more than one new PHI in a single - // destination BB with the same old dbg.value, merge the updates so that we - // get a single new DPValue with all the new PHIs. + // previously mapped PHIs. If so, create a new DbgVariableRecord that will + // propagate the info through the new PHI. If we use more than one new PHI in + // a single destination BB with the same old dbg.value, merge the updates so + // that we get a single new DbgVariableRecord with all the new PHIs. for (auto PHI : InsertedPHIs) { BasicBlock *Parent = PHI->getParent(); // Avoid inserting a debug-info record into an EH block. @@ -2023,13 +2032,13 @@ static void insertDPValuesForPHIs(BasicBlock *BB, for (auto VI : PHI->operand_values()) { auto V = DbgValueMap.find(VI); if (V != DbgValueMap.end()) { - DPValue *DbgII = cast<DPValue>(V->second); + DbgVariableRecord *DbgII = cast<DbgVariableRecord>(V->second); auto NewDI = NewDbgValueMap.find({Parent, DbgII}); if (NewDI == NewDbgValueMap.end()) { - DPValue *NewDbgII = DbgII->clone(); + DbgVariableRecord *NewDbgII = DbgII->clone(); NewDI = NewDbgValueMap.insert({{Parent, DbgII}, NewDbgII}).first; } - DPValue *NewDbgII = NewDI->second; + DbgVariableRecord *NewDbgII = NewDI->second; // If PHI contains VI as an operand more than once, we may // replaced it in NewDbgII; confirm that it is present. if (is_contained(NewDbgII->location_ops(), VI)) @@ -2037,10 +2046,10 @@ static void insertDPValuesForPHIs(BasicBlock *BB, } } } - // Insert the new DPValues into their destination blocks. + // Insert the new DbgVariableRecords into their destination blocks. for (auto DI : NewDbgValueMap) { BasicBlock *Parent = DI.first.first; - DPValue *NewDbgII = DI.second; + DbgVariableRecord *NewDbgII = DI.second; auto InsertionPt = Parent->getFirstInsertionPt(); assert(InsertionPt != Parent->end() && "Ill-formed basic block"); @@ -2055,7 +2064,7 @@ void llvm::insertDebugValuesForPHIs(BasicBlock *BB, if (InsertedPHIs.size() == 0) return; - insertDPValuesForPHIs(BB, InsertedPHIs); + insertDbgVariableRecordsForPHIs(BB, InsertedPHIs); // Map existing PHI nodes to their dbg.values. ValueToValueMapTy DbgValueMap; @@ -2117,7 +2126,7 @@ bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress, DIBuilder &Builder, uint8_t DIExprFlags, int Offset) { TinyPtrVector<DbgDeclareInst *> DbgDeclares = findDbgDeclares(Address); - TinyPtrVector<DPValue *> DPVDeclares = findDPVDeclares(Address); + TinyPtrVector<DbgVariableRecord *> DVRDeclares = findDVRDeclares(Address); auto ReplaceOne = [&](auto *DII) { assert(DII->getVariable() && "Missing variable"); @@ -2128,21 +2137,22 @@ bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress, }; for_each(DbgDeclares, ReplaceOne); - for_each(DPVDeclares, ReplaceOne); + for_each(DVRDeclares, ReplaceOne); - return !DbgDeclares.empty() || !DPVDeclares.empty(); + return !DbgDeclares.empty() || !DVRDeclares.empty(); } static void updateOneDbgValueForAlloca(const DebugLoc &Loc, DILocalVariable *DIVar, DIExpression *DIExpr, Value *NewAddress, - DbgValueInst *DVI, DPValue *DPV, + DbgValueInst *DVI, + DbgVariableRecord *DVR, DIBuilder &Builder, int Offset) { assert(DIVar && "Missing variable"); - // This is an alloca-based dbg.value/DPValue. The first thing it should do - // with the alloca pointer is dereference it. Otherwise we don't know how to - // handle it and give up. + // This is an alloca-based dbg.value/DbgVariableRecord. The first thing it + // should do with the alloca pointer is dereference it. Otherwise we don't + // know how to handle it and give up. if (!DIExpr || DIExpr->getNumElements() < 1 || DIExpr->getElement(0) != dwarf::DW_OP_deref) return; @@ -2155,16 +2165,16 @@ static void updateOneDbgValueForAlloca(const DebugLoc &Loc, DVI->setExpression(DIExpr); DVI->replaceVariableLocationOp(0u, NewAddress); } else { - assert(DPV); - DPV->setExpression(DIExpr); - DPV->replaceVariableLocationOp(0u, NewAddress); + assert(DVR); + DVR->setExpression(DIExpr); + DVR->replaceVariableLocationOp(0u, NewAddress); } } void llvm::replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress, DIBuilder &Builder, int Offset) { SmallVector<DbgValueInst *, 1> DbgUsers; - SmallVector<DPValue *, 1> DPUsers; + SmallVector<DbgVariableRecord *, 1> DPUsers; findDbgValues(DbgUsers, AI, &DPUsers); // Attempt to replace dbg.values that use this alloca. @@ -2173,18 +2183,18 @@ void llvm::replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress, DVI->getExpression(), NewAllocaAddress, DVI, nullptr, Builder, Offset); - // Replace any DPValues that use this alloca. - for (DPValue *DPV : DPUsers) - updateOneDbgValueForAlloca(DPV->getDebugLoc(), DPV->getVariable(), - DPV->getExpression(), NewAllocaAddress, nullptr, - DPV, Builder, Offset); + // Replace any DbgVariableRecords that use this alloca. + for (DbgVariableRecord *DVR : DPUsers) + updateOneDbgValueForAlloca(DVR->getDebugLoc(), DVR->getVariable(), + DVR->getExpression(), NewAllocaAddress, nullptr, + DVR, Builder, Offset); } /// Where possible to salvage debug information for \p I do so. /// If not possible mark undef. void llvm::salvageDebugInfo(Instruction &I) { SmallVector<DbgVariableIntrinsic *, 1> DbgUsers; - SmallVector<DPValue *, 1> DPUsers; + SmallVector<DbgVariableRecord *, 1> DPUsers; findDbgUsers(DbgUsers, &I, &DPUsers); salvageDebugInfoForDbgValues(I, DbgUsers, DPUsers); } @@ -2224,7 +2234,7 @@ template <typename T> static void salvageDbgAssignAddress(T *Assign) { void llvm::salvageDebugInfoForDbgValues( Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers, - ArrayRef<DPValue *> DPUsers) { + ArrayRef<DbgVariableRecord *> DPUsers) { // These are arbitrary chosen limits on the maximum number of values and the // maximum size of a debug expression we can salvage up to, used for // performance reasons. @@ -2290,67 +2300,68 @@ void llvm::salvageDebugInfoForDbgValues( LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n'); Salvaged = true; } - // Duplicate of above block for DPValues. - for (auto *DPV : DPUsers) { - if (DPV->isDbgAssign()) { - if (DPV->getAddress() == &I) { - salvageDbgAssignAddress(DPV); + // Duplicate of above block for DbgVariableRecords. + for (auto *DVR : DPUsers) { + if (DVR->isDbgAssign()) { + if (DVR->getAddress() == &I) { + salvageDbgAssignAddress(DVR); Salvaged = true; } - if (DPV->getValue() != &I) + if (DVR->getValue() != &I) continue; } // Do not add DW_OP_stack_value for DbgDeclare and DbgAddr, because they // are implicitly pointing out the value as a DWARF memory location // description. - bool StackValue = DPV->getType() != DPValue::LocationType::Declare; - auto DPVLocation = DPV->location_ops(); + bool StackValue = + DVR->getType() != DbgVariableRecord::LocationType::Declare; + auto DVRLocation = DVR->location_ops(); assert( - is_contained(DPVLocation, &I) && + is_contained(DVRLocation, &I) && "DbgVariableIntrinsic must use salvaged instruction as its location"); SmallVector<Value *, 4> AdditionalValues; - // 'I' may appear more than once in DPV's location ops, and each use of 'I' + // 'I' may appear more than once in DVR's location ops, and each use of 'I' // must be updated in the DIExpression and potentially have additional // values added; thus we call salvageDebugInfoImpl for each 'I' instance in - // DPVLocation. + // DVRLocation. Value *Op0 = nullptr; - DIExpression *SalvagedExpr = DPV->getExpression(); - auto LocItr = find(DPVLocation, &I); - while (SalvagedExpr && LocItr != DPVLocation.end()) { + DIExpression *SalvagedExpr = DVR->getExpression(); + auto LocItr = find(DVRLocation, &I); + while (SalvagedExpr && LocItr != DVRLocation.end()) { SmallVector<uint64_t, 16> Ops; - unsigned LocNo = std::distance(DPVLocation.begin(), LocItr); + unsigned LocNo = std::distance(DVRLocation.begin(), LocItr); uint64_t CurrentLocOps = SalvagedExpr->getNumLocationOperands(); Op0 = salvageDebugInfoImpl(I, CurrentLocOps, Ops, AdditionalValues); if (!Op0) break; SalvagedExpr = DIExpression::appendOpsToArg(SalvagedExpr, Ops, LocNo, StackValue); - LocItr = std::find(++LocItr, DPVLocation.end(), &I); + LocItr = std::find(++LocItr, DVRLocation.end(), &I); } // salvageDebugInfoImpl should fail on examining the first element of // DbgUsers, or none of them. if (!Op0) break; - DPV->replaceVariableLocationOp(&I, Op0); + DVR->replaceVariableLocationOp(&I, Op0); bool IsValidSalvageExpr = SalvagedExpr->getNumElements() <= MaxExpressionSize; if (AdditionalValues.empty() && IsValidSalvageExpr) { - DPV->setExpression(SalvagedExpr); - } else if (DPV->getType() != DPValue::LocationType::Declare && + DVR->setExpression(SalvagedExpr); + } else if (DVR->getType() != DbgVariableRecord::LocationType::Declare && IsValidSalvageExpr && - DPV->getNumVariableLocationOps() + AdditionalValues.size() <= + DVR->getNumVariableLocationOps() + AdditionalValues.size() <= MaxDebugArgs) { - DPV->addVariableLocationOps(AdditionalValues, SalvagedExpr); + DVR->addVariableLocationOps(AdditionalValues, SalvagedExpr); } else { // Do not salvage using DIArgList for dbg.addr/dbg.declare, as it is // currently only valid for stack value expressions. // Also do not salvage if the resulting DIArgList would contain an // unreasonably large number of values. - DPV->setKillLocation(); + DVR->setKillLocation(); } - LLVM_DEBUG(dbgs() << "SALVAGE: " << DPV << '\n'); + LLVM_DEBUG(dbgs() << "SALVAGE: " << DVR << '\n'); Salvaged = true; } @@ -2360,8 +2371,8 @@ void llvm::salvageDebugInfoForDbgValues( for (auto *DII : DbgUsers) DII->setKillLocation(); - for (auto *DPV : DPUsers) - DPV->setKillLocation(); + for (auto *DVR : DPUsers) + DVR->setKillLocation(); } Value *getSalvageOpsForGEP(GetElementPtrInst *GEP, const DataLayout &DL, @@ -2577,10 +2588,10 @@ using DbgValReplacement = std::optional<DIExpression *>; static bool rewriteDebugUsers( Instruction &From, Value &To, Instruction &DomPoint, DominatorTree &DT, function_ref<DbgValReplacement(DbgVariableIntrinsic &DII)> RewriteExpr, - function_ref<DbgValReplacement(DPValue &DPV)> RewriteDPVExpr) { + function_ref<DbgValReplacement(DbgVariableRecord &DVR)> RewriteDVRExpr) { // Find debug users of From. SmallVector<DbgVariableIntrinsic *, 1> Users; - SmallVector<DPValue *, 1> DPUsers; + SmallVector<DbgVariableRecord *, 1> DPUsers; findDbgUsers(Users, &From, &DPUsers); if (Users.empty() && DPUsers.empty()) return false; @@ -2589,7 +2600,7 @@ static bool rewriteDebugUsers( bool Changed = false; SmallPtrSet<DbgVariableIntrinsic *, 1> UndefOrSalvage; - SmallPtrSet<DPValue *, 1> UndefOrSalvageDPV; + SmallPtrSet<DbgVariableRecord *, 1> UndefOrSalvageDVR; if (isa<Instruction>(&To)) { bool DomPointAfterFrom = From.getNextNonDebugInstruction() == &DomPoint; @@ -2608,22 +2619,22 @@ static bool rewriteDebugUsers( } } - // DPValue implementation of the above. - for (auto *DPV : DPUsers) { - Instruction *MarkedInstr = DPV->getMarker()->MarkedInstr; + // DbgVariableRecord implementation of the above. + for (auto *DVR : DPUsers) { + Instruction *MarkedInstr = DVR->getMarker()->MarkedInstr; Instruction *NextNonDebug = MarkedInstr; // The next instruction might still be a dbg.declare, skip over it. if (isa<DbgVariableIntrinsic>(NextNonDebug)) NextNonDebug = NextNonDebug->getNextNonDebugInstruction(); if (DomPointAfterFrom && NextNonDebug == &DomPoint) { - LLVM_DEBUG(dbgs() << "MOVE: " << *DPV << '\n'); - DPV->removeFromParent(); + LLVM_DEBUG(dbgs() << "MOVE: " << *DVR << '\n'); + DVR->removeFromParent(); // Ensure there's a marker. - DomPoint.getParent()->insertDbgRecordAfter(DPV, &DomPoint); + DomPoint.getParent()->insertDbgRecordAfter(DVR, &DomPoint); Changed = true; } else if (!DT.dominates(&DomPoint, MarkedInstr)) { - UndefOrSalvageDPV.insert(DPV); + UndefOrSalvageDVR.insert(DVR); } } } @@ -2633,30 +2644,30 @@ static bool rewriteDebugUsers( if (UndefOrSalvage.count(DII)) continue; - DbgValReplacement DVR = RewriteExpr(*DII); - if (!DVR) + DbgValReplacement DVRepl = RewriteExpr(*DII); + if (!DVRepl) continue; DII->replaceVariableLocationOp(&From, &To); - DII->setExpression(*DVR); + DII->setExpression(*DVRepl); LLVM_DEBUG(dbgs() << "REWRITE: " << *DII << '\n'); Changed = true; } - for (auto *DPV : DPUsers) { - if (UndefOrSalvageDPV.count(DPV)) + for (auto *DVR : DPUsers) { + if (UndefOrSalvageDVR.count(DVR)) continue; - DbgValReplacement DVR = RewriteDPVExpr(*DPV); - if (!DVR) + DbgValReplacement DVRepl = RewriteDVRExpr(*DVR); + if (!DVRepl) continue; - DPV->replaceVariableLocationOp(&From, &To); - DPV->setExpression(*DVR); - LLVM_DEBUG(dbgs() << "REWRITE: " << DPV << '\n'); + DVR->replaceVariableLocationOp(&From, &To); + DVR->setExpression(*DVRepl); + LLVM_DEBUG(dbgs() << "REWRITE: " << DVR << '\n'); Changed = true; } - if (!UndefOrSalvage.empty() || !UndefOrSalvageDPV.empty()) { + if (!UndefOrSalvage.empty() || !UndefOrSalvageDVR.empty()) { // Try to salvage the remaining debug users. salvageDebugInfo(From); Changed = true; @@ -2704,15 +2715,15 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To, auto Identity = [&](DbgVariableIntrinsic &DII) -> DbgValReplacement { return DII.getExpression(); }; - auto IdentityDPV = [&](DPValue &DPV) -> DbgValReplacement { - return DPV.getExpression(); + auto IdentityDVR = [&](DbgVariableRecord &DVR) -> DbgValReplacement { + return DVR.getExpression(); }; // Handle no-op conversions. Module &M = *From.getModule(); const DataLayout &DL = M.getDataLayout(); if (isBitCastSemanticsPreserving(DL, FromTy, ToTy)) - return rewriteDebugUsers(From, To, DomPoint, DT, Identity, IdentityDPV); + return rewriteDebugUsers(From, To, DomPoint, DT, Identity, IdentityDVR); // Handle integer-to-integer widening and narrowing. // FIXME: Use DW_OP_convert when it's available everywhere. @@ -2724,7 +2735,7 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To, // When the width of the result grows, assume that a debugger will only // access the low `FromBits` bits when inspecting the source variable. if (FromBits < ToBits) - return rewriteDebugUsers(From, To, DomPoint, DT, Identity, IdentityDPV); + return rewriteDebugUsers(From, To, DomPoint, DT, Identity, IdentityDVR); // The width of the result has shrunk. Use sign/zero extension to describe // the source variable's high bits. @@ -2740,10 +2751,10 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To, return DIExpression::appendExt(DII.getExpression(), ToBits, FromBits, Signed); }; - // RemoveDIs: duplicate implementation working on DPValues rather than on - // dbg.value intrinsics. - auto SignOrZeroExtDPV = [&](DPValue &DPV) -> DbgValReplacement { - DILocalVariable *Var = DPV.getVariable(); + // RemoveDIs: duplicate implementation working on DbgVariableRecords rather + // than on dbg.value intrinsics. + auto SignOrZeroExtDVR = [&](DbgVariableRecord &DVR) -> DbgValReplacement { + DILocalVariable *Var = DVR.getVariable(); // Without knowing signedness, sign/zero extension isn't possible. auto Signedness = Var->getSignedness(); @@ -2751,11 +2762,11 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To, return std::nullopt; bool Signed = *Signedness == DIBasicType::Signedness::Signed; - return DIExpression::appendExt(DPV.getExpression(), ToBits, FromBits, + return DIExpression::appendExt(DVR.getExpression(), ToBits, FromBits, Signed); }; return rewriteDebugUsers(From, To, DomPoint, DT, SignOrZeroExt, - SignOrZeroExtDPV); + SignOrZeroExtDVR); } // TODO: Floating-point conversions, vectors. @@ -2795,8 +2806,8 @@ llvm::removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB) { if (!Inst->use_empty() && !Inst->getType()->isTokenTy()) Inst->replaceAllUsesWith(PoisonValue::get(Inst->getType())); if (Inst->isEHPad() || Inst->getType()->isTokenTy()) { - // EHPads can't have DPValues attached to them, but it might be possible - // for things with token type. + // EHPads can't have DbgVariableRecords attached to them, but it might be + // possible for things with token type. Inst->dropDbgRecords(); EndInst = Inst; continue; @@ -3544,12 +3555,12 @@ void llvm::copyRangeMetadata(const DataLayout &DL, const LoadInst &OldLI, void llvm::dropDebugUsers(Instruction &I) { SmallVector<DbgVariableIntrinsic *, 1> DbgUsers; - SmallVector<DPValue *, 1> DPUsers; + SmallVector<DbgVariableRecord *, 1> DPUsers; findDbgUsers(DbgUsers, &I, &DPUsers); for (auto *DII : DbgUsers) DII->eraseFromParent(); - for (auto *DPV : DPUsers) - DPV->eraseFromParent(); + for (auto *DVR : DPUsers) + DVR->eraseFromParent(); } void llvm::hoistAllInstructionsInto(BasicBlock *DomBlock, Instruction *InsertPt, diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp index 980ecf06c055..4470c5af870a 100644 --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -159,8 +159,8 @@ static void RewriteUsesOfClonedInstructions(BasicBlock *OrigHeader, // Replace MetadataAsValue(ValueAsMetadata(OrigHeaderVal)) uses in debug // intrinsics. SmallVector<DbgValueInst *, 1> DbgValues; - SmallVector<DPValue *, 1> DPValues; - llvm::findDbgValues(DbgValues, OrigHeaderVal, &DPValues); + SmallVector<DbgVariableRecord *, 1> DbgVariableRecords; + llvm::findDbgValues(DbgValues, OrigHeaderVal, &DbgVariableRecords); for (auto &DbgValue : DbgValues) { // The original users in the OrigHeader are already using the original // definitions. @@ -183,11 +183,11 @@ static void RewriteUsesOfClonedInstructions(BasicBlock *OrigHeader, } // RemoveDIs: duplicate implementation for non-instruction debug-info - // storage in DPValues. - for (DPValue *DPV : DPValues) { + // storage in DbgVariableRecords. + for (DbgVariableRecord *DVR : DbgVariableRecords) { // The original users in the OrigHeader are already using the original // definitions. - BasicBlock *UserBB = DPV->getMarker()->getParent(); + BasicBlock *UserBB = DVR->getMarker()->getParent(); if (UserBB == OrigHeader) continue; @@ -202,7 +202,7 @@ static void RewriteUsesOfClonedInstructions(BasicBlock *OrigHeader, NewVal = SSA.GetValueInMiddleOfBlock(UserBB); else NewVal = UndefValue::get(OrigHeaderVal->getType()); - DPV->replaceVariableLocationOp(OrigHeaderVal, NewVal); + DVR->replaceVariableLocationOp(OrigHeaderVal, NewVal); } } } @@ -552,20 +552,22 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { for (Instruction &I : llvm::drop_begin(llvm::reverse(*OrigPreheader))) { if (auto *DII = dyn_cast<DbgVariableIntrinsic>(&I)) { DbgIntrinsics.insert(makeHash(DII)); - // Until RemoveDIs supports dbg.declares in DPValue format, we'll need - // to collect DPValues attached to any other debug intrinsics. - for (const DPValue &DPV : filterDbgVars(DII->getDbgRecordRange())) - DbgIntrinsics.insert(makeHash(&DPV)); + // Until RemoveDIs supports dbg.declares in DbgVariableRecord format, + // we'll need to collect DbgVariableRecords attached to any other debug + // intrinsics. + for (const DbgVariableRecord &DVR : + filterDbgVars(DII->getDbgRecordRange())) + DbgIntrinsics.insert(makeHash(&DVR)); } else { break; } } - // Build DPValue hashes for DPValues attached to the terminator, which isn't - // considered in the loop above. - for (const DPValue &DPV : + // Build DbgVariableRecord hashes for DbgVariableRecords attached to the + // terminator, which isn't considered in the loop above. + for (const DbgVariableRecord &DVR : filterDbgVars(OrigPreheader->getTerminator()->getDbgRecordRange())) - DbgIntrinsics.insert(makeHash(&DPV)); + DbgIntrinsics.insert(makeHash(&DVR)); // Remember the local noalias scope declarations in the header. After the // rotation, they must be duplicated and the scope must be cloned. This @@ -627,13 +629,14 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { !NextDbgInsts.empty()) { auto DbgValueRange = LoopEntryBranch->cloneDebugInfoFrom(Inst, NextDbgInsts.begin()); - RemapDPValueRange(M, DbgValueRange, ValueMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + RemapDbgVariableRecordRange(M, DbgValueRange, ValueMap, + RF_NoModuleLevelChanges | + RF_IgnoreMissingLocals); // Erase anything we've seen before. - for (DPValue &DPV : + for (DbgVariableRecord &DVR : make_early_inc_range(filterDbgVars(DbgValueRange))) - if (DbgIntrinsics.count(makeHash(&DPV))) - DPV.eraseFromParent(); + if (DbgIntrinsics.count(makeHash(&DVR))) + DVR.eraseFromParent(); } NextDbgInsts = I->getDbgRecordRange(); @@ -653,13 +656,15 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { if (LoopEntryBranch->getParent()->IsNewDbgInfoFormat && !NextDbgInsts.empty()) { auto Range = C->cloneDebugInfoFrom(Inst, NextDbgInsts.begin()); - RemapDPValueRange(M, Range, ValueMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + RemapDbgVariableRecordRange(M, Range, ValueMap, + RF_NoModuleLevelChanges | + RF_IgnoreMissingLocals); NextDbgInsts = DPMarker::getEmptyDbgRecordRange(); // Erase anything we've seen before. - for (DPValue &DPV : make_early_inc_range(filterDbgVars(Range))) - if (DbgIntrinsics.count(makeHash(&DPV))) - DPV.eraseFromParent(); + for (DbgVariableRecord &DVR : + make_early_inc_range(filterDbgVars(Range))) + if (DbgIntrinsics.count(makeHash(&DVR))) + DVR.eraseFromParent(); } // Eagerly remap the operands of the instruction. diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index ecd76b7c1fbf..2d5b5f967ffb 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -917,8 +917,9 @@ bool llvm::UnrollRuntimeLoopRemainder( for (Instruction &I : *BB) { RemapInstruction(&I, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); - RemapDPValueRange(M, I.getDbgRecordRange(), VMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + RemapDbgVariableRecordRange(M, I.getDbgRecordRange(), VMap, + RF_NoModuleLevelChanges | + RF_IgnoreMissingLocals); } } diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index 0748b9d18103..73c5d6367822 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -605,7 +605,7 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE, // Use a map to unique and a vector to guarantee deterministic ordering. llvm::SmallDenseSet<DebugVariable, 4> DeadDebugSet; llvm::SmallVector<DbgVariableIntrinsic *, 4> DeadDebugInst; - llvm::SmallVector<DPValue *, 4> DeadDPValues; + llvm::SmallVector<DbgVariableRecord *, 4> DeadDbgVariableRecords; if (ExitBlock) { // Given LCSSA form is satisfied, we should not have users of instructions @@ -631,17 +631,17 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE, U.set(Poison); } - // RemoveDIs: do the same as below for DPValues. + // RemoveDIs: do the same as below for DbgVariableRecords. if (Block->IsNewDbgInfoFormat) { - for (DPValue &DPV : llvm::make_early_inc_range( + for (DbgVariableRecord &DVR : llvm::make_early_inc_range( filterDbgVars(I.getDbgRecordRange()))) { - DebugVariable Key(DPV.getVariable(), DPV.getExpression(), - DPV.getDebugLoc().get()); + DebugVariable Key(DVR.getVariable(), DVR.getExpression(), + DVR.getDebugLoc().get()); if (!DeadDebugSet.insert(Key).second) continue; - // Unlinks the DPV from it's container, for later insertion. - DPV.removeFromParent(); - DeadDPValues.push_back(&DPV); + // Unlinks the DVR from it's container, for later insertion. + DVR.removeFromParent(); + DeadDbgVariableRecords.push_back(&DVR); } } @@ -673,11 +673,11 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE, DVI->moveBefore(*ExitBlock, InsertDbgValueBefore); // Due to the "head" bit in BasicBlock::iterator, we're going to insert - // each DPValue right at the start of the block, wheras dbg.values would be - // repeatedly inserted before the first instruction. To replicate this - // behaviour, do it backwards. - for (DPValue *DPV : llvm::reverse(DeadDPValues)) - ExitBlock->insertDbgRecordBefore(DPV, InsertDbgValueBefore); + // each DbgVariableRecord right at the start of the block, wheras dbg.values + // would be repeatedly inserted before the first instruction. To replicate + // this behaviour, do it backwards. + for (DbgVariableRecord *DVR : llvm::reverse(DeadDbgVariableRecords)) + ExitBlock->insertDbgRecordBefore(DVR, InsertDbgValueBefore); } // Remove the block from the reference counting scheme, so that we can diff --git a/llvm/lib/Transforms/Utils/MemoryOpRemark.cpp b/llvm/lib/Transforms/Utils/MemoryOpRemark.cpp index d671a9373bf0..8f55d7bbd318 100644 --- a/llvm/lib/Transforms/Utils/MemoryOpRemark.cpp +++ b/llvm/lib/Transforms/Utils/MemoryOpRemark.cpp @@ -332,7 +332,7 @@ void MemoryOpRemark::visitVariable(const Value *V, } }; for_each(findDbgDeclares(const_cast<Value *>(V)), FindDI); - for_each(findDPVDeclares(const_cast<Value *>(V)), FindDI); + for_each(findDVRDeclares(const_cast<Value *>(V)), FindDI); if (FoundDI) { assert(!Result.empty()); diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp index cab19586a551..a3858a7985ce 100644 --- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp +++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp @@ -110,21 +110,21 @@ Instruction *getUntagLocationIfFunctionExit(Instruction &Inst) { void StackInfoBuilder::visit(Instruction &Inst) { // Visit non-intrinsic debug-info records attached to Inst. - for (DPValue &DPV : filterDbgVars(Inst.getDbgRecordRange())) { + for (DbgVariableRecord &DVR : filterDbgVars(Inst.getDbgRecordRange())) { auto AddIfInteresting = [&](Value *V) { if (auto *AI = dyn_cast_or_null<AllocaInst>(V)) { if (!isInterestingAlloca(*AI)) return; AllocaInfo &AInfo = Info.AllocasToInstrument[AI]; - auto &DPVVec = AInfo.DbgVariableRecords; - if (DPVVec.empty() || DPVVec.back() != &DPV) - DPVVec.push_back(&DPV); + auto &DVRVec = AInfo.DbgVariableRecords; + if (DVRVec.empty() || DVRVec.back() != &DVR) + DVRVec.push_back(&DVR); } }; - for_each(DPV.location_ops(), AddIfInteresting); - if (DPV.isDbgAssign()) - AddIfInteresting(DPV.getAddress()); + for_each(DVR.location_ops(), AddIfInteresting); + if (DVR.isDbgAssign()) + AddIfInteresting(DVR.getAddress()); } if (CallInst *CI = dyn_cast<CallInst>(&Inst)) { diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp index b462803bad38..adcf161b313b 100644 --- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -104,11 +104,13 @@ namespace { static void createDebugValue(DIBuilder &DIB, Value *NewValue, DILocalVariable *Variable, DIExpression *Expression, const DILocation *DI, - DPValue *InsertBefore) { - // FIXME: Merge these two functions now that DIBuilder supports DPValues. - // We neeed the API to accept DPValues as an insert point for that to work. + DbgVariableRecord *InsertBefore) { + // FIXME: Merge these two functions now that DIBuilder supports + // DbgVariableRecords. We neeed the API to accept DbgVariableRecords as an + // insert point for that to work. (void)DIB; - DPValue::createDPValue(NewValue, Variable, Expression, DI, *InsertBefore); + DbgVariableRecord::createDbgVariableRecord(NewValue, Variable, Expression, DI, + *InsertBefore); } static void createDebugValue(DIBuilder &DIB, Value *NewValue, DILocalVariable *Variable, @@ -123,7 +125,7 @@ class AssignmentTrackingInfo { /// fragment. (i.e. not be a comprehensive set if there are multiple /// dbg.assigns for one variable fragment). SmallVector<DbgVariableIntrinsic *> DbgAssigns; - SmallVector<DPValue *> DPVAssigns; + SmallVector<DbgVariableRecord *> DVRAssigns; public: void init(AllocaInst *AI) { @@ -132,21 +134,21 @@ public: if (Vars.insert(DebugVariable(DAI)).second) DbgAssigns.push_back(DAI); } - for (DPValue *DPV : at::getDPVAssignmentMarkers(AI)) { - if (Vars.insert(DebugVariable(DPV)).second) - DPVAssigns.push_back(DPV); + for (DbgVariableRecord *DVR : at::getDVRAssignmentMarkers(AI)) { + if (Vars.insert(DebugVariable(DVR)).second) + DVRAssigns.push_back(DVR); } } /// Update assignment tracking debug info given for the to-be-deleted store /// \p ToDelete that stores to this alloca. - void - updateForDeletedStore(StoreInst *ToDelete, DIBuilder &DIB, - SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete, - SmallSet<DPValue *, 8> *DPVAssignsToDelete) const { + void updateForDeletedStore( + StoreInst *ToDelete, DIBuilder &DIB, + SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete, + SmallSet<DbgVariableRecord *, 8> *DVRAssignsToDelete) const { // There's nothing to do if the alloca doesn't have any variables using // assignment tracking. - if (DbgAssigns.empty() && DPVAssigns.empty()) + if (DbgAssigns.empty() && DVRAssigns.empty()) return; // Insert a dbg.value where the linked dbg.assign is and remember to delete @@ -165,8 +167,8 @@ public: }; for (auto *Assign : at::getAssignmentMarkers(ToDelete)) InsertValueForAssign(Assign, DbgAssignsToDelete); - for (auto *Assign : at::getDPVAssignmentMarkers(ToDelete)) - InsertValueForAssign(Assign, DPVAssignsToDelete); + for (auto *Assign : at::getDVRAssignmentMarkers(ToDelete)) + InsertValueForAssign(Assign, DVRAssignsToDelete); // It's possible for variables using assignment tracking to have no // dbg.assign linked to this store. These are variables in DbgAssigns that @@ -182,7 +184,7 @@ public: ConvertDebugDeclareToDebugValue(Assign, ToDelete, DIB); }; for_each(DbgAssigns, ConvertUnlinkedAssignToValue); - for_each(DPVAssigns, ConvertUnlinkedAssignToValue); + for_each(DVRAssigns, ConvertUnlinkedAssignToValue); } /// Update assignment tracking debug info given for the newly inserted PHI \p @@ -193,20 +195,20 @@ public: // debug-phi. for (auto *DAI : DbgAssigns) ConvertDebugDeclareToDebugValue(DAI, NewPhi, DIB); - for (auto *DPV : DPVAssigns) - ConvertDebugDeclareToDebugValue(DPV, NewPhi, DIB); + for (auto *DVR : DVRAssigns) + ConvertDebugDeclareToDebugValue(DVR, NewPhi, DIB); } void clear() { DbgAssigns.clear(); - DPVAssigns.clear(); + DVRAssigns.clear(); } - bool empty() { return DbgAssigns.empty() && DPVAssigns.empty(); } + bool empty() { return DbgAssigns.empty() && DVRAssigns.empty(); } }; struct AllocaInfo { using DbgUserVec = SmallVector<DbgVariableIntrinsic *, 1>; - using DPUserVec = SmallVector<DPValue *, 1>; + using DPUserVec = SmallVector<DbgVariableRecord *, 1>; SmallVector<BasicBlock *, 32> DefiningBlocks; SmallVector<BasicBlock *, 32> UsingBlocks; @@ -262,7 +264,7 @@ struct AllocaInfo { } } DbgUserVec AllDbgUsers; - SmallVector<DPValue *> AllDPUsers; + SmallVector<DbgVariableRecord *> AllDPUsers; findDbgUsers(AllDbgUsers, AI, &AllDPUsers); std::copy_if(AllDbgUsers.begin(), AllDbgUsers.end(), std::back_inserter(DbgUsers), [](DbgVariableIntrinsic *DII) { @@ -270,7 +272,7 @@ struct AllocaInfo { }); std::copy_if(AllDPUsers.begin(), AllDPUsers.end(), std::back_inserter(DPUsers), - [](DPValue *DPV) { return !DPV->isDbgAssign(); }); + [](DbgVariableRecord *DVR) { return !DVR->isDbgAssign(); }); AssignmentTracking.init(AI); } }; @@ -378,7 +380,7 @@ struct PromoteMem2Reg { /// A set of dbg.assigns to delete because they've been demoted to /// dbg.values. Call cleanUpDbgAssigns to delete them. SmallSet<DbgAssignIntrinsic *, 8> DbgAssignsToDelete; - SmallSet<DPValue *, 8> DPVAssignsToDelete; + SmallSet<DbgVariableRecord *, 8> DVRAssignsToDelete; /// The set of basic blocks the renamer has already visited. SmallPtrSet<BasicBlock *, 16> Visited; @@ -428,9 +430,9 @@ private: for (auto *DAI : DbgAssignsToDelete) DAI->eraseFromParent(); DbgAssignsToDelete.clear(); - for (auto *DPV : DPVAssignsToDelete) - DPV->eraseFromParent(); - DPVAssignsToDelete.clear(); + for (auto *DVR : DVRAssignsToDelete) + DVR->eraseFromParent(); + DVRAssignsToDelete.clear(); } }; @@ -508,7 +510,7 @@ rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI, const DataLayout &DL, DominatorTree &DT, AssumptionCache *AC, SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete, - SmallSet<DPValue *, 8> *DPVAssignsToDelete) { + SmallSet<DbgVariableRecord *, 8> *DVRAssignsToDelete) { StoreInst *OnlyStore = Info.OnlyStore; bool StoringGlobalVal = !isa<Instruction>(OnlyStore->getOperand(0)); BasicBlock *StoreBB = OnlyStore->getParent(); @@ -569,7 +571,7 @@ rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI, DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false); // Update assignment tracking info for the store we're going to delete. Info.AssignmentTracking.updateForDeletedStore( - Info.OnlyStore, DIB, DbgAssignsToDelete, DPVAssignsToDelete); + Info.OnlyStore, DIB, DbgAssignsToDelete, DVRAssignsToDelete); // Record debuginfo for the store and remove the declaration's // debuginfo. @@ -618,7 +620,7 @@ promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info, LargeBlockInfo &LBI, const DataLayout &DL, DominatorTree &DT, AssumptionCache *AC, SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete, - SmallSet<DPValue *, 8> *DPVAssignsToDelete) { + SmallSet<DbgVariableRecord *, 8> *DVRAssignsToDelete) { // The trickiest case to handle is when we have large blocks. Because of this, // this code is optimized assuming that large blocks happen. This does not // significantly pessimize the small block case. This uses LargeBlockInfo to @@ -683,7 +685,7 @@ promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info, StoreInst *SI = cast<StoreInst>(AI->user_back()); // Update assignment tracking info for the store we're going to delete. Info.AssignmentTracking.updateForDeletedStore(SI, DIB, DbgAssignsToDelete, - DPVAssignsToDelete); + DVRAssignsToDelete); // Record debuginfo for the store before removing it. auto DbgUpdateForStore = [&](auto &Container) { for (auto *DbgItem : Container) { @@ -755,7 +757,7 @@ void PromoteMem2Reg::run() { // it that are directly dominated by the definition with the value stored. if (Info.DefiningBlocks.size() == 1) { if (rewriteSingleStoreAlloca(AI, Info, LBI, SQ.DL, DT, AC, - &DbgAssignsToDelete, &DPVAssignsToDelete)) { + &DbgAssignsToDelete, &DVRAssignsToDelete)) { // The alloca has been processed, move on. RemoveFromAllocasList(AllocaNum); ++NumSingleStore; @@ -767,7 +769,7 @@ void PromoteMem2Reg::run() { // linear sweep over the block to eliminate it. if (Info.OnlyUsedInOneBlock && promoteSingleBlockAlloca(AI, Info, LBI, SQ.DL, DT, AC, - &DbgAssignsToDelete, &DPVAssignsToDelete)) { + &DbgAssignsToDelete, &DVRAssignsToDelete)) { // The alloca has been processed, move on. RemoveFromAllocasList(AllocaNum); continue; @@ -1174,7 +1176,7 @@ NextIteration: // Record debuginfo for the store before removing it. IncomingLocs[AllocaNo] = SI->getDebugLoc(); AllocaATInfo[AllocaNo].updateForDeletedStore(SI, DIB, &DbgAssignsToDelete, - &DPVAssignsToDelete); + &DVRAssignsToDelete); auto ConvertDbgDeclares = [&](auto &Container) { for (auto *DbgItem : Container) if (DbgItem->isAddressOfVariable()) diff --git a/llvm/lib/Transforms/Utils/SSAUpdater.cpp b/llvm/lib/Transforms/Utils/SSAUpdater.cpp index fc21fb552137..38df20c949c2 100644 --- a/llvm/lib/Transforms/Utils/SSAUpdater.cpp +++ b/llvm/lib/Transforms/Utils/SSAUpdater.cpp @@ -199,17 +199,17 @@ void SSAUpdater::RewriteUse(Use &U) { void SSAUpdater::UpdateDebugValues(Instruction *I) { SmallVector<DbgValueInst *, 4> DbgValues; - SmallVector<DPValue *, 4> DPValues; - llvm::findDbgValues(DbgValues, I, &DPValues); + SmallVector<DbgVariableRecord *, 4> DbgVariableRecords; + llvm::findDbgValues(DbgValues, I, &DbgVariableRecords); for (auto &DbgValue : DbgValues) { if (DbgValue->getParent() == I->getParent()) continue; UpdateDebugValue(I, DbgValue); } - for (auto &DPV : DPValues) { - if (DPV->getParent() == I->getParent()) + for (auto &DVR : DbgVariableRecords) { + if (DVR->getParent() == I->getParent()) continue; - UpdateDebugValue(I, DPV); + UpdateDebugValue(I, DVR); } } @@ -220,10 +220,10 @@ void SSAUpdater::UpdateDebugValues(Instruction *I, } } -void SSAUpdater::UpdateDebugValues(Instruction *I, - SmallVectorImpl<DPValue *> &DPValues) { - for (auto &DPV : DPValues) { - UpdateDebugValue(I, DPV); +void SSAUpdater::UpdateDebugValues( + Instruction *I, SmallVectorImpl<DbgVariableRecord *> &DbgVariableRecords) { + for (auto &DVR : DbgVariableRecords) { + UpdateDebugValue(I, DVR); } } @@ -236,13 +236,13 @@ void SSAUpdater::UpdateDebugValue(Instruction *I, DbgValueInst *DbgValue) { DbgValue->setKillLocation(); } -void SSAUpdater::UpdateDebugValue(Instruction *I, DPValue *DPV) { - BasicBlock *UserBB = DPV->getParent(); +void SSAUpdater::UpdateDebugValue(Instruction *I, DbgVariableRecord *DVR) { + BasicBlock *UserBB = DVR->getParent(); if (HasValueForBlock(UserBB)) { Value *NewVal = GetValueAtEndOfBlock(UserBB); - DPV->replaceVariableLocationOp(I, NewVal); + DVR->replaceVariableLocationOp(I, NewVal); } else - DPV->setKillLocation(); + DVR->setKillLocation(); } void SSAUpdater::RewriteUseAfterInsertions(Use &U) { diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 292ad78a1852..55bbffb18879 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1126,8 +1126,9 @@ static void CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses( NewBonusInst->insertInto(PredBlock, PTI->getIterator()); auto Range = NewBonusInst->cloneDebugInfoFrom(&BonusInst); - RemapDPValueRange(NewBonusInst->getModule(), Range, VMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + RemapDbgVariableRecordRange(NewBonusInst->getModule(), Range, VMap, + RF_NoModuleLevelChanges | + RF_IgnoreMissingLocals); if (isa<DbgInfoIntrinsic>(BonusInst)) continue; @@ -1526,15 +1527,15 @@ static bool shouldHoistCommonInstructions(Instruction *I1, Instruction *I2, return true; } -/// Hoists DPValues from \p I1 and \p OtherInstrs that are identical in -/// lock-step to \p TI. This matches how dbg.* intrinsics are hoisting in +/// Hoists DbgVariableRecords from \p I1 and \p OtherInstrs that are identical +/// in lock-step to \p TI. This matches how dbg.* intrinsics are hoisting in /// hoistCommonCodeFromSuccessors. e.g. The input: -/// I1 DPVs: { x, z }, -/// OtherInsts: { I2 DPVs: { x, y, z } } -/// would result in hoisting only DPValue x. -static void -hoistLockstepIdenticalDPValues(Instruction *TI, Instruction *I1, - SmallVectorImpl<Instruction *> &OtherInsts) { +/// I1 DVRs: { x, z }, +/// OtherInsts: { I2 DVRs: { x, y, z } } +/// would result in hoisting only DbgVariableRecord x. +static void hoistLockstepIdenticalDbgVariableRecords( + Instruction *TI, Instruction *I1, + SmallVectorImpl<Instruction *> &OtherInsts) { if (!I1->hasDbgRecords()) return; using CurrentAndEndIt = @@ -1570,12 +1571,12 @@ hoistLockstepIdenticalDPValues(Instruction *TI, Instruction *I1, // This replicates the dbg.* intrinsic behaviour in // hoistCommonCodeFromSuccessors. while (none_of(Itrs, atEnd)) { - bool HoistDPVs = allIdentical(Itrs); + bool HoistDVRs = allIdentical(Itrs); for (CurrentAndEndIt &Pair : Itrs) { // Increment Current iterator now as we may be about to move the // DbgRecord. DbgRecord &DR = *Pair.first++; - if (HoistDPVs) { + if (HoistDVRs) { DR.removeFromParent(); TI->getParent()->insertDbgRecordBefore(&DR, TI->getIterator()); } @@ -1691,7 +1692,7 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB, // at the beginning of the loop, we can hoist the terminator instruction. // If any instructions remain in the block, we cannot hoist terminators. if (NumSkipped || !AllInstsAreIdentical) { - hoistLockstepIdenticalDPValues(TI, I1, OtherInsts); + hoistLockstepIdenticalDbgVariableRecords(TI, I1, OtherInsts); return Changed; } @@ -1721,9 +1722,9 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB, // The debug location is an integral part of a debug info intrinsic // and can't be separated from it or replaced. Instead of attempting // to merge locations, simply hoist both copies of the intrinsic. - hoistLockstepIdenticalDPValues(TI, I1, OtherInsts); - // We've just hoisted DPValues; move I1 after them (before TI) and - // leave any that were not hoisted behind (by calling moveBefore + hoistLockstepIdenticalDbgVariableRecords(TI, I1, OtherInsts); + // We've just hoisted DbgVariableRecords; move I1 after them (before TI) + // and leave any that were not hoisted behind (by calling moveBefore // rather than moveBeforePreserving). I1->moveBefore(TI); for (auto &SuccIter : OtherSuccIterRange) { @@ -1735,9 +1736,9 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB, // For a normal instruction, we just move one to right before the // branch, then replace all uses of the other with the first. Finally, // we remove the now redundant second instruction. - hoistLockstepIdenticalDPValues(TI, I1, OtherInsts); - // We've just hoisted DPValues; move I1 after them (before TI) and - // leave any that were not hoisted behind (by calling moveBefore + hoistLockstepIdenticalDbgVariableRecords(TI, I1, OtherInsts); + // We've just hoisted DbgVariableRecords; move I1 after them (before TI) + // and leave any that were not hoisted behind (by calling moveBefore // rather than moveBeforePreserving). I1->moveBefore(TI); for (auto &SuccIter : OtherSuccIterRange) { @@ -1759,7 +1760,7 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB, NumHoistCommonInstrs += SuccIterPairs.size(); } else { if (NumSkipped >= HoistCommonSkipLimit) { - hoistLockstepIdenticalDPValues(TI, I1, OtherInsts); + hoistLockstepIdenticalDbgVariableRecords(TI, I1, OtherInsts); return Changed; } // We are about to skip over a pair of non-identical instructions. Record @@ -1822,9 +1823,9 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf( } } - // Hoist DPValues attached to the terminator to match dbg.* intrinsic hoisting - // behaviour in hoistCommonCodeFromSuccessors. - hoistLockstepIdenticalDPValues(TI, I1, OtherSuccTIs); + // Hoist DbgVariableRecords attached to the terminator to match dbg.* + // intrinsic hoisting behaviour in hoistCommonCodeFromSuccessors. + hoistLockstepIdenticalDbgVariableRecords(TI, I1, OtherSuccTIs); // Clone the terminator and hoist it into the pred, without any debug info. Instruction *NT = I1->clone(); NT->insertInto(TIParent, TI->getIterator()); @@ -3179,7 +3180,7 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, DbgAssign->replaceVariableLocationOp(OrigV, S); }; for_each(at::getAssignmentMarkers(SpeculatedStore), replaceVariable); - for_each(at::getDPVAssignmentMarkers(SpeculatedStore), replaceVariable); + for_each(at::getDVRAssignmentMarkers(SpeculatedStore), replaceVariable); } // Metadata can be dependent on the condition we are hoisting above. @@ -3204,13 +3205,15 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, } // Hoist the instructions. - // In "RemoveDIs" non-instr debug-info mode, drop DPValues attached to these - // instructions, in the same way that dbg.value intrinsics are dropped at the - // end of this block. + // In "RemoveDIs" non-instr debug-info mode, drop DbgVariableRecords attached + // to these instructions, in the same way that dbg.value intrinsics are + // dropped at the end of this block. for (auto &It : make_range(ThenBB->begin(), ThenBB->end())) for (DbgRecord &DR : make_early_inc_range(It.getDbgRecordRange())) - // Drop all records except assign-kind DPValues (dbg.assign equivalent). - if (DPValue *DPV = dyn_cast<DPValue>(&DR); !DPV || !DPV->isDbgAssign()) + // Drop all records except assign-kind DbgVariableRecords (dbg.assign + // equivalent). + if (DbgVariableRecord *DVR = dyn_cast<DbgVariableRecord>(&DR); + !DVR || !DVR->isDbgAssign()) It.dropOneDbgRecord(&DR); BB->splice(BI->getIterator(), ThenBB, ThenBB->begin(), std::prev(ThenBB->end())); @@ -3385,7 +3388,7 @@ FoldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, TranslateMap[Cond] = CB; // RemoveDIs: track instructions that we optimise away while folding, so - // that we can copy DPValues from them later. + // that we can copy DbgVariableRecords from them later. BasicBlock::iterator SrcDbgCursor = BB->begin(); for (BasicBlock::iterator BBI = BB->begin(); &*BBI != BI; ++BBI) { if (PHINode *PN = dyn_cast<PHINode>(BBI)) { @@ -3849,10 +3852,10 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, if (PredBlock->IsNewDbgInfoFormat) { PredBlock->getTerminator()->cloneDebugInfoFrom(BB->getTerminator()); - for (DPValue &DPV : + for (DbgVariableRecord &DVR : filterDbgVars(PredBlock->getTerminator()->getDbgRecordRange())) { - RemapDPValue(M, &DPV, VMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + RemapDbgVariableRecord(M, &DVR, VMap, + RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); } } diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index d0377421145c..8c24599c8ce3 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -146,7 +146,7 @@ public: Value *mapValue(const Value *V); void remapInstruction(Instruction *I); void remapFunction(Function &F); - void remapDbgRecord(DbgRecord &DPV); + void remapDbgRecord(DbgRecord &DVR); Constant *mapConstant(const Constant *C) { return cast_or_null<Constant>(mapValue(C)); @@ -543,7 +543,7 @@ void Mapper::remapDbgRecord(DbgRecord &DR) { return; } - DPValue &V = cast<DPValue>(DR); + DbgVariableRecord &V = cast<DbgVariableRecord>(DR); // Remap variables and DILocations. auto *MappedVar = mapMetadata(V.getVariable()); auto *MappedDILoc = mapMetadata(V.getDebugLoc()); @@ -1233,14 +1233,14 @@ void ValueMapper::remapInstruction(Instruction &I) { FlushingMapper(pImpl)->remapInstruction(&I); } -void ValueMapper::remapDPValue(Module *M, DPValue &V) { +void ValueMapper::remapDbgVariableRecord(Module *M, DbgVariableRecord &V) { FlushingMapper(pImpl)->remapDbgRecord(V); } -void ValueMapper::remapDPValueRange( +void ValueMapper::remapDbgVariableRecordRange( Module *M, iterator_range<DbgRecord::self_iterator> Range) { - for (DPValue &DPV : filterDbgVars(Range)) { - remapDPValue(M, DPV); + for (DbgVariableRecord &DVR : filterDbgVars(Range)) { + remapDbgVariableRecord(M, DVR); } } diff --git a/llvm/test/DebugInfo/dpvalue-print-nocrash.ll b/llvm/test/DebugInfo/dpvalue-print-nocrash.ll index 0a618c6780d1..d8cb542285c8 100755 --- a/llvm/test/DebugInfo/dpvalue-print-nocrash.ll +++ b/llvm/test/DebugInfo/dpvalue-print-nocrash.ll @@ -1,4 +1,4 @@ -;; Tests that we can debug-print DPValues that have no markers attached. +;; Tests that we can debug-print DbgVariableRecords that have no markers attached. ; RUN: opt -passes="instcombine" -debug %s -o /dev/null 2>&1 | FileCheck %s ; REQUIRES: asserts diff --git a/llvm/test/Transforms/LoopRotate/dbgvalue.ll b/llvm/test/Transforms/LoopRotate/dbgvalue.ll index 92cc886bc81c..9ecc31e1bd2d 100644 --- a/llvm/test/Transforms/LoopRotate/dbgvalue.ll +++ b/llvm/test/Transforms/LoopRotate/dbgvalue.ll @@ -220,7 +220,7 @@ for.end: ; Test that dbg.value intrinsincs adjacent to the `icmp slt i32 0, 0` get ; rotated as expected. The icmp is loop-invariant and so gets hoisted to the -; preheader via a different code path. This is more difficult for DPValue +; preheader via a different code path. This is more difficult for DbgVariableRecord ; debug-info records to handle, because they have to get detached and moved ; somewhere else during rotation. define void @invariant_hoist() !dbg !70 { diff --git a/llvm/test/tools/llvm-reduce/remove-dp-values.ll b/llvm/test/tools/llvm-reduce/remove-dp-values.ll index 40ff9f32e960..d137b279f4ea 100644 --- a/llvm/test/tools/llvm-reduce/remove-dp-values.ll +++ b/llvm/test/tools/llvm-reduce/remove-dp-values.ll @@ -1,7 +1,7 @@ ; RUN: llvm-reduce --abort-on-invalid-reduction --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t --try-experimental-debuginfo-iterators ; RUN: FileCheck --check-prefixes=CHECK-FINAL --input-file=%t %s --implicit-check-not=dbg.value -; Test that we can, in RemoveDIs mode / DPValues mode (where variable location +; Test that we can, in RemoveDIs mode / DbgVariableRecords mode (where variable location ; information isn't an instruction), remove one variable location assignment ; but not another. diff --git a/llvm/tools/llvm-reduce/deltas/ReduceDbgRecords.cpp b/llvm/tools/llvm-reduce/deltas/ReduceDbgRecords.cpp index 2f3d4cac9fa0..25de659109c9 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceDbgRecords.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceDbgRecords.cpp @@ -7,13 +7,13 @@ //===----------------------------------------------------------------------===// // // This file implements a function which calls the Generic Delta pass in order -// to reduce uninteresting DPValues from defined functions. +// to reduce uninteresting DbgVariableRecords from defined functions. // -// DPValues store variable-location debug-info and are attached to instructions. -// This information used to be represented by intrinsics such as dbg.value, and -// would naturally get reduced by llvm-reduce like any other instruction. As -// DPValues get stored elsewhere, they need to be enumerated and eliminated like -// any other data structure in LLVM. +// DbgVariableRecords store variable-location debug-info and are attached to +// instructions. This information used to be represented by intrinsics such as +// dbg.value, and would naturally get reduced by llvm-reduce like any other +// instruction. As DbgVariableRecords get stored elsewhere, they need to be +// enumerated and eliminated like any other data structure in LLVM. // //===----------------------------------------------------------------------===// diff --git a/llvm/tools/llvm-reduce/deltas/ReduceDbgRecords.h b/llvm/tools/llvm-reduce/deltas/ReduceDbgRecords.h index 6a8f62155ec3..07a1e04fceae 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceDbgRecords.h +++ b/llvm/tools/llvm-reduce/deltas/ReduceDbgRecords.h @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // // This file implements a function which calls the Generic Delta pass in order -// to reduce uninteresting DPValues from defined functions. +// to reduce uninteresting DbgVariableRecords from defined functions. // //===----------------------------------------------------------------------===// diff --git a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp index bfc64cb84143..92658b7b6895 100644 --- a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp +++ b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp @@ -41,7 +41,7 @@ namespace { // position that it already resides at. This is fine -- but gets complicated // with dbg.value intrinsics. By moving an instruction, we can end up changing // nothing but the location of debug-info intrinsics. That has to be modelled -// by DPValues, the dbg.value replacement. +// by DbgVariableRecords, the dbg.value replacement. TEST(BasicBlockDbgInfoTest, InsertAfterSelf) { LLVMContext C; UseNewDbgInfoFormat = true; @@ -90,10 +90,10 @@ TEST(BasicBlockDbgInfoTest, InsertAfterSelf) { // %b = add // %c = add // dbg.value - // Check that this is replicated by DPValues. + // Check that this is replicated by DbgVariableRecords. Inst2->moveAfter(Inst1); - // Inst1 should only have one DPValue on it. + // Inst1 should only have one DbgVariableRecord on it. EXPECT_TRUE(Inst1->hasDbgRecords()); auto Range1 = Inst1->getDbgRecordRange(); EXPECT_EQ(std::distance(Range1.begin(), Range1.end()), 1u); @@ -158,44 +158,44 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) { EXPECT_EQ(BB.getNextMarker(Instr1), Marker2); EXPECT_EQ(BB.getNextMarker(Instr2), EndMarker); // Is nullptr. - // There should be two DPValues, + // There should be two DbgVariableRecords, EXPECT_EQ(Marker1->StoredDbgRecords.size(), 1u); EXPECT_EQ(Marker2->StoredDbgRecords.size(), 1u); // Unlink them and try to re-insert them through the basic block. - DbgRecord *DPV1 = &*Marker1->StoredDbgRecords.begin(); - DbgRecord *DPV2 = &*Marker2->StoredDbgRecords.begin(); - DPV1->removeFromParent(); - DPV2->removeFromParent(); + DbgRecord *DVR1 = &*Marker1->StoredDbgRecords.begin(); + DbgRecord *DVR2 = &*Marker2->StoredDbgRecords.begin(); + DVR1->removeFromParent(); + DVR2->removeFromParent(); EXPECT_TRUE(Marker1->StoredDbgRecords.empty()); EXPECT_TRUE(Marker2->StoredDbgRecords.empty()); // This should appear in Marker1. - BB.insertDbgRecordBefore(DPV1, BB.begin()); + BB.insertDbgRecordBefore(DVR1, BB.begin()); EXPECT_EQ(Marker1->StoredDbgRecords.size(), 1u); - EXPECT_EQ(DPV1, &*Marker1->StoredDbgRecords.begin()); + EXPECT_EQ(DVR1, &*Marker1->StoredDbgRecords.begin()); // This should attach to Marker2. - BB.insertDbgRecordAfter(DPV2, &*BB.begin()); + BB.insertDbgRecordAfter(DVR2, &*BB.begin()); EXPECT_EQ(Marker2->StoredDbgRecords.size(), 1u); - EXPECT_EQ(DPV2, &*Marker2->StoredDbgRecords.begin()); + EXPECT_EQ(DVR2, &*Marker2->StoredDbgRecords.begin()); - // Now, how about removing instructions? That should cause any DPValues to - // "fall down". + // Now, how about removing instructions? That should cause any + // DbgVariableRecords to "fall down". Instr1->removeFromParent(); Marker1 = nullptr; - // DPValues should now be in Marker2. + // DbgVariableRecords should now be in Marker2. EXPECT_EQ(BB.size(), 1u); EXPECT_EQ(Marker2->StoredDbgRecords.size(), 2u); // They should also be in the correct order. - SmallVector<DbgRecord *, 2> DPVs; - for (DbgRecord &DPV : Marker2->getDbgRecordRange()) - DPVs.push_back(&DPV); - EXPECT_EQ(DPVs[0], DPV1); - EXPECT_EQ(DPVs[1], DPV2); - - // If we remove the end instruction, the DPValues should fall down into - // the trailing marker. + SmallVector<DbgRecord *, 2> DVRs; + for (DbgRecord &DVR : Marker2->getDbgRecordRange()) + DVRs.push_back(&DVR); + EXPECT_EQ(DVRs[0], DVR1); + EXPECT_EQ(DVRs[1], DVR2); + + // If we remove the end instruction, the DbgVariableRecords should fall down + // into the trailing marker. EXPECT_EQ(BB.getTrailingDbgRecords(), nullptr); Instr2->removeFromParent(); EXPECT_TRUE(BB.empty()); @@ -204,35 +204,35 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) { EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u); // Again, these should arrive in the correct order. - DPVs.clear(); - for (DbgRecord &DPV : EndMarker->getDbgRecordRange()) - DPVs.push_back(&DPV); - EXPECT_EQ(DPVs[0], DPV1); - EXPECT_EQ(DPVs[1], DPV2); + DVRs.clear(); + for (DbgRecord &DVR : EndMarker->getDbgRecordRange()) + DVRs.push_back(&DVR); + EXPECT_EQ(DVRs[0], DVR1); + EXPECT_EQ(DVRs[1], DVR2); // Inserting a normal instruction at the beginning: shouldn't dislodge the - // DPValues. It's intended to not go at the start. + // DbgVariableRecords. It's intended to not go at the start. Instr1->insertBefore(BB, BB.begin()); EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u); Instr1->removeFromParent(); - // Inserting at end(): should dislodge the DPValues, if they were dbg.values - // then they would sit "above" the new instruction. + // Inserting at end(): should dislodge the DbgVariableRecords, if they were + // dbg.values then they would sit "above" the new instruction. Instr1->insertBefore(BB, BB.end()); EXPECT_EQ(Instr1->DbgMarker->StoredDbgRecords.size(), 2u); // We should de-allocate the trailing marker when something is inserted // at end(). EXPECT_EQ(BB.getTrailingDbgRecords(), nullptr); - // Remove Instr1: now the DPValues will fall down again, + // Remove Instr1: now the DbgVariableRecords will fall down again, Instr1->removeFromParent(); EndMarker = BB.getTrailingDbgRecords(); EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u); // Inserting a terminator, however it's intended, should dislodge the - // trailing DPValues, as it's the clear intention of the caller that this be - // the final instr in the block, and DPValues aren't allowed to live off the - // end forever. + // trailing DbgVariableRecords, as it's the clear intention of the caller that + // this be the final instr in the block, and DbgVariableRecords aren't allowed + // to live off the end forever. Instr2->insertBefore(BB, BB.begin()); EXPECT_EQ(Instr2->DbgMarker->StoredDbgRecords.size(), 2u); EXPECT_EQ(BB.getTrailingDbgRecords(), nullptr); @@ -300,29 +300,30 @@ TEST(BasicBlockDbgInfoTest, HeadBitOperations) { ASSERT_TRUE(CInst->DbgMarker); EXPECT_FALSE(CInst->DbgMarker->StoredDbgRecords.empty()); - // If we move "c" to the start of the block, just normally, then the DPValues - // should fall down to "d". + // If we move "c" to the start of the block, just normally, then the + // DbgVariableRecords should fall down to "d". CInst->moveBefore(BB, BeginIt2); EXPECT_TRUE(!CInst->DbgMarker || CInst->DbgMarker->StoredDbgRecords.empty()); ASSERT_TRUE(DInst->DbgMarker); EXPECT_FALSE(DInst->DbgMarker->StoredDbgRecords.empty()); // Wheras if we move D to the start of the block with moveBeforePreserving, - // the DPValues should move with it. + // the DbgVariableRecords should move with it. DInst->moveBeforePreserving(BB, BB.begin()); EXPECT_FALSE(DInst->DbgMarker->StoredDbgRecords.empty()); EXPECT_EQ(&*BB.begin(), DInst); - // Similarly, moveAfterPreserving "D" to "C" should move DPValues with "D". + // Similarly, moveAfterPreserving "D" to "C" should move DbgVariableRecords + // with "D". DInst->moveAfterPreserving(CInst); EXPECT_FALSE(DInst->DbgMarker->StoredDbgRecords.empty()); // (move back to the start...) DInst->moveBeforePreserving(BB, BB.begin()); - // Current order of insts: "D -> C -> B -> Ret". DPValues on "D". + // Current order of insts: "D -> C -> B -> Ret". DbgVariableRecords on "D". // If we move "C" to the beginning of the block, it should go before the - // DPValues. They'll stay on "D". + // DbgVariableRecords. They'll stay on "D". CInst->moveBefore(BB, BB.begin()); EXPECT_TRUE(!CInst->DbgMarker || CInst->DbgMarker->StoredDbgRecords.empty()); EXPECT_FALSE(DInst->DbgMarker->StoredDbgRecords.empty()); @@ -333,14 +334,14 @@ TEST(BasicBlockDbgInfoTest, HeadBitOperations) { CInst->moveBefore(BInst); EXPECT_EQ(&*BB.begin(), DInst); - // Current order of insts: "D -> C -> B -> Ret". DPValues on "D". + // Current order of insts: "D -> C -> B -> Ret". DbgVariableRecords on "D". // Now move CInst to the position of DInst, but using getIterator instead of // BasicBlock::begin. This signals that we want the "C" instruction to be - // immediately before "D", with any DPValues on "D" now moving to "C". - // It's the equivalent of moving an instruction to the position between a + // immediately before "D", with any DbgVariableRecords on "D" now moving to + // "C". It's the equivalent of moving an instruction to the position between a // run of dbg.values and the next instruction. CInst->moveBefore(BB, DInst->getIterator()); - // CInst gains the DPValues. + // CInst gains the DbgVariableRecords. EXPECT_TRUE(!DInst->DbgMarker || DInst->DbgMarker->StoredDbgRecords.empty()); EXPECT_FALSE(CInst->DbgMarker->StoredDbgRecords.empty()); EXPECT_EQ(&*BB.begin(), CInst); @@ -378,8 +379,8 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) { !11 = !DILocation(line: 1, column: 1, scope: !6) )"); - // Check that DPValues can be accessed from Instructions without digging - // into the depths of DPMarkers. + // Check that DbgVariableRecords can be accessed from Instructions without + // digging into the depths of DPMarkers. BasicBlock &BB = M->getFunction("f")->getEntryBlock(); // Convert the module to "new" form debug-info. M->convertToNewDbgValues(); @@ -391,25 +392,25 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) { ASSERT_FALSE(BInst->DbgMarker); ASSERT_TRUE(CInst->DbgMarker); ASSERT_EQ(CInst->DbgMarker->StoredDbgRecords.size(), 1u); - DbgRecord *DPV1 = &*CInst->DbgMarker->StoredDbgRecords.begin(); - ASSERT_TRUE(DPV1); + DbgRecord *DVR1 = &*CInst->DbgMarker->StoredDbgRecords.begin(); + ASSERT_TRUE(DVR1); EXPECT_FALSE(BInst->hasDbgRecords()); - // Clone DPValues from one inst to another. Other arguments to clone are - // tested in DPMarker test. + // Clone DbgVariableRecords from one inst to another. Other arguments to clone + // are tested in DPMarker test. auto Range1 = BInst->cloneDebugInfoFrom(CInst); EXPECT_EQ(BInst->DbgMarker->StoredDbgRecords.size(), 1u); - DbgRecord *DPV2 = &*BInst->DbgMarker->StoredDbgRecords.begin(); + DbgRecord *DVR2 = &*BInst->DbgMarker->StoredDbgRecords.begin(); EXPECT_EQ(std::distance(Range1.begin(), Range1.end()), 1u); - EXPECT_EQ(&*Range1.begin(), DPV2); - EXPECT_NE(DPV1, DPV2); + EXPECT_EQ(&*Range1.begin(), DVR2); + EXPECT_NE(DVR1, DVR2); // We should be able to get a range over exactly the same information. auto Range2 = BInst->getDbgRecordRange(); EXPECT_EQ(Range1.begin(), Range2.begin()); EXPECT_EQ(Range1.end(), Range2.end()); - // We should be able to query if there are DPValues, + // We should be able to query if there are DbgVariableRecords, EXPECT_TRUE(BInst->hasDbgRecords()); EXPECT_TRUE(CInst->hasDbgRecords()); EXPECT_FALSE(DInst->hasDbgRecords()); @@ -419,8 +420,8 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) { EXPECT_FALSE(BInst->hasDbgRecords()); EXPECT_EQ(BInst->DbgMarker->StoredDbgRecords.size(), 0u); - // And we should be able to drop individual DPValues. - CInst->dropOneDbgRecord(DPV1); + // And we should be able to drop individual DbgVariableRecords. + CInst->dropOneDbgRecord(DVR1); EXPECT_FALSE(CInst->hasDbgRecords()); EXPECT_EQ(CInst->DbgMarker->StoredDbgRecords.size(), 0u); @@ -514,7 +515,7 @@ protected: BasicBlock *BBEntry, *BBExit; BasicBlock::iterator Dest, First, Last; Instruction *BInst, *Branch, *CInst; - DPValue *DPVA, *DPVB, *DPVConst; + DbgVariableRecord *DVRA, *DVRB, *DVRConst; void SetUp() override { UseNewDbgInfoFormat = true; @@ -531,18 +532,21 @@ protected: Branch = &*Last; CInst = &*Dest; - DPVA = cast<DPValue>(&*BInst->DbgMarker->StoredDbgRecords.begin()); - DPVB = cast<DPValue>(&*Branch->DbgMarker->StoredDbgRecords.begin()); - DPVConst = cast<DPValue>(&*CInst->DbgMarker->StoredDbgRecords.begin()); + DVRA = + cast<DbgVariableRecord>(&*BInst->DbgMarker->StoredDbgRecords.begin()); + DVRB = + cast<DbgVariableRecord>(&*Branch->DbgMarker->StoredDbgRecords.begin()); + DVRConst = + cast<DbgVariableRecord>(&*CInst->DbgMarker->StoredDbgRecords.begin()); } void TearDown() override { UseNewDbgInfoFormat = false; } - bool InstContainsDPValue(Instruction *I, DPValue *DPV) { + bool InstContainsDbgVariableRecord(Instruction *I, DbgVariableRecord *DVR) { for (DbgRecord &D : I->getDbgRecordRange()) { - if (&D == DPV) { + if (&D == DVR) { // Confirm too that the links between the records are correct. - EXPECT_EQ(DPV->Marker, I->DbgMarker); + EXPECT_EQ(DVR->Marker, I->DbgMarker); EXPECT_EQ(I->DbgMarker->MarkedInstr, I); return true; } @@ -550,7 +554,8 @@ protected: return false; } - bool CheckDPVOrder(Instruction *I, SmallVector<DPValue *> CheckVals) { + bool CheckDVROrder(Instruction *I, + SmallVector<DbgVariableRecord *> CheckVals) { SmallVector<DbgRecord *> Vals; for (DbgRecord &D : I->getDbgRecordRange()) Vals.push_back(&D); @@ -578,15 +583,15 @@ TEST_F(DbgSpliceTest, DbgSpliceTest0) { /* define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, +!dbg !11 } Splice from First, not including leading dbg.value, to Last, including the @@ -595,15 +600,14 @@ Dest %c = add i16 %b, 1, !dbg !11 define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, !dbg !11 } @@ -613,14 +617,14 @@ Dest %c = add i16 %b, 1, !dbg !11 EXPECT_EQ(CInst->getParent(), BBExit); EXPECT_EQ(Branch->getParent(), BBEntry); - // DPVB: should be on Dest, in exit block. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVB)); + // DVRB: should be on Dest, in exit block. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB)); - // DPVA, should have "fallen" onto the branch, remained in entry block. - EXPECT_TRUE(InstContainsDPValue(Branch, DPVA)); + // DVRA, should have "fallen" onto the branch, remained in entry block. + EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA)); - // DPVConst should be on the moved %b instruction. - EXPECT_TRUE(InstContainsDPValue(BInst, DPVConst)); + // DVRConst should be on the moved %b instruction. + EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst)); } TEST_F(DbgSpliceTest, DbgSpliceTest1) { @@ -631,15 +635,15 @@ TEST_F(DbgSpliceTest, DbgSpliceTest1) { /* define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, +!dbg !11 } Splice from First, not including leading dbg.value, to Last, including the @@ -648,15 +652,15 @@ Dest %c = add i16 %b, 1, !dbg !11 define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 Last br label %exit, !dbg !11 BBExit exit: First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata +!DIExpression()), !dbg !11 DVRConst call void @llvm.dbg.value(metadata i16 0, +metadata !9, metadata !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, +!dbg !11 ret i16 0, !dbg !11 } @@ -666,17 +670,17 @@ Dest %c = add i16 %b, 1, !dbg !11 EXPECT_EQ(CInst->getParent(), BBExit); EXPECT_EQ(Branch->getParent(), BBEntry); - // DPVB: should be on CInst, in exit block. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVB)); + // DVRB: should be on CInst, in exit block. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB)); - // DPVA, should have "fallen" onto the branch, remained in entry block. - EXPECT_TRUE(InstContainsDPValue(Branch, DPVA)); + // DVRA, should have "fallen" onto the branch, remained in entry block. + EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA)); - // DPVConst should be behind / after the moved instructions, remain on CInst. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVConst)); + // DVRConst should be behind / after the moved instructions, remain on CInst. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); - // Order of DPVB and DPVConst should be thus: - EXPECT_TRUE(CheckDPVOrder(CInst, {DPVB, DPVConst})); + // Order of DVRB and DVRConst should be thus: + EXPECT_TRUE(CheckDVROrder(CInst, {DVRB, DVRConst})); } TEST_F(DbgSpliceTest, DbgSpliceTest2) { @@ -687,15 +691,15 @@ TEST_F(DbgSpliceTest, DbgSpliceTest2) { /* define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, +!dbg !11 } Splice from head of First, which includes the leading dbg.value, to Last, @@ -707,12 +711,12 @@ BBEntry entry: Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 DVRA call void @llvm.dbg.value(metadata i16 %a, +metadata !9, metadata !DIExpression()), !dbg !11 First %b = add i16 %a, 1, +!dbg !11 DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, +metadata !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret +i16 0, !dbg !11 } @@ -721,18 +725,18 @@ Dest %c = add i16 %b, 1, !dbg !11 EXPECT_EQ(BInst->getParent(), BBExit); EXPECT_EQ(CInst->getParent(), BBExit); - // DPVB: should be on CInst, in exit block. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVB)); + // DVRB: should be on CInst, in exit block. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB)); - // DPVA, should have transferred with the spliced instructions, remains on + // DVRA, should have transferred with the spliced instructions, remains on // the "b" inst. - EXPECT_TRUE(InstContainsDPValue(BInst, DPVA)); + EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA)); - // DPVConst should be ahead of the moved instructions, ahead of BInst. - EXPECT_TRUE(InstContainsDPValue(BInst, DPVConst)); + // DVRConst should be ahead of the moved instructions, ahead of BInst. + EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst)); - // Order of DPVA and DPVConst should be thus: - EXPECT_TRUE(CheckDPVOrder(BInst, {DPVConst, DPVA})); + // Order of DVRA and DVRConst should be thus: + EXPECT_TRUE(CheckDVROrder(BInst, {DVRConst, DVRA})); } TEST_F(DbgSpliceTest, DbgSpliceTest3) { @@ -743,15 +747,15 @@ TEST_F(DbgSpliceTest, DbgSpliceTest3) { /* define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, +!dbg !11 } Splice from head of First, which includes the leading dbg.value, to Last, @@ -763,12 +767,12 @@ BBEntry entry: Last br label %exit, !dbg !11 BBExit exit: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, +metadata !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret +i16 0, !dbg !11 } */ @@ -776,18 +780,18 @@ Dest %c = add i16 %b, 1, !dbg !11 EXPECT_EQ(BInst->getParent(), BBExit); EXPECT_EQ(CInst->getParent(), BBExit); - // DPVB: should be on CInst, in exit block. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVB)); + // DVRB: should be on CInst, in exit block. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRB)); - // DPVA, should have transferred with the spliced instructions, remains on + // DVRA, should have transferred with the spliced instructions, remains on // the "b" inst. - EXPECT_TRUE(InstContainsDPValue(BInst, DPVA)); + EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA)); - // DPVConst should be behind the moved instructions, ahead of CInst. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVConst)); + // DVRConst should be behind the moved instructions, ahead of CInst. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); - // Order of DPVB and DPVConst should be thus: - EXPECT_TRUE(CheckDPVOrder(CInst, {DPVB, DPVConst})); + // Order of DVRB and DVRConst should be thus: + EXPECT_TRUE(CheckDVROrder(CInst, {DVRB, DVRConst})); } TEST_F(DbgSpliceTest, DbgSpliceTest4) { @@ -798,15 +802,15 @@ TEST_F(DbgSpliceTest, DbgSpliceTest4) { /* define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, +!dbg !11 } Splice from First, not including the leading dbg.value, to Last, but NOT @@ -815,15 +819,15 @@ Dest %c = add i16 %b, 1, !dbg !11 define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 DVRB call void @llvm.dbg.value(metadata i16 %b, +metadata !9, metadata !DIExpression()), !dbg !11 Last br label %exit, !dbg +!11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 Dest %c = +add i16 %b, 1, !dbg !11 ret i16 0, !dbg !11 } */ @@ -832,17 +836,17 @@ Dest %c = add i16 %b, 1, !dbg !11 EXPECT_EQ(CInst->getParent(), BBExit); EXPECT_EQ(Branch->getParent(), BBEntry); - // DPVB: should be on Branch as before, remain in entry block. - EXPECT_TRUE(InstContainsDPValue(Branch, DPVB)); + // DVRB: should be on Branch as before, remain in entry block. + EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); - // DPVA, should have remained in entry block, falls onto Branch inst. - EXPECT_TRUE(InstContainsDPValue(Branch, DPVA)); + // DVRA, should have remained in entry block, falls onto Branch inst. + EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA)); - // DPVConst should be ahead of the moved instructions, BInst. - EXPECT_TRUE(InstContainsDPValue(BInst, DPVConst)); + // DVRConst should be ahead of the moved instructions, BInst. + EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst)); - // Order of DPVA and DPVA should be thus: - EXPECT_TRUE(CheckDPVOrder(Branch, {DPVA, DPVB})); + // Order of DVRA and DVRA should be thus: + EXPECT_TRUE(CheckDVROrder(Branch, {DVRA, DVRB})); } TEST_F(DbgSpliceTest, DbgSpliceTest5) { @@ -853,15 +857,15 @@ TEST_F(DbgSpliceTest, DbgSpliceTest5) { /* define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, +!dbg !11 } Splice from First, not including the leading dbg.value, to Last, but NOT @@ -870,15 +874,16 @@ Dest %c = add i16 %b, 1, !dbg !11 define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 DVRB call void @llvm.dbg.value(metadata i16 %b, +metadata !9, metadata !DIExpression()), !dbg !11 Last br label %exit, !dbg +!11 BBExit exit: First %b = add i16 %a, 1, !dbg !11 -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, +!dbg !11 } */ @@ -887,17 +892,17 @@ Dest %c = add i16 %b, 1, !dbg !11 EXPECT_EQ(CInst->getParent(), BBExit); EXPECT_EQ(Branch->getParent(), BBEntry); - // DPVB: should be on Branch as before, remain in entry block. - EXPECT_TRUE(InstContainsDPValue(Branch, DPVB)); + // DVRB: should be on Branch as before, remain in entry block. + EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); - // DPVA, should have remained in entry block, falls onto Branch inst. - EXPECT_TRUE(InstContainsDPValue(Branch, DPVA)); + // DVRA, should have remained in entry block, falls onto Branch inst. + EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRA)); - // DPVConst should be behind of the moved instructions, on CInst. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVConst)); + // DVRConst should be behind of the moved instructions, on CInst. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); - // Order of DPVA and DPVB should be thus: - EXPECT_TRUE(CheckDPVOrder(Branch, {DPVA, DPVB})); + // Order of DVRA and DVRB should be thus: + EXPECT_TRUE(CheckDVROrder(Branch, {DVRA, DVRB})); } TEST_F(DbgSpliceTest, DbgSpliceTest6) { @@ -908,15 +913,15 @@ TEST_F(DbgSpliceTest, DbgSpliceTest6) { /* define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, +!dbg !11 } Splice from First, including the leading dbg.value, to Last, but NOT @@ -925,15 +930,14 @@ Dest %c = add i16 %b, 1, !dbg !11 define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata +!DIExpression()), !dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 DVRA call void @llvm.dbg.value(metadata i16 %a, +metadata !9, metadata !DIExpression()), !dbg !11 First %b = add i16 %a, 1, +!dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, !dbg !11 } */ @@ -942,17 +946,17 @@ Dest %c = add i16 %b, 1, !dbg !11 EXPECT_EQ(CInst->getParent(), BBExit); EXPECT_EQ(Branch->getParent(), BBEntry); - // DPVB: should be on Branch as before, remain in entry block. - EXPECT_TRUE(InstContainsDPValue(Branch, DPVB)); + // DVRB: should be on Branch as before, remain in entry block. + EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); - // DPVA, should have transferred to BBExit, on B inst. - EXPECT_TRUE(InstContainsDPValue(BInst, DPVA)); + // DVRA, should have transferred to BBExit, on B inst. + EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA)); - // DPVConst should be ahead of the moved instructions, on BInst. - EXPECT_TRUE(InstContainsDPValue(BInst, DPVConst)); + // DVRConst should be ahead of the moved instructions, on BInst. + EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRConst)); - // Order of DPVA and DPVConst should be thus: - EXPECT_TRUE(CheckDPVOrder(BInst, {DPVConst, DPVA})); + // Order of DVRA and DVRConst should be thus: + EXPECT_TRUE(CheckDVROrder(BInst, {DVRConst, DVRA})); } TEST_F(DbgSpliceTest, DbgSpliceTest7) { @@ -963,15 +967,15 @@ TEST_F(DbgSpliceTest, DbgSpliceTest7) { /* define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, +!dbg !11 } Splice from First, including the leading dbg.value, to Last, but NOT @@ -980,15 +984,14 @@ Dest %c = add i16 %b, 1, !dbg !11 define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata +!DIExpression()), !dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRConst call +void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), +!dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, !dbg !11 } */ @@ -997,21 +1000,21 @@ Dest %c = add i16 %b, 1, !dbg !11 EXPECT_EQ(CInst->getParent(), BBExit); EXPECT_EQ(Branch->getParent(), BBEntry); - // DPVB: should be on Branch as before, remain in entry block. - EXPECT_TRUE(InstContainsDPValue(Branch, DPVB)); + // DVRB: should be on Branch as before, remain in entry block. + EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); - // DPVA, should have transferred to BBExit, on B inst. - EXPECT_TRUE(InstContainsDPValue(BInst, DPVA)); + // DVRA, should have transferred to BBExit, on B inst. + EXPECT_TRUE(InstContainsDbgVariableRecord(BInst, DVRA)); - // DPVConst should be after of the moved instructions, on CInst. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVConst)); + // DVRConst should be after of the moved instructions, on CInst. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); } // But wait, there's more! What if you splice a range that is empty, but // implicitly contains debug-info? In the dbg.value design for debug-info, -// this would be an explicit range, but in DPValue debug-info, it isn't. -// Check that if we try to do that, with differing head-bit values, that -// DPValues are transferred. +// this would be an explicit range, but in DbgVariableRecord debug-info, it +// isn't. Check that if we try to do that, with differing head-bit values, that +// DbgVariableRecords are transferred. // Test with empty transfers to Dest, with head bit set and not set. TEST_F(DbgSpliceTest, DbgSpliceEmpty0) { @@ -1021,31 +1024,31 @@ TEST_F(DbgSpliceTest, DbgSpliceEmpty0) { /* define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, +!dbg !11 } Splice from BBEntry.getFirstInsertionPt to First -- this implicitly is a - splice of DPVA, but the iterators are pointing at the same instruction. The + splice of DVRA, but the iterators are pointing at the same instruction. The only difference is the setting of the head bit. Becomes; define i16 @f(i16 %a) !dbg !6 { First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata +!DIExpression()), !dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 DVRA call void @llvm.dbg.value(metadata i16 %a, +metadata !9, metadata !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, +!dbg !11 ret i16 0, !dbg !11 } */ @@ -1054,17 +1057,17 @@ Dest %c = add i16 %b, 1, !dbg !11 EXPECT_EQ(CInst->getParent(), BBExit); EXPECT_EQ(Branch->getParent(), BBEntry); - // DPVB: should be on Branch as before, remain in entry block. - EXPECT_TRUE(InstContainsDPValue(Branch, DPVB)); + // DVRB: should be on Branch as before, remain in entry block. + EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); - // DPVA, should have transferred to BBExit, on C inst. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVA)); + // DVRA, should have transferred to BBExit, on C inst. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRA)); - // DPVConst should be ahead of the moved DPValue, on CInst. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVConst)); + // DVRConst should be ahead of the moved DbgVariableRecord, on CInst. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); - // Order of DPVA and DPVConst should be thus: - EXPECT_TRUE(CheckDPVOrder(CInst, {DPVConst, DPVA})); + // Order of DVRA and DVRConst should be thus: + EXPECT_TRUE(CheckDVROrder(CInst, {DVRConst, DVRA})); } TEST_F(DbgSpliceTest, DbgSpliceEmpty1) { @@ -1074,32 +1077,32 @@ TEST_F(DbgSpliceTest, DbgSpliceEmpty1) { /* define i16 @f(i16 %a) !dbg !6 { BBEntry entry: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 First %b = add i16 %a, 1, !dbg !11 DVRB call +void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), +!dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata +!DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, !dbg !11 ret i16 0, +!dbg !11 } Splice from BBEntry.getFirstInsertionPt to First -- this implicitly is a - splice of DPVA, but the iterators are pointing at the same instruction. The + splice of DVRA, but the iterators are pointing at the same instruction. The only difference is the setting of the head bit. Insert at head of Dest, - i.e. before DPVConst. Becomes; + i.e. before DVRConst. Becomes; define i16 @f(i16 %a) !dbg !6 { First %b = add i16 %a, 1, !dbg !11 -DPVB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11 -Last br label %exit, !dbg !11 +DVRB call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata +!DIExpression()), !dbg !11 Last br label %exit, !dbg !11 BBExit exit: -DPVA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11 -DPVConst call void @llvm.dbg.value(metadata i16 0, metadata !9, metadata !DIExpression()), !dbg !11 -Dest %c = add i16 %b, 1, !dbg !11 - ret i16 0, !dbg !11 +DVRA call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata +!DIExpression()), !dbg !11 DVRConst call void @llvm.dbg.value(metadata i16 0, +metadata !9, metadata !DIExpression()), !dbg !11 Dest %c = add i16 %b, 1, +!dbg !11 ret i16 0, !dbg !11 } */ @@ -1108,21 +1111,21 @@ Dest %c = add i16 %b, 1, !dbg !11 EXPECT_EQ(CInst->getParent(), BBExit); EXPECT_EQ(Branch->getParent(), BBEntry); - // DPVB: should be on Branch as before, remain in entry block. - EXPECT_TRUE(InstContainsDPValue(Branch, DPVB)); + // DVRB: should be on Branch as before, remain in entry block. + EXPECT_TRUE(InstContainsDbgVariableRecord(Branch, DVRB)); - // DPVA, should have transferred to BBExit, on C inst. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVA)); + // DVRA, should have transferred to BBExit, on C inst. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRA)); - // DPVConst should be ahead of the moved DPValue, on CInst. - EXPECT_TRUE(InstContainsDPValue(CInst, DPVConst)); + // DVRConst should be ahead of the moved DbgVariableRecord, on CInst. + EXPECT_TRUE(InstContainsDbgVariableRecord(CInst, DVRConst)); - // Order of DPVA and DPVConst should be thus: - EXPECT_TRUE(CheckDPVOrder(CInst, {DPVA, DPVConst})); + // Order of DVRA and DVRConst should be thus: + EXPECT_TRUE(CheckDVROrder(CInst, {DVRA, DVRConst})); } -// If we splice new instructions into a block with trailing DPValues, then -// the trailing DPValues should get flushed back out. +// If we splice new instructions into a block with trailing DbgVariableRecords, +// then the trailing DbgVariableRecords should get flushed back out. TEST(BasicBlockDbgInfoTest, DbgSpliceTrailing) { LLVMContext C; UseNewDbgInfoFormat = true; @@ -1159,7 +1162,7 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceTrailing) { BasicBlock &Exit = *Entry.getNextNode(); M->convertToNewDbgValues(); - // Begin by forcing entry block to have dangling DPValue. + // Begin by forcing entry block to have dangling DbgVariableRecord. Entry.getTerminator()->eraseFromParent(); ASSERT_NE(Entry.getTrailingDbgRecords(), nullptr); EXPECT_TRUE(Entry.empty()); @@ -1167,8 +1170,8 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceTrailing) { // Now transfer the entire contents of the exit block into the entry. Entry.splice(Entry.end(), &Exit, Exit.begin(), Exit.end()); - // The trailing DPValue should have been placed at the front of what's been - // spliced in. + // The trailing DbgVariableRecord should have been placed at the front of + // what's been spliced in. Instruction *BInst = &*Entry.begin(); ASSERT_TRUE(BInst->DbgMarker); EXPECT_EQ(BInst->DbgMarker->StoredDbgRecords.size(), 1u); @@ -1176,10 +1179,10 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceTrailing) { UseNewDbgInfoFormat = false; } -// When we remove instructions from the program, adjacent DPValues coalesce -// together into one DPMarker. In "old" dbg.value mode you could re-insert -// the removed instruction back into the middle of a sequence of dbg.values. -// Test that this can be replicated correctly by DPValues +// When we remove instructions from the program, adjacent DbgVariableRecords +// coalesce together into one DPMarker. In "old" dbg.value mode you could +// re-insert the removed instruction back into the middle of a sequence of +// dbg.values. Test that this can be replicated correctly by DbgVariableRecords TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsert) { LLVMContext C; UseNewDbgInfoFormat = true; @@ -1221,7 +1224,7 @@ TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsert) { Instruction *RetInst = AddInst->getNextNode(); ASSERT_TRUE(isa<ReturnInst>(RetInst)); - // add and sub should both have one DPValue on add and ret. + // add and sub should both have one DbgVariableRecord on add and ret. EXPECT_FALSE(SubInst->hasDbgRecords()); EXPECT_TRUE(AddInst->hasDbgRecords()); EXPECT_TRUE(RetInst->hasDbgRecords()); @@ -1232,20 +1235,21 @@ TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsert) { // The Supported (TM) code sequence for removing then reinserting insts // after another instruction: - std::optional<DPValue::self_iterator> Pos = + std::optional<DbgVariableRecord::self_iterator> Pos = AddInst->getDbgReinsertionPosition(); AddInst->removeFromParent(); // We should have a re-insertion position. ASSERT_TRUE(Pos); - // Both DPValues should now be attached to the ret inst. + // Both DbgVariableRecords should now be attached to the ret inst. auto R3 = RetInst->getDbgRecordRange(); EXPECT_EQ(std::distance(R3.begin(), R3.end()), 2u); // Re-insert and re-insert. AddInst->insertAfter(SubInst); Entry.reinsertInstInDbgRecords(AddInst, Pos); - // We should be back into a position of having one DPValue on add and ret. + // We should be back into a position of having one DbgVariableRecord on add + // and ret. EXPECT_FALSE(SubInst->hasDbgRecords()); EXPECT_TRUE(AddInst->hasDbgRecords()); EXPECT_TRUE(RetInst->hasDbgRecords()); @@ -1257,9 +1261,9 @@ TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsert) { UseNewDbgInfoFormat = false; } -// Test instruction removal and re-insertion, this time with one DPValue that -// should hop up one instruction. -TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsertForOneDPValue) { +// Test instruction removal and re-insertion, this time with one +// DbgVariableRecord that should hop up one instruction. +TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsertForOneDbgVariableRecord) { LLVMContext C; UseNewDbgInfoFormat = true; @@ -1299,7 +1303,7 @@ TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsertForOneDPValue) { Instruction *RetInst = AddInst->getNextNode(); ASSERT_TRUE(isa<ReturnInst>(RetInst)); - // There should be one DPValue. + // There should be one DbgVariableRecord. EXPECT_FALSE(SubInst->hasDbgRecords()); EXPECT_TRUE(AddInst->hasDbgRecords()); EXPECT_FALSE(RetInst->hasDbgRecords()); @@ -1307,13 +1311,13 @@ TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsertForOneDPValue) { EXPECT_EQ(std::distance(R1.begin(), R1.end()), 1u); // The Supported (TM) code sequence for removing then reinserting insts: - std::optional<DPValue::self_iterator> Pos = + std::optional<DbgVariableRecord::self_iterator> Pos = AddInst->getDbgReinsertionPosition(); AddInst->removeFromParent(); - // No re-insertion position as there were no DPValues on the ret. + // No re-insertion position as there were no DbgVariableRecords on the ret. ASSERT_FALSE(Pos); - // The single DPValue should now be attached to the ret inst. + // The single DbgVariableRecord should now be attached to the ret inst. EXPECT_TRUE(RetInst->hasDbgRecords()); auto R2 = RetInst->getDbgRecordRange(); EXPECT_EQ(std::distance(R2.begin(), R2.end()), 1u); @@ -1321,7 +1325,8 @@ TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsertForOneDPValue) { // Re-insert and re-insert. AddInst->insertAfter(SubInst); Entry.reinsertInstInDbgRecords(AddInst, Pos); - // We should be back into a position of having one DPValue on the AddInst. + // We should be back into a position of having one DbgVariableRecord on the + // AddInst. EXPECT_FALSE(SubInst->hasDbgRecords()); EXPECT_TRUE(AddInst->hasDbgRecords()); EXPECT_FALSE(RetInst->hasDbgRecords()); @@ -1374,7 +1379,7 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty1) { BasicBlock &Exit = *Entry.getNextNode(); M->convertToNewDbgValues(); - // Begin by forcing entry block to have dangling DPValue. + // Begin by forcing entry block to have dangling DbgVariableRecord. Entry.getTerminator()->eraseFromParent(); ASSERT_NE(Entry.getTrailingDbgRecords(), nullptr); EXPECT_TRUE(Entry.empty()); @@ -1388,16 +1393,16 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty1) { Instruction *BInst = &*Entry.begin(); ASSERT_TRUE(BInst->hasDbgRecords()); EXPECT_EQ(BInst->DbgMarker->StoredDbgRecords.size(), 2u); - SmallVector<DPValue *, 2> DPValues; - for (DbgRecord &DPV : BInst->getDbgRecordRange()) - DPValues.push_back(cast<DPValue>(&DPV)); + SmallVector<DbgVariableRecord *, 2> DbgVariableRecords; + for (DbgRecord &DVR : BInst->getDbgRecordRange()) + DbgVariableRecords.push_back(cast<DbgVariableRecord>(&DVR)); - EXPECT_EQ(DPValues[0]->getVariableLocationOp(0), F.getArg(0)); - Value *SecondDPVValue = DPValues[1]->getVariableLocationOp(0); - ASSERT_TRUE(isa<ConstantInt>(SecondDPVValue)); - EXPECT_EQ(cast<ConstantInt>(SecondDPVValue)->getZExtValue(), 0ull); + EXPECT_EQ(DbgVariableRecords[0]->getVariableLocationOp(0), F.getArg(0)); + Value *SecondDVRValue = DbgVariableRecords[1]->getVariableLocationOp(0); + ASSERT_TRUE(isa<ConstantInt>(SecondDVRValue)); + EXPECT_EQ(cast<ConstantInt>(SecondDVRValue)->getZExtValue(), 0ull); - // No trailing DPValues in the entry block now. + // No trailing DbgVariableRecords in the entry block now. EXPECT_EQ(Entry.getTrailingDbgRecords(), nullptr); UseNewDbgInfoFormat = false; @@ -1444,31 +1449,31 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty2) { BasicBlock &Exit = *Entry.getNextNode(); M->convertToNewDbgValues(); - // Begin by forcing entry block to have dangling DPValue. + // Begin by forcing entry block to have dangling DbgVariableRecord. Entry.getTerminator()->eraseFromParent(); ASSERT_NE(Entry.getTrailingDbgRecords(), nullptr); EXPECT_TRUE(Entry.empty()); // Now transfer into the entry block -- fetching the first instruction with // begin and then calling getIterator clears the "head" bit, meaning that the - // range to move will not include any leading DPValues. + // range to move will not include any leading DbgVariableRecords. Entry.splice(Entry.end(), &Exit, Exit.begin()->getIterator(), Exit.end()); // We should now have one dbg.values on the first instruction, %a. Instruction *BInst = &*Entry.begin(); ASSERT_TRUE(BInst->hasDbgRecords()); EXPECT_EQ(BInst->DbgMarker->StoredDbgRecords.size(), 1u); - SmallVector<DPValue *, 2> DPValues; - for (DbgRecord &DPV : BInst->getDbgRecordRange()) - DPValues.push_back(cast<DPValue>(&DPV)); + SmallVector<DbgVariableRecord *, 2> DbgVariableRecords; + for (DbgRecord &DVR : BInst->getDbgRecordRange()) + DbgVariableRecords.push_back(cast<DbgVariableRecord>(&DVR)); - EXPECT_EQ(DPValues[0]->getVariableLocationOp(0), F.getArg(0)); - // No trailing DPValues in the entry block now. + EXPECT_EQ(DbgVariableRecords[0]->getVariableLocationOp(0), F.getArg(0)); + // No trailing DbgVariableRecords in the entry block now. EXPECT_EQ(Entry.getTrailingDbgRecords(), nullptr); // We should have nothing left in the exit block... EXPECT_TRUE(Exit.empty()); - // ... except for some dangling DPValues. + // ... except for some dangling DbgVariableRecords. EXPECT_NE(Exit.getTrailingDbgRecords(), nullptr); EXPECT_FALSE(Exit.getTrailingDbgRecords()->empty()); Exit.getTrailingDbgRecords()->eraseFromParent(); diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp index 55944b894988..3672f2bccfec 100644 --- a/llvm/unittests/IR/DebugInfoTest.cpp +++ b/llvm/unittests/IR/DebugInfoTest.cpp @@ -234,8 +234,8 @@ TEST(DbgVariableIntrinsic, EmptyMDIsKillLocation) { EXPECT_TRUE(DbgDeclare->isKillLocation()); } -// Duplicate of above test, but in DPValue representation. -TEST(MetadataTest, DeleteInstUsedByDPValue) { +// Duplicate of above test, but in DbgVariableRecord representation. +TEST(MetadataTest, DeleteInstUsedByDbgVariableRecord) { LLVMContext C; std::unique_ptr<Module> M = parseIR(C, R"( define i16 @f(i16 %a) !dbg !6 { @@ -267,26 +267,26 @@ TEST(MetadataTest, DeleteInstUsedByDPValue) { Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHI(); M->convertToNewDbgValues(); - // Find the DPValues using %b. + // Find the DbgVariableRecords using %b. SmallVector<DbgValueInst *, 2> DVIs; - SmallVector<DPValue *, 2> DPVs; - findDbgValues(DVIs, &I, &DPVs); - ASSERT_EQ(DPVs.size(), 2u); + SmallVector<DbgVariableRecord *, 2> DVRs; + findDbgValues(DVIs, &I, &DVRs); + ASSERT_EQ(DVRs.size(), 2u); - // Delete %b. The DPValue should now point to undef. + // Delete %b. The DbgVariableRecord should now point to undef. I.eraseFromParent(); - EXPECT_EQ(DPVs[0]->getNumVariableLocationOps(), 1u); - EXPECT_TRUE(isa<UndefValue>(DPVs[0]->getVariableLocationOp(0))); - EXPECT_TRUE(DPVs[0]->isKillLocation()); - EXPECT_EQ(DPVs[1]->getNumVariableLocationOps(), 2u); - EXPECT_TRUE(isa<UndefValue>(DPVs[1]->getVariableLocationOp(1))); - EXPECT_TRUE(DPVs[1]->isKillLocation()); + EXPECT_EQ(DVRs[0]->getNumVariableLocationOps(), 1u); + EXPECT_TRUE(isa<UndefValue>(DVRs[0]->getVariableLocationOp(0))); + EXPECT_TRUE(DVRs[0]->isKillLocation()); + EXPECT_EQ(DVRs[1]->getNumVariableLocationOps(), 2u); + EXPECT_TRUE(isa<UndefValue>(DVRs[1]->getVariableLocationOp(1))); + EXPECT_TRUE(DVRs[1]->isKillLocation()); UseNewDbgInfoFormat = OldDbgValueMode; } // Ensure that the order of dbg.value intrinsics returned by findDbgValues, and -// their corresponding DPValue representation, are consistent. -TEST(MetadataTest, OrderingOfDPValues) { +// their corresponding DbgVariableRecord representation, are consistent. +TEST(MetadataTest, OrderingOfDbgVariableRecords) { LLVMContext C; std::unique_ptr<Module> M = parseIR(C, R"( define i16 @f(i16 %a) !dbg !6 { @@ -319,10 +319,10 @@ TEST(MetadataTest, OrderingOfDPValues) { Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHI(); SmallVector<DbgValueInst *, 2> DVIs; - SmallVector<DPValue *, 2> DPVs; - findDbgValues(DVIs, &I, &DPVs); + SmallVector<DbgVariableRecord *, 2> DVRs; + findDbgValues(DVIs, &I, &DVRs); ASSERT_EQ(DVIs.size(), 2u); - ASSERT_EQ(DPVs.size(), 0u); + ASSERT_EQ(DVRs.size(), 0u); // The correct order of dbg.values is given by their use-list, which becomes // the reverse order of creation. Thus the dbg.values should come out as @@ -332,17 +332,17 @@ TEST(MetadataTest, OrderingOfDPValues) { DILocalVariable *Var1 = DVIs[1]->getVariable(); EXPECT_TRUE(Var1->getName() == "foo"); - // Now try again, but in DPValue form. + // Now try again, but in DbgVariableRecord form. DVIs.clear(); M->convertToNewDbgValues(); - findDbgValues(DVIs, &I, &DPVs); + findDbgValues(DVIs, &I, &DVRs); ASSERT_EQ(DVIs.size(), 0u); - ASSERT_EQ(DPVs.size(), 2u); + ASSERT_EQ(DVRs.size(), 2u); - Var0 = DPVs[0]->getVariable(); + Var0 = DVRs[0]->getVariable(); EXPECT_TRUE(Var0->getName() == "bar"); - Var1 = DPVs[1]->getVariable(); + Var1 = DVRs[1]->getVariable(); EXPECT_TRUE(Var1->getName() == "foo"); M->convertFromNewDbgValues(); @@ -861,9 +861,9 @@ TEST(AssignmentTrackingTest, InstrMethods) { } } -// Test some very straight-forward operations on DPValues -- these are +// Test some very straight-forward operations on DbgVariableRecords -- these are // dbg.values that have been converted to a non-instruction format. -TEST(MetadataTest, ConvertDbgToDPValue) { +TEST(MetadataTest, ConvertDbgToDbgVariableRecord) { LLVMContext C; std::unique_ptr<Module> M = parseIR(C, R"( define i16 @f(i16 %a) !dbg !6 { @@ -900,7 +900,7 @@ TEST(MetadataTest, ConvertDbgToDPValue) { const DIExpression *Expr = nullptr; const DILocation *Loc = nullptr; const Metadata *MLoc = nullptr; - DPValue *DPV1 = nullptr; + DbgVariableRecord *DVR1 = nullptr; { DbgValueInst *DPI = dyn_cast<DbgValueInst>(&I); ASSERT_TRUE(DPI); @@ -909,17 +909,18 @@ TEST(MetadataTest, ConvertDbgToDPValue) { Loc = DPI->getDebugLoc().get(); MLoc = DPI->getRawLocation(); - // Test the creation of a DPValue and it's conversion back to a dbg.value. - DPV1 = new DPValue(DPI); - EXPECT_EQ(DPV1->getVariable(), Var); - EXPECT_EQ(DPV1->getExpression(), Expr); - EXPECT_EQ(DPV1->getDebugLoc().get(), Loc); - EXPECT_EQ(DPV1->getRawLocation(), MLoc); + // Test the creation of a DbgVariableRecord and it's conversion back to a + // dbg.value. + DVR1 = new DbgVariableRecord(DPI); + EXPECT_EQ(DVR1->getVariable(), Var); + EXPECT_EQ(DVR1->getExpression(), Expr); + EXPECT_EQ(DVR1->getDebugLoc().get(), Loc); + EXPECT_EQ(DVR1->getRawLocation(), MLoc); // Erase dbg.value, DPI->eraseFromParent(); - // Re-create from DPV1, inserting at front. - DPV1->createDebugIntrinsic(&*M, + // Re-create from DVR1, inserting at front. + DVR1->createDebugIntrinsic(&*M, &M->getFunction("f")->getEntryBlock().front()); Instruction *NewDPI = &M->getFunction("f")->getEntryBlock().front(); @@ -931,17 +932,17 @@ TEST(MetadataTest, ConvertDbgToDPValue) { EXPECT_EQ(DPI2->getRawLocation(), MLoc); } - // Fetch the second dbg.value, convert it to a DPValue, + // Fetch the second dbg.value, convert it to a DbgVariableRecord, BasicBlock::iterator It = M->getFunction("f")->getEntryBlock().begin(); It = std::next(std::next(It)); DbgValueInst *DPI3 = dyn_cast<DbgValueInst>(It); ASSERT_TRUE(DPI3); - DPValue *DPV2 = new DPValue(DPI3); + DbgVariableRecord *DVR2 = new DbgVariableRecord(DPI3); // These dbg.values are supposed to refer to different values. - EXPECT_NE(DPV1->getRawLocation(), DPV2->getRawLocation()); + EXPECT_NE(DVR1->getRawLocation(), DVR2->getRawLocation()); - // Try manipulating DPValues and markers in the exit block. + // Try manipulating DbgVariableRecords and markers in the exit block. BasicBlock *ExitBlock = &*std::next(M->getFunction("f")->getEntryBlock().getIterator()); Instruction *FirstInst = &ExitBlock->front(); Instruction *RetInst = &*std::next(FirstInst->getIterator()); @@ -951,45 +952,48 @@ TEST(MetadataTest, ConvertDbgToDPValue) { ExitBlock->createMarker(FirstInst); ExitBlock->createMarker(RetInst); - // Insert DbgRecords into markers, order should come out DPV2, DPV1. - FirstInst->DbgMarker->insertDbgRecord(DPV1, false); - FirstInst->DbgMarker->insertDbgRecord(DPV2, true); + // Insert DbgRecords into markers, order should come out DVR2, DVR1. + FirstInst->DbgMarker->insertDbgRecord(DVR1, false); + FirstInst->DbgMarker->insertDbgRecord(DVR2, true); unsigned int ItCount = 0; for (DbgRecord &Item : FirstInst->DbgMarker->getDbgRecordRange()) { - EXPECT_TRUE((&Item == DPV2 && ItCount == 0) || - (&Item == DPV1 && ItCount == 1)); + EXPECT_TRUE((&Item == DVR2 && ItCount == 0) || + (&Item == DVR1 && ItCount == 1)); EXPECT_EQ(Item.getMarker(), FirstInst->DbgMarker); ++ItCount; } - // Clone them onto the second marker -- should allocate new DPVs. + // Clone them onto the second marker -- should allocate new DVRs. RetInst->DbgMarker->cloneDebugInfoFrom(FirstInst->DbgMarker, std::nullopt, false); EXPECT_EQ(RetInst->DbgMarker->StoredDbgRecords.size(), 2u); ItCount = 0; // Check these things store the same information; but that they're not the same // objects. - for (DPValue &Item : filterDbgVars(RetInst->DbgMarker->getDbgRecordRange())) { - EXPECT_TRUE((Item.getRawLocation() == DPV2->getRawLocation() && ItCount == 0) || - (Item.getRawLocation() == DPV1->getRawLocation() && ItCount == 1)); + for (DbgVariableRecord &Item : + filterDbgVars(RetInst->DbgMarker->getDbgRecordRange())) { + EXPECT_TRUE( + (Item.getRawLocation() == DVR2->getRawLocation() && ItCount == 0) || + (Item.getRawLocation() == DVR1->getRawLocation() && ItCount == 1)); EXPECT_EQ(Item.getMarker(), RetInst->DbgMarker); - EXPECT_NE(&Item, DPV1); - EXPECT_NE(&Item, DPV2); + EXPECT_NE(&Item, DVR1); + EXPECT_NE(&Item, DVR2); ++ItCount; } RetInst->DbgMarker->dropDbgRecords(); EXPECT_EQ(RetInst->DbgMarker->StoredDbgRecords.size(), 0u); - // Try cloning one single DPValue. + // Try cloning one single DbgVariableRecord. auto DIIt = std::next(FirstInst->DbgMarker->getDbgRecordRange().begin()); RetInst->DbgMarker->cloneDebugInfoFrom(FirstInst->DbgMarker, DIIt, false); EXPECT_EQ(RetInst->DbgMarker->StoredDbgRecords.size(), 1u); - // The second DPValue should have been cloned; it should have the same values - // as DPV1. - EXPECT_EQ(cast<DPValue>(RetInst->DbgMarker->StoredDbgRecords.begin()) - ->getRawLocation(), - DPV1->getRawLocation()); + // The second DbgVariableRecord should have been cloned; it should have the + // same values as DVR1. + EXPECT_EQ( + cast<DbgVariableRecord>(RetInst->DbgMarker->StoredDbgRecords.begin()) + ->getRawLocation(), + DVR1->getRawLocation()); // We should be able to drop individual DbgRecords. RetInst->DbgMarker->dropOneDbgRecord( &*RetInst->DbgMarker->StoredDbgRecords.begin()); @@ -998,19 +1002,19 @@ TEST(MetadataTest, ConvertDbgToDPValue) { // to is disappearing so it needs to be transferred into "this" marker. RetInst->DbgMarker->absorbDebugValues(*FirstInst->DbgMarker, true); EXPECT_EQ(RetInst->DbgMarker->StoredDbgRecords.size(), 2u); - // Should be the DPV1 and DPV2 objects. + // Should be the DVR1 and DVR2 objects. ItCount = 0; for (DbgRecord &Item : RetInst->DbgMarker->getDbgRecordRange()) { - EXPECT_TRUE((&Item == DPV2 && ItCount == 0) || - (&Item == DPV1 && ItCount == 1)); + EXPECT_TRUE((&Item == DVR2 && ItCount == 0) || + (&Item == DVR1 && ItCount == 1)); EXPECT_EQ(Item.getMarker(), RetInst->DbgMarker); ++ItCount; } - // Finally -- there are two DPValues left over. If we remove evrything in the - // basic block, then they should sink down into the "TrailingDbgRecords" - // container for dangling debug-info. Future facilities will restore them - // back when a terminator is inserted. + // Finally -- there are two DbgVariableRecords left over. If we remove + // evrything in the basic block, then they should sink down into the + // "TrailingDbgRecords" container for dangling debug-info. Future facilities + // will restore them back when a terminator is inserted. FirstInst->DbgMarker->removeMarker(); FirstInst->eraseFromParent(); RetInst->DbgMarker->removeMarker(); @@ -1019,24 +1023,24 @@ TEST(MetadataTest, ConvertDbgToDPValue) { DPMarker *EndMarker = ExitBlock->getTrailingDbgRecords(); ASSERT_NE(EndMarker, nullptr); EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u); - // Test again that it's those two DPValues, DPV1 and DPV2. + // Test again that it's those two DbgVariableRecords, DVR1 and DVR2. ItCount = 0; for (DbgRecord &Item : EndMarker->getDbgRecordRange()) { - EXPECT_TRUE((&Item == DPV2 && ItCount == 0) || - (&Item == DPV1 && ItCount == 1)); + EXPECT_TRUE((&Item == DVR2 && ItCount == 0) || + (&Item == DVR1 && ItCount == 1)); EXPECT_EQ(Item.getMarker(), EndMarker); ++ItCount; } - // Cleanup the trailing DPValue records and marker. + // Cleanup the trailing DbgVariableRecord records and marker. EndMarker->eraseFromParent(); - // The record of those trailing DPValues would dangle and cause an assertion - // failure if it lived until the end of the LLVMContext. + // The record of those trailing DbgVariableRecords would dangle and cause an + // assertion failure if it lived until the end of the LLVMContext. ExitBlock->deleteTrailingDbgRecords(); } -TEST(MetadataTest, DPValueConversionRoutines) { +TEST(MetadataTest, DbgVariableRecordConversionRoutines) { LLVMContext C; // For the purpose of this test, set and un-set the command line option @@ -1073,14 +1077,14 @@ TEST(MetadataTest, DPValueConversionRoutines) { )"); // Check that the conversion routines and utilities between dbg.value - // debug-info format and DPValues works. + // debug-info format and DbgVariableRecords works. Function *F = M->getFunction("f"); BasicBlock *BB1 = &F->getEntryBlock(); // First instruction should be a dbg.value. EXPECT_TRUE(isa<DbgValueInst>(BB1->front())); EXPECT_FALSE(BB1->IsNewDbgInfoFormat); - // Validating the block for DPValues / DPMarkers shouldn't fail -- there's - // no data stored right now. + // Validating the block for DbgVariableRecords / DPMarkers shouldn't fail -- + // there's no data stored right now. bool BrokenDebugInfo = false; bool Error = verifyModule(*M, &errs(), &BrokenDebugInfo); EXPECT_FALSE(Error); @@ -1104,7 +1108,7 @@ TEST(MetadataTest, DPValueConversionRoutines) { EXPECT_FALSE(isa<DbgValueInst>(I)); // There should be a DPMarker on each of the two instructions in the entry - // block, each containing one DPValue. + // block, each containing one DbgVariableRecord. EXPECT_EQ(BB1->size(), 2u); Instruction *FirstInst = &BB1->front(); Instruction *SecondInst = FirstInst->getNextNode(); @@ -1115,21 +1119,21 @@ TEST(MetadataTest, DPValueConversionRoutines) { EXPECT_EQ(SecondInst, SecondInst->DbgMarker->MarkedInstr); EXPECT_EQ(FirstInst->DbgMarker->StoredDbgRecords.size(), 1u); - DPValue *DPV1 = - cast<DPValue>(&*FirstInst->DbgMarker->getDbgRecordRange().begin()); - EXPECT_EQ(DPV1->getMarker(), FirstInst->DbgMarker); + DbgVariableRecord *DVR1 = cast<DbgVariableRecord>( + &*FirstInst->DbgMarker->getDbgRecordRange().begin()); + EXPECT_EQ(DVR1->getMarker(), FirstInst->DbgMarker); // Should point at %a, an argument. - EXPECT_TRUE(isa<Argument>(DPV1->getVariableLocationOp(0))); + EXPECT_TRUE(isa<Argument>(DVR1->getVariableLocationOp(0))); EXPECT_EQ(SecondInst->DbgMarker->StoredDbgRecords.size(), 1u); - DPValue *DPV2 = - cast<DPValue>(&*SecondInst->DbgMarker->getDbgRecordRange().begin()); - EXPECT_EQ(DPV2->getMarker(), SecondInst->DbgMarker); + DbgVariableRecord *DVR2 = cast<DbgVariableRecord>( + &*SecondInst->DbgMarker->getDbgRecordRange().begin()); + EXPECT_EQ(DVR2->getMarker(), SecondInst->DbgMarker); // Should point at FirstInst. - EXPECT_EQ(DPV2->getVariableLocationOp(0), FirstInst); + EXPECT_EQ(DVR2->getVariableLocationOp(0), FirstInst); - // There should be no DPValues / DPMarkers in the second block, but it should - // be marked as being in the new format. + // There should be no DbgVariableRecords / DPMarkers in the second block, but + // it should be marked as being in the new format. BasicBlock *BB2 = BB1->getNextNode(); EXPECT_TRUE(BB2->IsNewDbgInfoFormat); for (auto &Inst : *BB2) @@ -1143,17 +1147,17 @@ TEST(MetadataTest, DPValueConversionRoutines) { // But if we were to break something, it should be able to fire. Don't attempt // to comprehensively test the validator, it's a smoke-test rather than a // "proper" verification pass. - DPV1->setMarker(nullptr); + DVR1->setMarker(nullptr); // A marker pointing the wrong way should be an error. Error = verifyModule(*M, &errs(), &BrokenDebugInfo); EXPECT_FALSE(Error); EXPECT_TRUE(BrokenDebugInfo); - DPV1->setMarker(FirstInst->DbgMarker); + DVR1->setMarker(FirstInst->DbgMarker); - DILocalVariable *DLV1 = DPV1->getVariable(); - DIExpression *Expr1 = DPV1->getExpression(); - DILocalVariable *DLV2 = DPV2->getVariable(); - DIExpression *Expr2 = DPV2->getExpression(); + DILocalVariable *DLV1 = DVR1->getVariable(); + DIExpression *Expr1 = DVR1->getExpression(); + DILocalVariable *DLV2 = DVR2->getVariable(); + DIExpression *Expr2 = DVR2->getExpression(); // Convert everything back to the "old" format and ensure it's right. M->convertFromNewDbgValues(); diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp index 77bd93569ea9..ec3059821230 100644 --- a/llvm/unittests/IR/IRBuilderTest.cpp +++ b/llvm/unittests/IR/IRBuilderTest.cpp @@ -944,7 +944,7 @@ TEST_F(IRBuilderTest, DIBuilder) { DIB.createAutoVariable(BarSP, "X", File, 2, IntType, true); DILocalVariable *VarY = DIB.createAutoVariable(BarSP, "Y", File, 2, IntType, true); - { /* dbg.value | DPValue::Value */ + { /* dbg.value | DbgVariableRecord::Value */ ExpectOrder(DIB.insertDbgValueIntrinsic(I, VarX, DIB.createExpression(), VarLoc, I), I->getIterator()); @@ -955,7 +955,7 @@ TEST_F(IRBuilderTest, DIBuilder) { ExpectOrder(VarXValue, I->getIterator()); EXPECT_EQ(BB->getTrailingDbgRecords(), nullptr); } - { /* dbg.declare | DPValue::Declare */ + { /* dbg.declare | DbgVariableRecord::Declare */ ExpectOrder(DIB.insertDeclare(I, VarY, DIB.createExpression(), VarLoc, I), I->getIterator()); // Check inserting at end of the block works as with labels. @@ -965,7 +965,7 @@ TEST_F(IRBuilderTest, DIBuilder) { ExpectOrder(VarYDeclare, I->getIterator()); EXPECT_EQ(BB->getTrailingDbgRecords(), nullptr); } - { /* dbg.assign | DPValue::Assign */ + { /* dbg.assign | DbgVariableRecord::Assign */ I = Builder.CreateAlloca(Builder.getInt32Ty()); I->setMetadata(LLVMContext::MD_DIAssignID, DIAssignID::getDistinct(Ctx)); // DbgAssign interface is slightly different - it always inserts after the diff --git a/llvm/unittests/IR/ValueTest.cpp b/llvm/unittests/IR/ValueTest.cpp index 97c8fea3c6db..246c2fc7fe40 100644 --- a/llvm/unittests/IR/ValueTest.cpp +++ b/llvm/unittests/IR/ValueTest.cpp @@ -317,9 +317,9 @@ TEST(ValueTest, replaceUsesOutsideBlock) { ASSERT_TRUE(Ret->getOperand(0) == cast<Value>(B)); } -TEST(ValueTest, replaceUsesOutsideBlockDPValue) { +TEST(ValueTest, replaceUsesOutsideBlockDbgVariableRecord) { // Check that Value::replaceUsesOutsideBlock(New, BB) replaces uses outside - // BB, including DPValues. + // BB, including DbgVariableRecords. const auto *IR = R"( define i32 @f() !dbg !6 { entry: @@ -379,14 +379,16 @@ TEST(ValueTest, replaceUsesOutsideBlockDPValue) { EXPECT_TRUE(Branch->hasDbgRecords()); EXPECT_TRUE(Ret->hasDbgRecords()); - DPValue *DPV1 = cast<DPValue>(&*Branch->getDbgRecordRange().begin()); - DPValue *DPV2 = cast<DPValue>(&*Ret->getDbgRecordRange().begin()); + DbgVariableRecord *DVR1 = + cast<DbgVariableRecord>(&*Branch->getDbgRecordRange().begin()); + DbgVariableRecord *DVR2 = + cast<DbgVariableRecord>(&*Ret->getDbgRecordRange().begin()); A->replaceUsesOutsideBlock(B, Entry); // These users are in Entry so shouldn't be changed. - EXPECT_TRUE(DPV1->getVariableLocationOp(0) == cast<Value>(A)); + EXPECT_TRUE(DVR1->getVariableLocationOp(0) == cast<Value>(A)); // These users are outside Entry so should be changed. - EXPECT_TRUE(DPV2->getVariableLocationOp(0) == cast<Value>(B)); + EXPECT_TRUE(DVR2->getVariableLocationOp(0) == cast<Value>(B)); UseNewDbgInfoFormat = OldDbgValueMode; } diff --git a/llvm/unittests/Transforms/Utils/LocalTest.cpp b/llvm/unittests/Transforms/Utils/LocalTest.cpp index 87a2a2ae4700..4258f218794f 100644 --- a/llvm/unittests/Transforms/Utils/LocalTest.cpp +++ b/llvm/unittests/Transforms/Utils/LocalTest.cpp @@ -1279,11 +1279,11 @@ TEST(Local, ExpressionForConstant) { EXPECT_EQ(Expr, nullptr); } -TEST(Local, ReplaceDPValue) { +TEST(Local, ReplaceDbgVariableRecord) { LLVMContext C; - // Test that RAUW also replaces the operands of DPValue objects, i.e. - // non-instruction stored debugging information. + // Test that RAUW also replaces the operands of DbgVariableRecord objects, + // i.e. non-instruction stored debugging information. std::unique_ptr<Module> M = parseIR(C, R"( declare void @llvm.dbg.value(metadata, metadata, metadata) @@ -1323,24 +1323,23 @@ TEST(Local, ReplaceDPValue) { It = std::next(It); Instruction *RetInst = &*It; - // Convert DVI into a DPValue. + // Convert DVI into a DbgVariableRecord. RetInst->DbgMarker = new DPMarker(); RetInst->DbgMarker->MarkedInstr = RetInst; - DPValue *DPV = new DPValue(DVI); - RetInst->DbgMarker->insertDbgRecord(DPV, false); + DbgVariableRecord *DVR = new DbgVariableRecord(DVI); + RetInst->DbgMarker->insertDbgRecord(DVR, false); // ... and erase the dbg.value. DVI->eraseFromParent(); - // DPV should originally refer to %bar, - EXPECT_EQ(DPV->getVariableLocationOp(0), BarInst); + // DVR should originally refer to %bar, + EXPECT_EQ(DVR->getVariableLocationOp(0), BarInst); // Now try to replace the computation of %bar with %foo -- this should cause - // the DPValue's to have it's operand updated beneath it. + // the DbgVariableRecord's to have it's operand updated beneath it. BarInst->replaceAllUsesWith(FooInst); - // Check DPV now points at %foo. - EXPECT_EQ(DPV->getVariableLocationOp(0), FooInst); + // Check DVR now points at %foo. + EXPECT_EQ(DVR->getVariableLocationOp(0), FooInst); // Teardown. RetInst->DbgMarker->eraseFromParent(); } - -- GitLab From cd34860705607ba804e20753f3ef4f2d4392df57 Mon Sep 17 00:00:00 2001 From: alx32 <103613512+alx32@users.noreply.github.com> Date: Tue, 19 Mar 2024 13:14:29 -0700 Subject: [PATCH 142/307] [lld-macho] Implement ObjC category merging (-objc_category_merging) (#85727) This change adds a flag to lld to enable category merging for MachoO + ObjC. It adds the '-objc_category_merging' flag for enabling this option and uses the existing '-no_objc_category_merging' flag for disabling it. In ld64, this optimization is enabled by default, but in lld, for now, we require explicitly passing the '-objc_category_merging' flag in order to enable it. Behavior: if in the same link unit, multiple categories are extending the same class, then they get merged into a single category. Ex: Cat1(method1+method2,protocol1) + Cat2(method3+method4,protocol2, property1) = Cat1_2(method1+method2+method3+method4, protocol1+protocol2, property1) Notes on implementation decisions made in this diff: There is a possibility to further improve the current implementation by directly merging the category data into the base class (if the base class is present in the link unit) - this improvement may be done as a follow-up. This improved functionality is already present in ld64. We do the merging on the raw inputSections - after dead-stripping (categories can't be dead stripped anyway). The changes are mostly self-contained to ObjC.cpp, except for adding a new flag (linkerOptimizeReason) to ConcatInputSection and StringPiece to mark that this data has been optimized away. Another way to do it would have been to just mark the pieces as not 'live' but this would cause the old symbols to show up in the linker map as being dead-stripped - even if dead-stripping is disabled. This flag allows us to match the ld64 behavior. Note: This is a re-land of https://github.com/llvm/llvm-project/pull/82928 after fixing using already freed memory in `generatedSectionData`. This issue was detected by ASAN build. --------- Co-authored-by: Alex B <alexborcan@meta.com> --- lld/MachO/Driver.cpp | 9 + lld/MachO/InputSection.h | 2 +- lld/MachO/ObjC.cpp | 929 +++++++++++++++++- lld/MachO/ObjC.h | 12 + lld/MachO/Options.td | 10 +- .../objc-category-merging-complete-test.s | 762 ++++++++++++++ ...jc-category-merging-extern-class-minimal.s | 155 +++ 7 files changed, 1871 insertions(+), 8 deletions(-) create mode 100644 lld/test/MachO/objc-category-merging-complete-test.s create mode 100644 lld/test/MachO/objc-category-merging-extern-class-minimal.s diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 9edb6b9c60a1..36248925d65a 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1437,6 +1437,8 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS, resetOutputSegments(); resetWriter(); InputFile::resetIdCount(); + + objc::doCleanup(); }; ctx->e.logName = args::getFilenameWithoutExe(argsArr[0]); @@ -1979,9 +1981,16 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS, if (config->deadStrip) markLive(); + // Categories are not subject to dead-strip. The __objc_catlist section is + // marked as NO_DEAD_STRIP and that propagates into all category data. if (args.hasArg(OPT_check_category_conflicts)) objc::checkCategories(); + // Category merging uses "->live = false" to erase old category data, so + // it has to run after dead-stripping (markLive). + if (args.hasArg(OPT_objc_category_merging, OPT_no_objc_category_merging)) + objc::mergeCategories(); + // ICF assumes that all literals have been folded already, so we must run // foldIdenticalLiterals before foldIdenticalSections. foldIdenticalLiterals(); diff --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h index becb01017d63..b25f0638f4c6 100644 --- a/lld/MachO/InputSection.h +++ b/lld/MachO/InputSection.h @@ -93,9 +93,9 @@ public: // .subsections_via_symbols, there is typically only one element here. llvm::TinyPtrVector<Defined *> symbols; -protected: const Section §ion; +protected: const Defined *getContainingSymbol(uint64_t off) const; }; diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp index 67254ec53a21..f54127638b86 100644 --- a/lld/MachO/ObjC.cpp +++ b/lld/MachO/ObjC.cpp @@ -7,16 +7,19 @@ //===----------------------------------------------------------------------===// #include "ObjC.h" +#include "ConcatOutputSection.h" #include "InputFiles.h" #include "InputSection.h" #include "Layout.h" #include "OutputSegment.h" +#include "SyntheticSections.h" #include "Target.h" #include "lld/Common/ErrorHandler.h" #include "llvm/ADT/DenseMap.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/Bitcode/BitcodeReader.h" +#include "llvm/Support/TimeProfiler.h" using namespace llvm; using namespace llvm::MachO; @@ -78,7 +81,8 @@ namespace { DO(Ptr, classMethods) \ DO(Ptr, protocols) \ DO(Ptr, instanceProps) \ - DO(Ptr, classProps) + DO(Ptr, classProps) \ + DO(uint32_t, size) CREATE_LAYOUT_CLASS(Category, FOR_EACH_CATEGORY_FIELD); @@ -112,13 +116,19 @@ CREATE_LAYOUT_CLASS(ROClass, FOR_EACH_RO_CLASS_FIELD); #undef FOR_EACH_RO_CLASS_FIELD #define FOR_EACH_LIST_HEADER(DO) \ - DO(uint32_t, size) \ - DO(uint32_t, count) + DO(uint32_t, structSize) \ + DO(uint32_t, structCount) CREATE_LAYOUT_CLASS(ListHeader, FOR_EACH_LIST_HEADER); #undef FOR_EACH_LIST_HEADER +#define FOR_EACH_PROTOCOL_LIST_HEADER(DO) DO(Ptr, protocolCount) + +CREATE_LAYOUT_CLASS(ProtocolListHeader, FOR_EACH_PROTOCOL_LIST_HEADER); + +#undef FOR_EACH_PROTOCOL_LIST_HEADER + #define FOR_EACH_METHOD(DO) \ DO(Ptr, name) \ DO(Ptr, type) \ @@ -311,6 +321,8 @@ void ObjcCategoryChecker::parseClass(const Defined *classSym) { } void objc::checkCategories() { + TimeTraceScope timeScope("ObjcCategoryChecker"); + ObjcCategoryChecker checker; for (const InputSection *isec : inputSections) { if (isec->getName() == section_names::objcCatList) @@ -320,3 +332,914 @@ void objc::checkCategories() { } } } + +namespace { + +class ObjcCategoryMerger { + // Information about an input category + struct InfoInputCategory { + ConcatInputSection *catListIsec; + ConcatInputSection *catBodyIsec; + uint32_t offCatListIsec = 0; + + bool wasMerged = false; + }; + + // To write new (merged) categories or classes, we will try make limited + // assumptions about the alignment and the sections the various class/category + // info are stored in and . So we'll just reuse the same sections and + // alignment as already used in existing (input) categories. To do this we + // have InfoCategoryWriter which contains the various sections that the + // generated categories will be written to. + template <typename T> struct InfoWriteSection { + bool valid = false; // Data has been successfully collected from input + uint32_t align = 0; + Section *inputSection; + Reloc relocTemplate; + T *outputSection; + }; + + struct InfoCategoryWriter { + InfoWriteSection<ConcatOutputSection> catListInfo; + InfoWriteSection<ConcatOutputSection> catBodyInfo; + InfoWriteSection<CStringSection> catNameInfo; + InfoWriteSection<ConcatOutputSection> catPtrListInfo; + }; + + // Information about a pointer list in the original categories (method lists, + // protocol lists, etc) + struct PointerListInfo { + PointerListInfo(const char *_categoryPrefix, uint32_t _categoryOffset, + uint32_t _pointersPerStruct) + : categoryPrefix(_categoryPrefix), categoryOffset(_categoryOffset), + pointersPerStruct(_pointersPerStruct) {} + const char *categoryPrefix; + uint32_t categoryOffset = 0; + + uint32_t pointersPerStruct = 0; + + uint32_t structSize = 0; + uint32_t structCount = 0; + + std::vector<Symbol *> allPtrs; + }; + + // Full information about all the categories that extend a class. This will + // include all the additional methods, protocols, and properties that are + // contained in all the categories that extend a particular class. + struct ClassExtensionInfo { + ClassExtensionInfo(CategoryLayout &_catLayout) : catLayout(_catLayout){}; + + // Merged names of containers. Ex: base|firstCategory|secondCategory|... + std::string mergedContainerName; + std::string baseClassName; + Symbol *baseClass = nullptr; + CategoryLayout &catLayout; + + // In case we generate new data, mark the new data as belonging to this file + ObjFile *objFileForMergeData = nullptr; + + PointerListInfo instanceMethods = { + objc::symbol_names::categoryInstanceMethods, + /*_categoryOffset=*/catLayout.instanceMethodsOffset, + /*pointersPerStruct=*/3}; + PointerListInfo classMethods = { + objc::symbol_names::categoryClassMethods, + /*_categoryOffset=*/catLayout.classMethodsOffset, + /*pointersPerStruct=*/3}; + PointerListInfo protocols = {objc::symbol_names::categoryProtocols, + /*_categoryOffset=*/catLayout.protocolsOffset, + /*pointersPerStruct=*/0}; + PointerListInfo instanceProps = { + objc::symbol_names::listProprieties, + /*_categoryOffset=*/catLayout.instancePropsOffset, + /*pointersPerStruct=*/2}; + PointerListInfo classProps = { + objc::symbol_names::klassPropList, + /*_categoryOffset=*/catLayout.classPropsOffset, + /*pointersPerStruct=*/2}; + }; + +public: + ObjcCategoryMerger(std::vector<ConcatInputSection *> &_allInputSections); + void doMerge(); + static void doCleanup(); + +private: + void collectAndValidateCategoriesData(); + void + mergeCategoriesIntoSingleCategory(std::vector<InfoInputCategory> &categories); + + void eraseISec(ConcatInputSection *isec); + void eraseMergedCategories(); + + void generateCatListForNonErasedCategories( + std::map<ConcatInputSection *, std::set<uint64_t>> + catListToErasedOffsets); + template <typename T> + void collectSectionWriteInfoFromIsec(const InputSection *isec, + InfoWriteSection<T> &catWriteInfo); + void collectCategoryWriterInfoFromCategory(const InfoInputCategory &catInfo); + void parseCatInfoToExtInfo(const InfoInputCategory &catInfo, + ClassExtensionInfo &extInfo); + + void parseProtocolListInfo(const ConcatInputSection *isec, uint32_t secOffset, + PointerListInfo &ptrList); + + void parsePointerListInfo(const ConcatInputSection *isec, uint32_t secOffset, + PointerListInfo &ptrList); + + void emitAndLinkPointerList(Defined *parentSym, uint32_t linkAtOffset, + const ClassExtensionInfo &extInfo, + const PointerListInfo &ptrList); + + void emitAndLinkProtocolList(Defined *parentSym, uint32_t linkAtOffset, + const ClassExtensionInfo &extInfo, + const PointerListInfo &ptrList); + + Defined *emitCategory(const ClassExtensionInfo &extInfo); + Defined *emitCatListEntrySec(const std::string &forCateogryName, + const std::string &forBaseClassName, + ObjFile *objFile); + Defined *emitCategoryBody(const std::string &name, const Defined *nameSym, + const Symbol *baseClassSym, + const std::string &baseClassName, ObjFile *objFile); + Defined *emitCategoryName(const std::string &name, ObjFile *objFile); + void createSymbolReference(Defined *refFrom, const Symbol *refTo, + uint32_t offset, const Reloc &relocTemplate); + Symbol *tryGetSymbolAtIsecOffset(const ConcatInputSection *isec, + uint32_t offset); + Defined *tryGetDefinedAtIsecOffset(const ConcatInputSection *isec, + uint32_t offset); + void tryEraseDefinedAtIsecOffset(const ConcatInputSection *isec, + uint32_t offset); + + // Allocate a null-terminated StringRef backed by generatedSectionData + StringRef newStringData(const char *str); + // Allocate section data, backed by generatedSectionData + SmallVector<uint8_t> &newSectionData(uint32_t size); + + CategoryLayout catLayout; + ClassLayout classLayout; + ROClassLayout roClassLayout; + ListHeaderLayout listHeaderLayout; + MethodLayout methodLayout; + ProtocolListHeaderLayout protocolListHeaderLayout; + + InfoCategoryWriter infoCategoryWriter; + std::vector<ConcatInputSection *> &allInputSections; + // Map of base class Symbol to list of InfoInputCategory's for it + DenseMap<const Symbol *, std::vector<InfoInputCategory>> categoryMap; + + // Normally, the binary data comes from the input files, but since we're + // generating binary data ourselves, we use the below array to store it in. + // Need this to be 'static' so the data survives past the ObjcCategoryMerger + // object, as the data will be read by the Writer when the final binary is + // generated. + static SmallVector<std::unique_ptr<SmallVector<uint8_t>>> + generatedSectionData; +}; + +SmallVector<std::unique_ptr<SmallVector<uint8_t>>> + ObjcCategoryMerger::generatedSectionData; + +ObjcCategoryMerger::ObjcCategoryMerger( + std::vector<ConcatInputSection *> &_allInputSections) + : catLayout(target->wordSize), classLayout(target->wordSize), + roClassLayout(target->wordSize), listHeaderLayout(target->wordSize), + methodLayout(target->wordSize), + protocolListHeaderLayout(target->wordSize), + allInputSections(_allInputSections) {} + +// This is a template so that it can be used both for CStringSection and +// ConcatOutputSection +template <typename T> +void ObjcCategoryMerger::collectSectionWriteInfoFromIsec( + const InputSection *isec, InfoWriteSection<T> &catWriteInfo) { + + catWriteInfo.inputSection = const_cast<Section *>(&isec->section); + catWriteInfo.align = isec->align; + catWriteInfo.outputSection = dyn_cast_or_null<T>(isec->parent); + + assert(catWriteInfo.outputSection && + "outputSection may not be null in collectSectionWriteInfoFromIsec."); + + if (isec->relocs.size()) + catWriteInfo.relocTemplate = isec->relocs[0]; + + catWriteInfo.valid = true; +} + +Symbol * +ObjcCategoryMerger::tryGetSymbolAtIsecOffset(const ConcatInputSection *isec, + uint32_t offset) { + const Reloc *reloc = isec->getRelocAt(offset); + + if (!reloc) + return nullptr; + + return reloc->referent.get<Symbol *>(); +} + +Defined * +ObjcCategoryMerger::tryGetDefinedAtIsecOffset(const ConcatInputSection *isec, + uint32_t offset) { + Symbol *sym = tryGetSymbolAtIsecOffset(isec, offset); + return dyn_cast_or_null<Defined>(sym); +} + +// Given an ConcatInputSection or CStringInputSection and an offset, if there is +// a symbol(Defined) at that offset, then erase the symbol (mark it not live) +void ObjcCategoryMerger::tryEraseDefinedAtIsecOffset( + const ConcatInputSection *isec, uint32_t offset) { + const Reloc *reloc = isec->getRelocAt(offset); + + if (!reloc) + return; + + Defined *sym = dyn_cast_or_null<Defined>(reloc->referent.get<Symbol *>()); + if (!sym) + return; + + if (auto *cisec = dyn_cast_or_null<ConcatInputSection>(sym->isec)) + eraseISec(cisec); + else if (auto *csisec = dyn_cast_or_null<CStringInputSection>(sym->isec)) { + uint32_t totalOffset = sym->value + reloc->addend; + StringPiece &piece = csisec->getStringPiece(totalOffset); + piece.live = false; + } else { + llvm_unreachable("erased symbol has to be Defined or CStringInputSection"); + } +} + +void ObjcCategoryMerger::collectCategoryWriterInfoFromCategory( + const InfoInputCategory &catInfo) { + + if (!infoCategoryWriter.catListInfo.valid) + collectSectionWriteInfoFromIsec<ConcatOutputSection>( + catInfo.catListIsec, infoCategoryWriter.catListInfo); + if (!infoCategoryWriter.catBodyInfo.valid) + collectSectionWriteInfoFromIsec<ConcatOutputSection>( + catInfo.catBodyIsec, infoCategoryWriter.catBodyInfo); + + if (!infoCategoryWriter.catNameInfo.valid) { + lld::macho::Defined *catNameSym = + tryGetDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset); + assert(catNameSym && "Category does not have a valid name Symbol"); + + collectSectionWriteInfoFromIsec<CStringSection>( + catNameSym->isec, infoCategoryWriter.catNameInfo); + } + + // Collect writer info from all the category lists (we're assuming they all + // would provide the same info) + if (!infoCategoryWriter.catPtrListInfo.valid) { + for (uint32_t off = catLayout.instanceMethodsOffset; + off <= catLayout.classPropsOffset; off += target->wordSize) { + if (Defined *ptrList = + tryGetDefinedAtIsecOffset(catInfo.catBodyIsec, off)) { + collectSectionWriteInfoFromIsec<ConcatOutputSection>( + ptrList->isec, infoCategoryWriter.catPtrListInfo); + // we've successfully collected data, so we can break + break; + } + } + } +} + +// Parse a protocol list that might be linked to ConcatInputSection at a given +// offset. The format of the protocol list is different than other lists (prop +// lists, method lists) so we need to parse it differently +void ObjcCategoryMerger::parseProtocolListInfo(const ConcatInputSection *isec, + uint32_t secOffset, + PointerListInfo &ptrList) { + if (!isec || (secOffset + target->wordSize > isec->data.size())) + assert("Tried to read pointer list beyond protocol section end"); + + const Reloc *reloc = isec->getRelocAt(secOffset); + if (!reloc) + return; + + auto *ptrListSym = dyn_cast_or_null<Defined>(reloc->referent.get<Symbol *>()); + assert(ptrListSym && "Protocol list reloc does not have a valid Defined"); + + // Theoretically protocol count can be either 32b or 64b, depending on + // platform pointer size, but to simplify implementation we always just read + // the lower 32b which should be good enough. + uint32_t protocolCount = *reinterpret_cast<const uint32_t *>( + ptrListSym->isec->data.data() + listHeaderLayout.structSizeOffset); + + ptrList.structCount += protocolCount; + ptrList.structSize = target->wordSize; + + uint32_t expectedListSize = + (protocolCount * target->wordSize) + + /*header(count)*/ protocolListHeaderLayout.totalSize + + /*extra null value*/ target->wordSize; + assert(expectedListSize == ptrListSym->isec->data.size() && + "Protocol list does not match expected size"); + + // Suppress unsuded var warning + (void)expectedListSize; + + uint32_t off = protocolListHeaderLayout.totalSize; + for (uint32_t inx = 0; inx < protocolCount; ++inx) { + const Reloc *reloc = ptrListSym->isec->getRelocAt(off); + assert(reloc && "No reloc found at protocol list offset"); + + auto *listSym = dyn_cast_or_null<Defined>(reloc->referent.get<Symbol *>()); + assert(listSym && "Protocol list reloc does not have a valid Defined"); + + ptrList.allPtrs.push_back(listSym); + off += target->wordSize; + } + assert((ptrListSym->isec->getRelocAt(off) == nullptr) && + "expected null terminating protocol"); + assert(off + /*extra null value*/ target->wordSize == expectedListSize && + "Protocol list end offset does not match expected size"); +} + +// Parse a pointer list that might be linked to ConcatInputSection at a given +// offset. This can be used for instance methods, class methods, instance props +// and class props since they have the same format. +void ObjcCategoryMerger::parsePointerListInfo(const ConcatInputSection *isec, + uint32_t secOffset, + PointerListInfo &ptrList) { + assert(ptrList.pointersPerStruct == 2 || ptrList.pointersPerStruct == 3); + assert(isec && "Trying to parse pointer list from null isec"); + assert(secOffset + target->wordSize <= isec->data.size() && + "Trying to read pointer list beyond section end"); + + const Reloc *reloc = isec->getRelocAt(secOffset); + if (!reloc) + return; + + auto *ptrListSym = dyn_cast_or_null<Defined>(reloc->referent.get<Symbol *>()); + assert(ptrListSym && "Reloc does not have a valid Defined"); + + uint32_t thisStructSize = *reinterpret_cast<const uint32_t *>( + ptrListSym->isec->data.data() + listHeaderLayout.structSizeOffset); + uint32_t thisStructCount = *reinterpret_cast<const uint32_t *>( + ptrListSym->isec->data.data() + listHeaderLayout.structCountOffset); + assert(thisStructSize == ptrList.pointersPerStruct * target->wordSize); + + assert(!ptrList.structSize || (thisStructSize == ptrList.structSize)); + + ptrList.structCount += thisStructCount; + ptrList.structSize = thisStructSize; + + uint32_t expectedListSize = + listHeaderLayout.totalSize + (thisStructSize * thisStructCount); + assert(expectedListSize == ptrListSym->isec->data.size() && + "Pointer list does not match expected size"); + + for (uint32_t off = listHeaderLayout.totalSize; off < expectedListSize; + off += target->wordSize) { + const Reloc *reloc = ptrListSym->isec->getRelocAt(off); + assert(reloc && "No reloc found at pointer list offset"); + + auto *listSym = dyn_cast_or_null<Defined>(reloc->referent.get<Symbol *>()); + assert(listSym && "Reloc does not have a valid Defined"); + + ptrList.allPtrs.push_back(listSym); + } +} + +// Here we parse all the information of an input category (catInfo) and +// append the parsed info into the structure which will contain all the +// information about how a class is extended (extInfo) +void ObjcCategoryMerger::parseCatInfoToExtInfo(const InfoInputCategory &catInfo, + ClassExtensionInfo &extInfo) { + const Reloc *catNameReloc = + catInfo.catBodyIsec->getRelocAt(catLayout.nameOffset); + + // Parse name + assert(catNameReloc && "Category does not have a reloc at 'nameOffset'"); + + // is this the first category we are parsing? + if (extInfo.mergedContainerName.empty()) + extInfo.objFileForMergeData = + dyn_cast_or_null<ObjFile>(catInfo.catBodyIsec->getFile()); + else + extInfo.mergedContainerName += "|"; + + assert(extInfo.objFileForMergeData && + "Expected to already have valid objextInfo.objFileForMergeData"); + + StringRef catName = getReferentString(*catNameReloc); + extInfo.mergedContainerName += catName.str(); + + // Parse base class + if (!extInfo.baseClass) { + Symbol *classSym = + tryGetSymbolAtIsecOffset(catInfo.catBodyIsec, catLayout.klassOffset); + assert(extInfo.baseClassName.empty()); + extInfo.baseClass = classSym; + llvm::StringRef classPrefix(objc::symbol_names::klass); + assert(classSym->getName().starts_with(classPrefix) && + "Base class symbol does not start with expected prefix"); + extInfo.baseClassName = classSym->getName().substr(classPrefix.size()); + } else { + assert((extInfo.baseClass == + tryGetSymbolAtIsecOffset(catInfo.catBodyIsec, + catLayout.klassOffset)) && + "Trying to parse category info into container with different base " + "class"); + } + + parsePointerListInfo(catInfo.catBodyIsec, catLayout.instanceMethodsOffset, + extInfo.instanceMethods); + + parsePointerListInfo(catInfo.catBodyIsec, catLayout.classMethodsOffset, + extInfo.classMethods); + + parseProtocolListInfo(catInfo.catBodyIsec, catLayout.protocolsOffset, + extInfo.protocols); + + parsePointerListInfo(catInfo.catBodyIsec, catLayout.instancePropsOffset, + extInfo.instanceProps); + + parsePointerListInfo(catInfo.catBodyIsec, catLayout.classPropsOffset, + extInfo.classProps); +} + +// Generate a protocol list (including header) and link it into the parent at +// the specified offset. +void ObjcCategoryMerger::emitAndLinkProtocolList( + Defined *parentSym, uint32_t linkAtOffset, + const ClassExtensionInfo &extInfo, const PointerListInfo &ptrList) { + if (ptrList.allPtrs.empty()) + return; + + assert(ptrList.allPtrs.size() == ptrList.structCount); + + uint32_t bodySize = (ptrList.structCount * target->wordSize) + + /*header(count)*/ protocolListHeaderLayout.totalSize + + /*extra null value*/ target->wordSize; + llvm::ArrayRef<uint8_t> bodyData = newSectionData(bodySize); + + // This theoretically can be either 32b or 64b, but writing just the first 32b + // is good enough + const uint32_t *ptrProtoCount = reinterpret_cast<const uint32_t *>( + bodyData.data() + protocolListHeaderLayout.protocolCountOffset); + + *const_cast<uint32_t *>(ptrProtoCount) = ptrList.allPtrs.size(); + + ConcatInputSection *listSec = make<ConcatInputSection>( + *infoCategoryWriter.catPtrListInfo.inputSection, bodyData, + infoCategoryWriter.catPtrListInfo.align); + listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection; + listSec->live = true; + allInputSections.push_back(listSec); + + listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection; + + std::string symName = ptrList.categoryPrefix; + symName += extInfo.baseClassName + "_$_(" + extInfo.mergedContainerName + ")"; + + Defined *ptrListSym = make<Defined>( + newStringData(symName.c_str()), /*file=*/parentSym->getObjectFile(), + listSec, /*value=*/0, bodyData.size(), /*isWeakDef=*/false, + /*isExternal=*/false, /*isPrivateExtern=*/false, /*includeInSymtab=*/true, + /*isReferencedDynamically=*/false, /*noDeadStrip=*/false, + /*isWeakDefCanBeHidden=*/false); + + ptrListSym->used = true; + parentSym->getObjectFile()->symbols.push_back(ptrListSym); + + createSymbolReference(parentSym, ptrListSym, linkAtOffset, + infoCategoryWriter.catBodyInfo.relocTemplate); + + uint32_t offset = protocolListHeaderLayout.totalSize; + for (Symbol *symbol : ptrList.allPtrs) { + createSymbolReference(ptrListSym, symbol, offset, + infoCategoryWriter.catPtrListInfo.relocTemplate); + offset += target->wordSize; + } +} + +// Generate a pointer list (including header) and link it into the parent at the +// specified offset. This is used for instance and class methods and +// proprieties. +void ObjcCategoryMerger::emitAndLinkPointerList( + Defined *parentSym, uint32_t linkAtOffset, + const ClassExtensionInfo &extInfo, const PointerListInfo &ptrList) { + if (ptrList.allPtrs.empty()) + return; + + assert(ptrList.allPtrs.size() * target->wordSize == + ptrList.structCount * ptrList.structSize); + + // Generate body + uint32_t bodySize = + listHeaderLayout.totalSize + (ptrList.structSize * ptrList.structCount); + llvm::ArrayRef<uint8_t> bodyData = newSectionData(bodySize); + + const uint32_t *ptrStructSize = reinterpret_cast<const uint32_t *>( + bodyData.data() + listHeaderLayout.structSizeOffset); + const uint32_t *ptrStructCount = reinterpret_cast<const uint32_t *>( + bodyData.data() + listHeaderLayout.structCountOffset); + + *const_cast<uint32_t *>(ptrStructSize) = ptrList.structSize; + *const_cast<uint32_t *>(ptrStructCount) = ptrList.structCount; + + ConcatInputSection *listSec = make<ConcatInputSection>( + *infoCategoryWriter.catPtrListInfo.inputSection, bodyData, + infoCategoryWriter.catPtrListInfo.align); + listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection; + listSec->live = true; + allInputSections.push_back(listSec); + + listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection; + + std::string symName = ptrList.categoryPrefix; + symName += extInfo.baseClassName + "_$_" + extInfo.mergedContainerName; + + Defined *ptrListSym = make<Defined>( + newStringData(symName.c_str()), /*file=*/parentSym->getObjectFile(), + listSec, /*value=*/0, bodyData.size(), /*isWeakDef=*/false, + /*isExternal=*/false, /*isPrivateExtern=*/false, /*includeInSymtab=*/true, + /*isReferencedDynamically=*/false, /*noDeadStrip=*/false, + /*isWeakDefCanBeHidden=*/false); + + ptrListSym->used = true; + parentSym->getObjectFile()->symbols.push_back(ptrListSym); + + createSymbolReference(parentSym, ptrListSym, linkAtOffset, + infoCategoryWriter.catBodyInfo.relocTemplate); + + uint32_t offset = listHeaderLayout.totalSize; + for (Symbol *symbol : ptrList.allPtrs) { + createSymbolReference(ptrListSym, symbol, offset, + infoCategoryWriter.catPtrListInfo.relocTemplate); + offset += target->wordSize; + } +} + +// This method creates an __objc_catlist ConcatInputSection with a single slot +Defined * +ObjcCategoryMerger::emitCatListEntrySec(const std::string &forCateogryName, + const std::string &forBaseClassName, + ObjFile *objFile) { + uint32_t sectionSize = target->wordSize; + llvm::ArrayRef<uint8_t> bodyData = newSectionData(sectionSize); + + ConcatInputSection *newCatList = + make<ConcatInputSection>(*infoCategoryWriter.catListInfo.inputSection, + bodyData, infoCategoryWriter.catListInfo.align); + newCatList->parent = infoCategoryWriter.catListInfo.outputSection; + newCatList->live = true; + allInputSections.push_back(newCatList); + + newCatList->parent = infoCategoryWriter.catListInfo.outputSection; + + std::string catSymName = "<__objc_catlist slot for merged category "; + catSymName += forBaseClassName + "(" + forCateogryName + ")>"; + + Defined *catListSym = make<Defined>( + newStringData(catSymName.c_str()), /*file=*/objFile, newCatList, + /*value=*/0, bodyData.size(), /*isWeakDef=*/false, /*isExternal=*/false, + /*isPrivateExtern=*/false, /*includeInSymtab=*/false, + /*isReferencedDynamically=*/false, /*noDeadStrip=*/false, + /*isWeakDefCanBeHidden=*/false); + + catListSym->used = true; + objFile->symbols.push_back(catListSym); + return catListSym; +} + +// Here we generate the main category body and link the name and base class into +// it. We don't link any other info yet like the protocol and class/instance +// methods/props. +Defined *ObjcCategoryMerger::emitCategoryBody(const std::string &name, + const Defined *nameSym, + const Symbol *baseClassSym, + const std::string &baseClassName, + ObjFile *objFile) { + llvm::ArrayRef<uint8_t> bodyData = newSectionData(catLayout.totalSize); + + uint32_t *ptrSize = (uint32_t *)(const_cast<uint8_t *>(bodyData.data()) + + catLayout.sizeOffset); + *ptrSize = catLayout.totalSize; + + ConcatInputSection *newBodySec = + make<ConcatInputSection>(*infoCategoryWriter.catBodyInfo.inputSection, + bodyData, infoCategoryWriter.catBodyInfo.align); + newBodySec->parent = infoCategoryWriter.catBodyInfo.outputSection; + newBodySec->live = true; + allInputSections.push_back(newBodySec); + + std::string symName = + objc::symbol_names::category + baseClassName + "_$_(" + name + ")"; + Defined *catBodySym = make<Defined>( + newStringData(symName.c_str()), /*file=*/objFile, newBodySec, + /*value=*/0, bodyData.size(), /*isWeakDef=*/false, /*isExternal=*/false, + /*isPrivateExtern=*/false, /*includeInSymtab=*/true, + /*isReferencedDynamically=*/false, /*noDeadStrip=*/false, + /*isWeakDefCanBeHidden=*/false); + + catBodySym->used = true; + objFile->symbols.push_back(catBodySym); + + createSymbolReference(catBodySym, nameSym, catLayout.nameOffset, + infoCategoryWriter.catBodyInfo.relocTemplate); + + // Create a reloc to the base class (either external or internal) + createSymbolReference(catBodySym, baseClassSym, catLayout.klassOffset, + infoCategoryWriter.catBodyInfo.relocTemplate); + + return catBodySym; +} + +// This writes the new category name (for the merged category) into the binary +// and returns the sybmol for it. +Defined *ObjcCategoryMerger::emitCategoryName(const std::string &name, + ObjFile *objFile) { + StringRef nameStrData = newStringData(name.c_str()); + // We use +1 below to include the null terminator + llvm::ArrayRef<uint8_t> nameData( + reinterpret_cast<const uint8_t *>(nameStrData.data()), + nameStrData.size() + 1); + + auto *parentSection = infoCategoryWriter.catNameInfo.inputSection; + CStringInputSection *newStringSec = make<CStringInputSection>( + *infoCategoryWriter.catNameInfo.inputSection, nameData, + infoCategoryWriter.catNameInfo.align, /*dedupLiterals=*/true); + + parentSection->subsections.push_back({0, newStringSec}); + + newStringSec->splitIntoPieces(); + newStringSec->pieces[0].live = true; + newStringSec->parent = infoCategoryWriter.catNameInfo.outputSection; + in.cStringSection->addInput(newStringSec); + assert(newStringSec->pieces.size() == 1); + + Defined *catNameSym = make<Defined>( + "<merged category name>", /*file=*/objFile, newStringSec, + /*value=*/0, nameData.size(), + /*isWeakDef=*/false, /*isExternal=*/false, /*isPrivateExtern=*/false, + /*includeInSymtab=*/false, /*isReferencedDynamically=*/false, + /*noDeadStrip=*/false, /*isWeakDefCanBeHidden=*/false); + + catNameSym->used = true; + objFile->symbols.push_back(catNameSym); + return catNameSym; +} + +// This method fully creates a new category from the given ClassExtensionInfo. +// It creates the category name, body and method/protocol/prop lists and links +// them all together. Then it creates a new __objc_catlist entry and adds the +// category to it. Calling this method will fully generate a category which will +// be available in the final binary. +Defined *ObjcCategoryMerger::emitCategory(const ClassExtensionInfo &extInfo) { + Defined *catNameSym = emitCategoryName(extInfo.mergedContainerName, + extInfo.objFileForMergeData); + + Defined *catBodySym = emitCategoryBody( + extInfo.mergedContainerName, catNameSym, extInfo.baseClass, + extInfo.baseClassName, extInfo.objFileForMergeData); + + Defined *catListSym = + emitCatListEntrySec(extInfo.mergedContainerName, extInfo.baseClassName, + extInfo.objFileForMergeData); + + // Add the single category body to the category list at the offset 0. + createSymbolReference(catListSym, catBodySym, /*offset=*/0, + infoCategoryWriter.catListInfo.relocTemplate); + + emitAndLinkPointerList(catBodySym, catLayout.instanceMethodsOffset, extInfo, + extInfo.instanceMethods); + + emitAndLinkPointerList(catBodySym, catLayout.classMethodsOffset, extInfo, + extInfo.classMethods); + + emitAndLinkProtocolList(catBodySym, catLayout.protocolsOffset, extInfo, + extInfo.protocols); + + emitAndLinkPointerList(catBodySym, catLayout.instancePropsOffset, extInfo, + extInfo.instanceProps); + + emitAndLinkPointerList(catBodySym, catLayout.classPropsOffset, extInfo, + extInfo.classProps); + + return catBodySym; +} + +// This method merges all the categories (sharing a base class) into a single +// category. +void ObjcCategoryMerger::mergeCategoriesIntoSingleCategory( + std::vector<InfoInputCategory> &categories) { + assert(categories.size() > 1 && "Expected at least 2 categories"); + + ClassExtensionInfo extInfo(catLayout); + + for (auto &catInfo : categories) + parseCatInfoToExtInfo(catInfo, extInfo); + + Defined *newCatDef = emitCategory(extInfo); + assert(newCatDef && "Failed to create a new category"); + + // Suppress unsuded var warning + (void)newCatDef; + + for (auto &catInfo : categories) + catInfo.wasMerged = true; +} + +void ObjcCategoryMerger::createSymbolReference(Defined *refFrom, + const Symbol *refTo, + uint32_t offset, + const Reloc &relocTemplate) { + Reloc r = relocTemplate; + r.offset = offset; + r.addend = 0; + r.referent = const_cast<Symbol *>(refTo); + refFrom->isec->relocs.push_back(r); +} + +void ObjcCategoryMerger::collectAndValidateCategoriesData() { + for (InputSection *sec : allInputSections) { + if (sec->getName() != section_names::objcCatList) + continue; + ConcatInputSection *catListCisec = dyn_cast<ConcatInputSection>(sec); + assert(catListCisec && + "__objc_catList InputSection is not a ConcatInputSection"); + + for (uint32_t off = 0; off < catListCisec->getSize(); + off += target->wordSize) { + Defined *categorySym = tryGetDefinedAtIsecOffset(catListCisec, off); + assert(categorySym && + "Failed to get a valid cateogry at __objc_catlit offset"); + + // We only support ObjC categories (no swift + @objc) + // TODO: Support swift + @objc categories also + if (!categorySym->getName().starts_with(objc::symbol_names::category)) + continue; + + auto *catBodyIsec = dyn_cast<ConcatInputSection>(categorySym->isec); + assert(catBodyIsec && + "Category data section is not an ConcatInputSection"); + + // Check that the category has a reloc at 'klassOffset' (which is + // a pointer to the class symbol) + + Symbol *classSym = + tryGetSymbolAtIsecOffset(catBodyIsec, catLayout.klassOffset); + assert(classSym && "Category does not have a valid base class"); + + InfoInputCategory catInputInfo{catListCisec, catBodyIsec, off}; + categoryMap[classSym].push_back(catInputInfo); + + collectCategoryWriterInfoFromCategory(catInputInfo); + } + } +} + +// In the input we have multiple __objc_catlist InputSection, each of which may +// contain links to multiple categories. Of these categories, we will merge (and +// erase) only some. There will be some categories that will remain untouched +// (not erased). For these not erased categories, we generate new __objc_catlist +// entries since the parent __objc_catlist entry will be erased +void ObjcCategoryMerger::generateCatListForNonErasedCategories( + const std::map<ConcatInputSection *, std::set<uint64_t>> + catListToErasedOffsets) { + + // Go through all offsets of all __objc_catlist's that we process and if there + // are categories that we didn't process - generate a new __objc_catlist for + // each. + for (auto &mapEntry : catListToErasedOffsets) { + ConcatInputSection *catListIsec = mapEntry.first; + for (uint32_t catListIsecOffset = 0; + catListIsecOffset < catListIsec->data.size(); + catListIsecOffset += target->wordSize) { + // This slot was erased, we can just skip it + if (mapEntry.second.count(catListIsecOffset)) + continue; + + Defined *nonErasedCatBody = + tryGetDefinedAtIsecOffset(catListIsec, catListIsecOffset); + assert(nonErasedCatBody && "Failed to relocate non-deleted category"); + + // Allocate data for the new __objc_catlist slot + auto bodyData = newSectionData(target->wordSize); + + // We mark the __objc_catlist slot as belonging to the same file as the + // category + ObjFile *objFile = dyn_cast<ObjFile>(nonErasedCatBody->getFile()); + + ConcatInputSection *listSec = make<ConcatInputSection>( + *infoCategoryWriter.catListInfo.inputSection, bodyData, + infoCategoryWriter.catListInfo.align); + listSec->parent = infoCategoryWriter.catListInfo.outputSection; + listSec->live = true; + allInputSections.push_back(listSec); + + std::string slotSymName = "<__objc_catlist slot for category "; + slotSymName += nonErasedCatBody->getName(); + slotSymName += ">"; + + Defined *catListSlotSym = make<Defined>( + newStringData(slotSymName.c_str()), /*file=*/objFile, listSec, + /*value=*/0, bodyData.size(), + /*isWeakDef=*/false, /*isExternal=*/false, /*isPrivateExtern=*/false, + /*includeInSymtab=*/false, /*isReferencedDynamically=*/false, + /*noDeadStrip=*/false, /*isWeakDefCanBeHidden=*/false); + + catListSlotSym->used = true; + objFile->symbols.push_back(catListSlotSym); + + // Now link the category body into the newly created slot + createSymbolReference(catListSlotSym, nonErasedCatBody, 0, + infoCategoryWriter.catListInfo.relocTemplate); + } + } +} + +void ObjcCategoryMerger::eraseISec(ConcatInputSection *isec) { + isec->live = false; + for (auto &sym : isec->symbols) + sym->used = false; +} + +// This fully erases the merged categories, including their body, their names, +// their method/protocol/prop lists and the __objc_catlist entries that link to +// them. +void ObjcCategoryMerger::eraseMergedCategories() { + // Map of InputSection to a set of offsets of the categories that were merged + std::map<ConcatInputSection *, std::set<uint64_t>> catListToErasedOffsets; + + for (auto &mapEntry : categoryMap) { + for (InfoInputCategory &catInfo : mapEntry.second) { + if (catInfo.wasMerged) { + eraseISec(catInfo.catListIsec); + catListToErasedOffsets[catInfo.catListIsec].insert( + catInfo.offCatListIsec); + } + } + } + + // If there were categories that we did not erase, we need to generate a new + // __objc_catList that contains only the un-merged categories, and get rid of + // the references to the ones we merged. + generateCatListForNonErasedCategories(catListToErasedOffsets); + + // Erase the old method lists & names of the categories that were merged + for (auto &mapEntry : categoryMap) { + for (InfoInputCategory &catInfo : mapEntry.second) { + if (!catInfo.wasMerged) + continue; + + eraseISec(catInfo.catBodyIsec); + tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset); + tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, + catLayout.instanceMethodsOffset); + tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, + catLayout.classMethodsOffset); + tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, + catLayout.protocolsOffset); + tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, + catLayout.classPropsOffset); + tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, + catLayout.instancePropsOffset); + } + } +} + +void ObjcCategoryMerger::doMerge() { + collectAndValidateCategoriesData(); + + for (auto &entry : categoryMap) + if (entry.second.size() > 1) + // Merge all categories into a new, single category + mergeCategoriesIntoSingleCategory(entry.second); + + // Erase all categories that were merged + eraseMergedCategories(); +} + +void ObjcCategoryMerger::doCleanup() { generatedSectionData.clear(); } + +StringRef ObjcCategoryMerger::newStringData(const char *str) { + uint32_t len = strlen(str); + auto &data = newSectionData(len + 1); + char *strData = reinterpret_cast<char *>(data.data()); + strncpy(strData, str, len); + return StringRef(strData, len); +} + +SmallVector<uint8_t> &ObjcCategoryMerger::newSectionData(uint32_t size) { + generatedSectionData.push_back( + std::make_unique<SmallVector<uint8_t>>(size, 0)); + return *generatedSectionData.back(); +} + +} // namespace + +void objc::mergeCategories() { + TimeTraceScope timeScope("ObjcCategoryMerger"); + + ObjcCategoryMerger merger(inputSections); + merger.doMerge(); +} + +void objc::doCleanup() { ObjcCategoryMerger::doCleanup(); } diff --git a/lld/MachO/ObjC.h b/lld/MachO/ObjC.h index 4c65f9a1f788..9fbe984e6223 100644 --- a/lld/MachO/ObjC.h +++ b/lld/MachO/ObjC.h @@ -17,14 +17,26 @@ namespace objc { namespace symbol_names { constexpr const char klass[] = "_OBJC_CLASS_$_"; +constexpr const char klassPropList[] = "__OBJC_$_CLASS_PROP_LIST_"; + constexpr const char metaclass[] = "_OBJC_METACLASS_$_"; constexpr const char ehtype[] = "_OBJC_EHTYPE_$_"; constexpr const char ivar[] = "_OBJC_IVAR_$_"; +constexpr const char listProprieties[] = "__OBJC_$_PROP_LIST_"; + +constexpr const char category[] = "__OBJC_$_CATEGORY_"; +constexpr const char categoryInstanceMethods[] = + "__OBJC_$_CATEGORY_INSTANCE_METHODS_"; +constexpr const char categoryClassMethods[] = + "__OBJC_$_CATEGORY_CLASS_METHODS_"; +constexpr const char categoryProtocols[] = "__OBJC_CATEGORY_PROTOCOLS_$_"; } // namespace symbol_names // Check for duplicate method names within related categories / classes. void checkCategories(); +void mergeCategories(); +void doCleanup(); } // namespace objc bool hasObjCSection(llvm::MemoryBufferRef); diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index a524e4a4c508..0d8ee2a0926b 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -129,6 +129,12 @@ def strict_auto_link : Flag<["--"], "strict-auto-link">, def check_category_conflicts : Flag<["--"], "check-category-conflicts">, HelpText<"Check for conflicts between category & class methods">, Group<grp_lld>; +def objc_category_merging : Flag<["-"], "objc_category_merging">, + HelpText<"Merge Objective-C categories that share the same base class">, + Group<grp_lld>; +def no_objc_category_merging : Flag<["-"], "no_objc_category_merging">, + HelpText<"Do not merge Objective-C categories">, + Group<grp_lld>; def lto_debug_pass_manager: Flag<["--"], "lto-debug-pass-manager">, HelpText<"Debug new pass manager">, Group<grp_lld>; def cs_profile_generate: Flag<["--"], "cs-profile-generate">, @@ -966,10 +972,6 @@ def interposable_list : Separate<["-"], "interposable_list">, def no_function_starts : Flag<["-"], "no_function_starts">, HelpText<"Do not create table of function start addresses">, Group<grp_rare>; -def no_objc_category_merging : Flag<["-"], "no_objc_category_merging">, - HelpText<"Do not merge Objective-C categories into their classes">, - Flags<[HelpHidden]>, - Group<grp_rare>; def object_path_lto : Separate<["-"], "object_path_lto">, MetaVarName<"<path>">, HelpText<"Retain any temporary mach-o file in <path> that would otherwise be deleted during LTO">, diff --git a/lld/test/MachO/objc-category-merging-complete-test.s b/lld/test/MachO/objc-category-merging-complete-test.s new file mode 100644 index 000000000000..3bc3ca26b6ae --- /dev/null +++ b/lld/test/MachO/objc-category-merging-complete-test.s @@ -0,0 +1,762 @@ +# REQUIRES: aarch64 +# RUN: rm -rf %t; split-file %s %t && cd %t + +## Create a dylib to link against(a64_file1.dylib) and merge categories in the main binary (file2_merge_a64.exe) +# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_file1.o a64_file1.s +# RUN: %lld -arch arm64 a64_file1.o -o a64_file1.dylib -dylib + +# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_file2.o a64_file2.s +# RUN: %lld -arch arm64 -o a64_file2_no_merge.exe a64_file1.dylib a64_file2.o +# RUN: %lld -arch arm64 -o a64_file2_merge.exe -objc_category_merging a64_file1.dylib a64_file2.o + +# RUN: llvm-objdump --objc-meta-data --macho a64_file2_no_merge.exe | FileCheck %s --check-prefixes=NO_MERGE_CATS +# RUN: llvm-objdump --objc-meta-data --macho a64_file2_merge.exe | FileCheck %s --check-prefixes=MERGE_CATS + + +MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_(Category02|Category03) +MERGE_CATS-NEXT: name {{.*}} Category02|Category03 +MERGE_CATS: instanceMethods +MERGE_CATS-NEXT: entsize 24 +MERGE_CATS-NEXT: count 4 +MERGE_CATS-NEXT: name {{.*}} class02InstanceMethod +MERGE_CATS-NEXT: types {{.*}} v16@0:8 +MERGE_CATS-NEXT: imp -[MyBaseClass(Category02) class02InstanceMethod] +MERGE_CATS-NEXT: name {{.*}} myProtocol02Method +MERGE_CATS-NEXT: types {{.*}} v16@0:8 +MERGE_CATS-NEXT: imp -[MyBaseClass(Category02) myProtocol02Method] +MERGE_CATS-NEXT: name {{.*}} class03InstanceMethod +MERGE_CATS-NEXT: types {{.*}} v16@0:8 +MERGE_CATS-NEXT: imp -[MyBaseClass(Category03) class03InstanceMethod] +MERGE_CATS-NEXT: name {{.*}} myProtocol03Method +MERGE_CATS-NEXT: types {{.*}} v16@0:8 +MERGE_CATS-NEXT: imp -[MyBaseClass(Category03) myProtocol03Method] +MERGE_CATS-NEXT: classMethods {{.*}} +MERGE_CATS-NEXT: entsize 24 +MERGE_CATS-NEXT: count 4 +MERGE_CATS-NEXT: name {{.*}} class02ClassMethod +MERGE_CATS-NEXT: types {{.*}} v16@0:8 +MERGE_CATS-NEXT: imp +[MyBaseClass(Category02) class02ClassMethod] +MERGE_CATS-NEXT: name {{.*}} MyProtocol02Prop +MERGE_CATS-NEXT: types {{.*}} i16@0:8 +MERGE_CATS-NEXT: imp +[MyBaseClass(Category02) MyProtocol02Prop] +MERGE_CATS-NEXT: name {{.*}} class03ClassMethod +MERGE_CATS-NEXT: types {{.*}} v16@0:8 +MERGE_CATS-NEXT: imp +[MyBaseClass(Category03) class03ClassMethod] +MERGE_CATS-NEXT: name {{.*}} MyProtocol03Prop +MERGE_CATS-NEXT: types {{.*}} i16@0:8 +MERGE_CATS-NEXT: imp +[MyBaseClass(Category03) MyProtocol03Prop] +MERGE_CATS-NEXT: protocols +MERGE_CATS-NEXT: count 2 +MERGE_CATS-NEXT: list[0] {{.*}} (struct protocol_t *) +MERGE_CATS-NEXT: isa 0x0 +MERGE_CATS-NEXT: name {{.*}} MyProtocol02 +MERGE_CATS-NEXT: protocols 0x0 +MERGE_CATS-NEXT: instanceMethods +MERGE_CATS-NEXT: entsize 24 +MERGE_CATS-NEXT: count 2 +MERGE_CATS-NEXT: name {{.*}} myProtocol02Method +MERGE_CATS-NEXT: types {{.*}} v16@0:8 +MERGE_CATS-NEXT: imp 0x0 +MERGE_CATS-NEXT: name {{.*}} MyProtocol02Prop +MERGE_CATS-NEXT: types {{.*}} i16@0:8 +MERGE_CATS-NEXT: imp 0x0 +MERGE_CATS-NEXT: classMethods +MERGE_CATS-NEXT: optionalInstanceMethods 0x0 +MERGE_CATS-NEXT: optionalClassMethods 0x0 +MERGE_CATS-NEXT: instanceProperties {{.*}} +MERGE_CATS-NEXT: list[1] {{.*}} +MERGE_CATS-NEXT: isa 0x0 +MERGE_CATS-NEXT: name {{.*}} MyProtocol03 +MERGE_CATS-NEXT: protocols 0x0 +MERGE_CATS-NEXT: instanceMethods +MERGE_CATS-NEXT: entsize 24 +MERGE_CATS-NEXT: count 2 +MERGE_CATS-NEXT: name {{.*}} myProtocol03Method +MERGE_CATS-NEXT: types {{.*}} v16@0:8 +MERGE_CATS-NEXT: imp 0x0 +MERGE_CATS-NEXT: name {{.*}} MyProtocol03Prop +MERGE_CATS-NEXT: types {{.*}} i16@0:8 +MERGE_CATS-NEXT: imp 0x0 +MERGE_CATS-NEXT: classMethods 0x0 +MERGE_CATS-NEXT: optionalInstanceMethods 0x0 +MERGE_CATS-NEXT: optionalClassMethods 0x0 +MERGE_CATS-NEXT: instanceProperties {{.*}} +MERGE_CATS-NEXT: instanceProperties +MERGE_CATS-NEXT: entsize 16 +MERGE_CATS-NEXT: count 2 +MERGE_CATS-NEXT: name {{.*}} MyProtocol02Prop +MERGE_CATS-NEXT: attributes {{.*}} Ti,R,D +MERGE_CATS-NEXT: name {{.*}} MyProtocol03Prop +MERGE_CATS-NEXT: attributes {{.*}} Ti,R,D + + +NO_MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_(Category02|Category03) +NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category02 +NO_MERGE_CATS: instanceMethods +NO_MERGE_CATS-NEXT: 24 +NO_MERGE_CATS-NEXT: 2 +NO_MERGE_CATS: classMethods +NO_MERGE_CATS-NEXT: 24 +NO_MERGE_CATS-NEXT: 2 + + +#--- a64_file1.s + +## @protocol MyProtocol01 +## - (void)myProtocol01Method; +## @property (nonatomic) int MyProtocol01Prop; +## @end +## +## __attribute__((objc_root_class)) +## @interface MyBaseClass<MyProtocol01> +## - (void)baseInstanceMethod; +## - (void)myProtocol01Method; +## + (void)baseClassMethod; +## @end +## +## @implementation MyBaseClass +## @synthesize MyProtocol01Prop; +## - (void)baseInstanceMethod {} +## - (void)myProtocol01Method {} +## + (void)baseClassMethod {} +## @end +## +## void *_objc_empty_cache; + + .section __TEXT,__text,regular,pure_instructions + .p2align 2 ; -- Begin function -[MyBaseClass baseInstanceMethod] +"-[MyBaseClass baseInstanceMethod]": ; @"\01-[MyBaseClass baseInstanceMethod]" + .cfi_startproc +; %bb.0: ; %entry + ret + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function -[MyBaseClass myProtocol01Method] +"-[MyBaseClass myProtocol01Method]": ; @"\01-[MyBaseClass myProtocol01Method]" + .cfi_startproc +; %bb.0: ; %entry + ret + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function +[MyBaseClass baseClassMethod] +"+[MyBaseClass baseClassMethod]": ; @"\01+[MyBaseClass baseClassMethod]" + .cfi_startproc +; %bb.0: ; %entry + ret + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function -[MyBaseClass MyProtocol01Prop] +"-[MyBaseClass MyProtocol01Prop]": ; @"\01-[MyBaseClass MyProtocol01Prop]" + .cfi_startproc +; %bb.0: ; %entry +Lloh0: + adrp x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGE +Lloh1: + ldrsw x8, [x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGEOFF] + ldr w0, [x0, x8] + ret + .loh AdrpLdr Lloh0, Lloh1 + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function -[MyBaseClass setMyProtocol01Prop:] +"-[MyBaseClass setMyProtocol01Prop:]": ; @"\01-[MyBaseClass setMyProtocol01Prop:]" + .cfi_startproc +; %bb.0: ; %entry +Lloh2: + adrp x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGE +Lloh3: + ldrsw x8, [x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGEOFF] + str w2, [x0, x8] + ret + .loh AdrpLdr Lloh2, Lloh3 + .cfi_endproc + ; -- End function + .private_extern _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop ; @"OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop" + .section __DATA,__objc_ivar + .globl _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop + .p2align 2, 0x0 +_OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop: + .long 0 ; 0x0 + .section __DATA,__objc_data + .globl _OBJC_CLASS_$_MyBaseClass ; @"OBJC_CLASS_$_MyBaseClass" + .p2align 3, 0x0 +_OBJC_CLASS_$_MyBaseClass: + .quad _OBJC_METACLASS_$_MyBaseClass + .quad 0 + .quad __objc_empty_cache + .quad 0 + .quad __OBJC_CLASS_RO_$_MyBaseClass + .globl _OBJC_METACLASS_$_MyBaseClass ; @"OBJC_METACLASS_$_MyBaseClass" + .p2align 3, 0x0 +_OBJC_METACLASS_$_MyBaseClass: + .quad _OBJC_METACLASS_$_MyBaseClass + .quad _OBJC_CLASS_$_MyBaseClass + .quad __objc_empty_cache + .quad 0 + .quad __OBJC_METACLASS_RO_$_MyBaseClass + .section __TEXT,__objc_classname,cstring_literals +l_OBJC_CLASS_NAME_: ; @OBJC_CLASS_NAME_ + .asciz "MyBaseClass" + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_METH_VAR_NAME_: ; @OBJC_METH_VAR_NAME_ + .asciz "baseClassMethod" + .section __TEXT,__objc_methtype,cstring_literals +l_OBJC_METH_VAR_TYPE_: ; @OBJC_METH_VAR_TYPE_ + .asciz "v16@0:8" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_CLASS_METHODS_MyBaseClass" +__OBJC_$_CLASS_METHODS_MyBaseClass: + .long 24 ; 0x18 + .long 1 ; 0x1 + .quad l_OBJC_METH_VAR_NAME_ + .quad l_OBJC_METH_VAR_TYPE_ + .quad "+[MyBaseClass baseClassMethod]" + .section __TEXT,__objc_classname,cstring_literals +l_OBJC_CLASS_NAME_.1: ; @OBJC_CLASS_NAME_.1 + .asciz "MyProtocol01" + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_METH_VAR_NAME_.2: ; @OBJC_METH_VAR_NAME_.2 + .asciz "myProtocol01Method" +l_OBJC_METH_VAR_NAME_.3: ; @OBJC_METH_VAR_NAME_.3 + .asciz "MyProtocol01Prop" + .section __TEXT,__objc_methtype,cstring_literals +l_OBJC_METH_VAR_TYPE_.4: ; @OBJC_METH_VAR_TYPE_.4 + .asciz "i16@0:8" + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_METH_VAR_NAME_.5: ; @OBJC_METH_VAR_NAME_.5 + .asciz "setMyProtocol01Prop:" + .section __TEXT,__objc_methtype,cstring_literals +l_OBJC_METH_VAR_TYPE_.6: ; @OBJC_METH_VAR_TYPE_.6 + .asciz "v20@0:8i16" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol01" +__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol01: + .long 24 ; 0x18 + .long 3 ; 0x3 + .quad l_OBJC_METH_VAR_NAME_.2 + .quad l_OBJC_METH_VAR_TYPE_ + .quad 0 + .quad l_OBJC_METH_VAR_NAME_.3 + .quad l_OBJC_METH_VAR_TYPE_.4 + .quad 0 + .quad l_OBJC_METH_VAR_NAME_.5 + .quad l_OBJC_METH_VAR_TYPE_.6 + .quad 0 + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_PROP_NAME_ATTR_: ; @OBJC_PROP_NAME_ATTR_ + .asciz "MyProtocol01Prop" +l_OBJC_PROP_NAME_ATTR_.7: ; @OBJC_PROP_NAME_ATTR_.7 + .asciz "Ti,N" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyProtocol01" +__OBJC_$_PROP_LIST_MyProtocol01: + .long 16 ; 0x10 + .long 1 ; 0x1 + .quad l_OBJC_PROP_NAME_ATTR_ + .quad l_OBJC_PROP_NAME_ATTR_.7 + .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol01" +__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol01: + .quad l_OBJC_METH_VAR_TYPE_ + .quad l_OBJC_METH_VAR_TYPE_.4 + .quad l_OBJC_METH_VAR_TYPE_.6 + .private_extern __OBJC_PROTOCOL_$_MyProtocol01 ; @"_OBJC_PROTOCOL_$_MyProtocol01" + .section __DATA,__data + .globl __OBJC_PROTOCOL_$_MyProtocol01 + .weak_definition __OBJC_PROTOCOL_$_MyProtocol01 + .p2align 3, 0x0 +__OBJC_PROTOCOL_$_MyProtocol01: + .quad 0 + .quad l_OBJC_CLASS_NAME_.1 + .quad 0 + .quad __OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol01 + .quad 0 + .quad 0 + .quad 0 + .quad __OBJC_$_PROP_LIST_MyProtocol01 + .long 96 ; 0x60 + .long 0 ; 0x0 + .quad __OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol01 + .quad 0 + .quad 0 + .private_extern __OBJC_LABEL_PROTOCOL_$_MyProtocol01 ; @"_OBJC_LABEL_PROTOCOL_$_MyProtocol01" + .section __DATA,__objc_protolist,coalesced,no_dead_strip + .globl __OBJC_LABEL_PROTOCOL_$_MyProtocol01 + .weak_definition __OBJC_LABEL_PROTOCOL_$_MyProtocol01 + .p2align 3, 0x0 +__OBJC_LABEL_PROTOCOL_$_MyProtocol01: + .quad __OBJC_PROTOCOL_$_MyProtocol01 + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_CLASS_PROTOCOLS_$_MyBaseClass" +__OBJC_CLASS_PROTOCOLS_$_MyBaseClass: + .quad 1 ; 0x1 + .quad __OBJC_PROTOCOL_$_MyProtocol01 + .quad 0 + .p2align 3, 0x0 ; @"_OBJC_METACLASS_RO_$_MyBaseClass" +__OBJC_METACLASS_RO_$_MyBaseClass: + .long 3 ; 0x3 + .long 40 ; 0x28 + .long 40 ; 0x28 + .space 4 + .quad 0 + .quad l_OBJC_CLASS_NAME_ + .quad __OBJC_$_CLASS_METHODS_MyBaseClass + .quad __OBJC_CLASS_PROTOCOLS_$_MyBaseClass + .quad 0 + .quad 0 + .quad 0 + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_METH_VAR_NAME_.8: ; @OBJC_METH_VAR_NAME_.8 + .asciz "baseInstanceMethod" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_INSTANCE_METHODS_MyBaseClass" +__OBJC_$_INSTANCE_METHODS_MyBaseClass: + .long 24 ; 0x18 + .long 4 ; 0x4 + .quad l_OBJC_METH_VAR_NAME_.8 + .quad l_OBJC_METH_VAR_TYPE_ + .quad "-[MyBaseClass baseInstanceMethod]" + .quad l_OBJC_METH_VAR_NAME_.2 + .quad l_OBJC_METH_VAR_TYPE_ + .quad "-[MyBaseClass myProtocol01Method]" + .quad l_OBJC_METH_VAR_NAME_.3 + .quad l_OBJC_METH_VAR_TYPE_.4 + .quad "-[MyBaseClass MyProtocol01Prop]" + .quad l_OBJC_METH_VAR_NAME_.5 + .quad l_OBJC_METH_VAR_TYPE_.6 + .quad "-[MyBaseClass setMyProtocol01Prop:]" + .section __TEXT,__objc_methtype,cstring_literals +l_OBJC_METH_VAR_TYPE_.9: ; @OBJC_METH_VAR_TYPE_.9 + .asciz "i" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_INSTANCE_VARIABLES_MyBaseClass" +__OBJC_$_INSTANCE_VARIABLES_MyBaseClass: + .long 32 ; 0x20 + .long 1 ; 0x1 + .quad _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop + .quad l_OBJC_METH_VAR_NAME_.3 + .quad l_OBJC_METH_VAR_TYPE_.9 + .long 2 ; 0x2 + .long 4 ; 0x4 + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_PROP_NAME_ATTR_.10: ; @OBJC_PROP_NAME_ATTR_.10 + .asciz "Ti,N,VMyProtocol01Prop" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyBaseClass" +__OBJC_$_PROP_LIST_MyBaseClass: + .long 16 ; 0x10 + .long 1 ; 0x1 + .quad l_OBJC_PROP_NAME_ATTR_ + .quad l_OBJC_PROP_NAME_ATTR_.10 + .p2align 3, 0x0 ; @"_OBJC_CLASS_RO_$_MyBaseClass" +__OBJC_CLASS_RO_$_MyBaseClass: + .long 2 ; 0x2 + .long 0 ; 0x0 + .long 4 ; 0x4 + .space 4 + .quad 0 + .quad l_OBJC_CLASS_NAME_ + .quad __OBJC_$_INSTANCE_METHODS_MyBaseClass + .quad __OBJC_CLASS_PROTOCOLS_$_MyBaseClass + .quad __OBJC_$_INSTANCE_VARIABLES_MyBaseClass + .quad 0 + .quad __OBJC_$_PROP_LIST_MyBaseClass + .globl __objc_empty_cache ; @_objc_empty_cache +.zerofill __DATA,__common,__objc_empty_cache,8,3 + .section __DATA,__objc_classlist,regular,no_dead_strip + .p2align 3, 0x0 ; @"OBJC_LABEL_CLASS_$" +l_OBJC_LABEL_CLASS_$: + .quad _OBJC_CLASS_$_MyBaseClass + .no_dead_strip __OBJC_LABEL_PROTOCOL_$_MyProtocol01 + .no_dead_strip __OBJC_PROTOCOL_$_MyProtocol01 + .section __DATA,__objc_imageinfo,regular,no_dead_strip +L_OBJC_IMAGE_INFO: + .long 0 + .long 96 +.subsections_via_symbols + + +#--- a64_file2.s + +## @protocol MyProtocol01 +## - (void)myProtocol01Method; +## @end +## +## @protocol MyProtocol02 +## - (void)myProtocol02Method; +## @property(readonly) int MyProtocol02Prop; +## @end +## +## @protocol MyProtocol03 +## - (void)myProtocol03Method; +## @property(readonly) int MyProtocol03Prop; +## @end +## +## +## __attribute__((objc_root_class)) +## @interface MyBaseClass<MyProtocol01> +## - (void)baseInstanceMethod; +## - (void)myProtocol01Method; +## + (void)baseClassMethod; +## @end +## +## +## +## @interface MyBaseClass(Category02)<MyProtocol02> +## - (void)class02InstanceMethod; +## - (void)myProtocol02Method; +## + (void)class02ClassMethod; +## + (int)MyProtocol02Prop; +## @end +## +## @implementation MyBaseClass(Category02) +## - (void)class02InstanceMethod {} +## - (void)myProtocol02Method {} +## + (void)class02ClassMethod {} +## + (int)MyProtocol02Prop { return 0;} +## @dynamic MyProtocol02Prop; +## @end +## +## @interface MyBaseClass(Category03)<MyProtocol03> +## - (void)class03InstanceMethod; +## - (void)myProtocol03Method; +## + (void)class03ClassMethod; +## + (int)MyProtocol03Prop; +## @end +## +## @implementation MyBaseClass(Category03) +## - (void)class03InstanceMethod {} +## - (void)myProtocol03Method {} +## + (void)class03ClassMethod {} +## + (int)MyProtocol03Prop { return 0;} +## @dynamic MyProtocol03Prop; +## @end +## +## int main() { +## return 0; +## } + + + .section __TEXT,__text,regular,pure_instructions + .p2align 2 ; -- Begin function -[MyBaseClass(Category02) class02InstanceMethod] +"-[MyBaseClass(Category02) class02InstanceMethod]": ; @"\01-[MyBaseClass(Category02) class02InstanceMethod]" + .cfi_startproc +; %bb.0: ; %entry + ret + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function -[MyBaseClass(Category02) myProtocol02Method] +"-[MyBaseClass(Category02) myProtocol02Method]": ; @"\01-[MyBaseClass(Category02) myProtocol02Method]" + .cfi_startproc +; %bb.0: ; %entry + ret + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function +[MyBaseClass(Category02) class02ClassMethod] +"+[MyBaseClass(Category02) class02ClassMethod]": ; @"\01+[MyBaseClass(Category02) class02ClassMethod]" + .cfi_startproc +; %bb.0: ; %entry + ret + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function +[MyBaseClass(Category02) MyProtocol02Prop] +"+[MyBaseClass(Category02) MyProtocol02Prop]": ; @"\01+[MyBaseClass(Category02) MyProtocol02Prop]" + .cfi_startproc +; %bb.0: ; %entry + b _OUTLINED_FUNCTION_0 + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function -[MyBaseClass(Category03) class03InstanceMethod] +"-[MyBaseClass(Category03) class03InstanceMethod]": ; @"\01-[MyBaseClass(Category03) class03InstanceMethod]" + .cfi_startproc +; %bb.0: ; %entry + ret + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function -[MyBaseClass(Category03) myProtocol03Method] +"-[MyBaseClass(Category03) myProtocol03Method]": ; @"\01-[MyBaseClass(Category03) myProtocol03Method]" + .cfi_startproc +; %bb.0: ; %entry + ret + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function +[MyBaseClass(Category03) class03ClassMethod] +"+[MyBaseClass(Category03) class03ClassMethod]": ; @"\01+[MyBaseClass(Category03) class03ClassMethod]" + .cfi_startproc +; %bb.0: ; %entry + ret + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function +[MyBaseClass(Category03) MyProtocol03Prop] +"+[MyBaseClass(Category03) MyProtocol03Prop]": ; @"\01+[MyBaseClass(Category03) MyProtocol03Prop]" + .cfi_startproc +; %bb.0: ; %entry + b _OUTLINED_FUNCTION_0 + .cfi_endproc + ; -- End function + .globl _main ; -- Begin function main + .p2align 2 +_main: ; @main + .cfi_startproc +; %bb.0: ; %entry + b _OUTLINED_FUNCTION_0 + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function OUTLINED_FUNCTION_0 +_OUTLINED_FUNCTION_0: ; @OUTLINED_FUNCTION_0 Tail Call + .cfi_startproc +; %bb.0: + mov w0, #0 + ret + .cfi_endproc + ; -- End function + .section __TEXT,__objc_classname,cstring_literals +l_OBJC_CLASS_NAME_: ; @OBJC_CLASS_NAME_ + .asciz "Category02" + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_METH_VAR_NAME_: ; @OBJC_METH_VAR_NAME_ + .asciz "class02InstanceMethod" + .section __TEXT,__objc_methtype,cstring_literals +l_OBJC_METH_VAR_TYPE_: ; @OBJC_METH_VAR_TYPE_ + .asciz "v16@0:8" + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_METH_VAR_NAME_.1: ; @OBJC_METH_VAR_NAME_.1 + .asciz "myProtocol02Method" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02" +__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02: + .long 24 ; 0x18 + .long 2 ; 0x2 + .quad l_OBJC_METH_VAR_NAME_ + .quad l_OBJC_METH_VAR_TYPE_ + .quad "-[MyBaseClass(Category02) class02InstanceMethod]" + .quad l_OBJC_METH_VAR_NAME_.1 + .quad l_OBJC_METH_VAR_TYPE_ + .quad "-[MyBaseClass(Category02) myProtocol02Method]" + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_METH_VAR_NAME_.2: ; @OBJC_METH_VAR_NAME_.2 + .asciz "class02ClassMethod" +l_OBJC_METH_VAR_NAME_.3: ; @OBJC_METH_VAR_NAME_.3 + .asciz "MyProtocol02Prop" + .section __TEXT,__objc_methtype,cstring_literals +l_OBJC_METH_VAR_TYPE_.4: ; @OBJC_METH_VAR_TYPE_.4 + .asciz "i16@0:8" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category02" +__OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category02: + .long 24 ; 0x18 + .long 2 ; 0x2 + .quad l_OBJC_METH_VAR_NAME_.2 + .quad l_OBJC_METH_VAR_TYPE_ + .quad "+[MyBaseClass(Category02) class02ClassMethod]" + .quad l_OBJC_METH_VAR_NAME_.3 + .quad l_OBJC_METH_VAR_TYPE_.4 + .quad "+[MyBaseClass(Category02) MyProtocol02Prop]" + .section __TEXT,__objc_classname,cstring_literals +l_OBJC_CLASS_NAME_.5: ; @OBJC_CLASS_NAME_.5 + .asciz "MyProtocol02" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol02" +__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol02: + .long 24 ; 0x18 + .long 2 ; 0x2 + .quad l_OBJC_METH_VAR_NAME_.1 + .quad l_OBJC_METH_VAR_TYPE_ + .quad 0 + .quad l_OBJC_METH_VAR_NAME_.3 + .quad l_OBJC_METH_VAR_TYPE_.4 + .quad 0 + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_PROP_NAME_ATTR_: ; @OBJC_PROP_NAME_ATTR_ + .asciz "MyProtocol02Prop" +l_OBJC_PROP_NAME_ATTR_.6: ; @OBJC_PROP_NAME_ATTR_.6 + .asciz "Ti,R" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyProtocol02" +__OBJC_$_PROP_LIST_MyProtocol02: + .long 16 ; 0x10 + .long 1 ; 0x1 + .quad l_OBJC_PROP_NAME_ATTR_ + .quad l_OBJC_PROP_NAME_ATTR_.6 + .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol02" +__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol02: + .quad l_OBJC_METH_VAR_TYPE_ + .quad l_OBJC_METH_VAR_TYPE_.4 + .private_extern __OBJC_PROTOCOL_$_MyProtocol02 ; @"_OBJC_PROTOCOL_$_MyProtocol02" + .section __DATA,__data + .globl __OBJC_PROTOCOL_$_MyProtocol02 + .weak_definition __OBJC_PROTOCOL_$_MyProtocol02 + .p2align 3, 0x0 +__OBJC_PROTOCOL_$_MyProtocol02: + .quad 0 + .quad l_OBJC_CLASS_NAME_.5 + .quad 0 + .quad __OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol02 + .quad 0 + .quad 0 + .quad 0 + .quad __OBJC_$_PROP_LIST_MyProtocol02 + .long 96 ; 0x60 + .long 0 ; 0x0 + .quad __OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol02 + .quad 0 + .quad 0 + .private_extern __OBJC_LABEL_PROTOCOL_$_MyProtocol02 ; @"_OBJC_LABEL_PROTOCOL_$_MyProtocol02" + .section __DATA,__objc_protolist,coalesced,no_dead_strip + .globl __OBJC_LABEL_PROTOCOL_$_MyProtocol02 + .weak_definition __OBJC_LABEL_PROTOCOL_$_MyProtocol02 + .p2align 3, 0x0 +__OBJC_LABEL_PROTOCOL_$_MyProtocol02: + .quad __OBJC_PROTOCOL_$_MyProtocol02 + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category02" +__OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category02: + .quad 1 ; 0x1 + .quad __OBJC_PROTOCOL_$_MyProtocol02 + .quad 0 + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_PROP_NAME_ATTR_.7: ; @OBJC_PROP_NAME_ATTR_.7 + .asciz "Ti,R,D" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyBaseClass_$_Category02" +__OBJC_$_PROP_LIST_MyBaseClass_$_Category02: + .long 16 ; 0x10 + .long 1 ; 0x1 + .quad l_OBJC_PROP_NAME_ATTR_ + .quad l_OBJC_PROP_NAME_ATTR_.7 + .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category02" +__OBJC_$_CATEGORY_MyBaseClass_$_Category02: + .quad l_OBJC_CLASS_NAME_ + .quad _OBJC_CLASS_$_MyBaseClass + .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02 + .quad __OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category02 + .quad __OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category02 + .quad __OBJC_$_PROP_LIST_MyBaseClass_$_Category02 + .quad 0 + .long 64 ; 0x40 + .space 4 + .section __TEXT,__objc_classname,cstring_literals +l_OBJC_CLASS_NAME_.8: ; @OBJC_CLASS_NAME_.8 + .asciz "Category03" + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_METH_VAR_NAME_.9: ; @OBJC_METH_VAR_NAME_.9 + .asciz "class03InstanceMethod" +l_OBJC_METH_VAR_NAME_.10: ; @OBJC_METH_VAR_NAME_.10 + .asciz "myProtocol03Method" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category03" +__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category03: + .long 24 ; 0x18 + .long 2 ; 0x2 + .quad l_OBJC_METH_VAR_NAME_.9 + .quad l_OBJC_METH_VAR_TYPE_ + .quad "-[MyBaseClass(Category03) class03InstanceMethod]" + .quad l_OBJC_METH_VAR_NAME_.10 + .quad l_OBJC_METH_VAR_TYPE_ + .quad "-[MyBaseClass(Category03) myProtocol03Method]" + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_METH_VAR_NAME_.11: ; @OBJC_METH_VAR_NAME_.11 + .asciz "class03ClassMethod" +l_OBJC_METH_VAR_NAME_.12: ; @OBJC_METH_VAR_NAME_.12 + .asciz "MyProtocol03Prop" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category03" +__OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category03: + .long 24 ; 0x18 + .long 2 ; 0x2 + .quad l_OBJC_METH_VAR_NAME_.11 + .quad l_OBJC_METH_VAR_TYPE_ + .quad "+[MyBaseClass(Category03) class03ClassMethod]" + .quad l_OBJC_METH_VAR_NAME_.12 + .quad l_OBJC_METH_VAR_TYPE_.4 + .quad "+[MyBaseClass(Category03) MyProtocol03Prop]" + .section __TEXT,__objc_classname,cstring_literals +l_OBJC_CLASS_NAME_.13: ; @OBJC_CLASS_NAME_.13 + .asciz "MyProtocol03" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol03" +__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol03: + .long 24 ; 0x18 + .long 2 ; 0x2 + .quad l_OBJC_METH_VAR_NAME_.10 + .quad l_OBJC_METH_VAR_TYPE_ + .quad 0 + .quad l_OBJC_METH_VAR_NAME_.12 + .quad l_OBJC_METH_VAR_TYPE_.4 + .quad 0 + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_PROP_NAME_ATTR_.14: ; @OBJC_PROP_NAME_ATTR_.14 + .asciz "MyProtocol03Prop" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyProtocol03" +__OBJC_$_PROP_LIST_MyProtocol03: + .long 16 ; 0x10 + .long 1 ; 0x1 + .quad l_OBJC_PROP_NAME_ATTR_.14 + .quad l_OBJC_PROP_NAME_ATTR_.6 + .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol03" +__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol03: + .quad l_OBJC_METH_VAR_TYPE_ + .quad l_OBJC_METH_VAR_TYPE_.4 + .private_extern __OBJC_PROTOCOL_$_MyProtocol03 ; @"_OBJC_PROTOCOL_$_MyProtocol03" + .section __DATA,__data + .globl __OBJC_PROTOCOL_$_MyProtocol03 + .weak_definition __OBJC_PROTOCOL_$_MyProtocol03 + .p2align 3, 0x0 +__OBJC_PROTOCOL_$_MyProtocol03: + .quad 0 + .quad l_OBJC_CLASS_NAME_.13 + .quad 0 + .quad __OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol03 + .quad 0 + .quad 0 + .quad 0 + .quad __OBJC_$_PROP_LIST_MyProtocol03 + .long 96 ; 0x60 + .long 0 ; 0x0 + .quad __OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol03 + .quad 0 + .quad 0 + .private_extern __OBJC_LABEL_PROTOCOL_$_MyProtocol03 ; @"_OBJC_LABEL_PROTOCOL_$_MyProtocol03" + .section __DATA,__objc_protolist,coalesced,no_dead_strip + .globl __OBJC_LABEL_PROTOCOL_$_MyProtocol03 + .weak_definition __OBJC_LABEL_PROTOCOL_$_MyProtocol03 + .p2align 3, 0x0 +__OBJC_LABEL_PROTOCOL_$_MyProtocol03: + .quad __OBJC_PROTOCOL_$_MyProtocol03 + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category03" +__OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category03: + .quad 1 ; 0x1 + .quad __OBJC_PROTOCOL_$_MyProtocol03 + .quad 0 + .p2align 3, 0x0 ; @"_OBJC_$_PROP_LIST_MyBaseClass_$_Category03" +__OBJC_$_PROP_LIST_MyBaseClass_$_Category03: + .long 16 ; 0x10 + .long 1 ; 0x1 + .quad l_OBJC_PROP_NAME_ATTR_.14 + .quad l_OBJC_PROP_NAME_ATTR_.7 + .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category03" +__OBJC_$_CATEGORY_MyBaseClass_$_Category03: + .quad l_OBJC_CLASS_NAME_.8 + .quad _OBJC_CLASS_$_MyBaseClass + .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category03 + .quad __OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category03 + .quad __OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category03 + .quad __OBJC_$_PROP_LIST_MyBaseClass_$_Category03 + .quad 0 + .long 64 ; 0x40 + .space 4 + .section __DATA,__objc_catlist,regular,no_dead_strip + .p2align 3, 0x0 ; @"OBJC_LABEL_CATEGORY_$" +l_OBJC_LABEL_CATEGORY_$: + .quad __OBJC_$_CATEGORY_MyBaseClass_$_Category02 + .quad __OBJC_$_CATEGORY_MyBaseClass_$_Category03 + .no_dead_strip __OBJC_LABEL_PROTOCOL_$_MyProtocol02 + .no_dead_strip __OBJC_LABEL_PROTOCOL_$_MyProtocol03 + .no_dead_strip __OBJC_PROTOCOL_$_MyProtocol02 + .no_dead_strip __OBJC_PROTOCOL_$_MyProtocol03 + .section __DATA,__objc_imageinfo,regular,no_dead_strip +L_OBJC_IMAGE_INFO: + .long 0 + .long 96 +.subsections_via_symbols diff --git a/lld/test/MachO/objc-category-merging-extern-class-minimal.s b/lld/test/MachO/objc-category-merging-extern-class-minimal.s new file mode 100644 index 000000000000..ede7ef5d9c32 --- /dev/null +++ b/lld/test/MachO/objc-category-merging-extern-class-minimal.s @@ -0,0 +1,155 @@ +# REQUIRES: aarch64 +# RUN: rm -rf %t; split-file %s %t && cd %t + +## Create a dylib with a fake base class to link against +# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_fakedylib.o a64_fakedylib.s +# RUN: %lld -arch arm64 a64_fakedylib.o -o a64_fakedylib.dylib -dylib + +## Create our main testing dylib - linking against the fake dylib above +# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_cat_minimal.o merge_cat_minimal.s +# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_no_merge.dylib a64_fakedylib.dylib merge_cat_minimal.o +# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_merge.dylib -objc_category_merging a64_fakedylib.dylib merge_cat_minimal.o + +## Now verify that the flag caused category merging to happen appropriatelly +# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_no_merge.dylib | FileCheck %s --check-prefixes=NO_MERGE_CATS +# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_merge.dylib | FileCheck %s --check-prefixes=MERGE_CATS + +#### Check merge categories enabled ### +# Check that the original categories are not there +MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category01 +MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02 + +# Check that the merged cateogry is there, in the correct format +MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_(Category01|Category02) +MERGE_CATS-NEXT: name {{.*}} Category01|Category02 +MERGE_CATS: instanceMethods +MERGE_CATS-NEXT: 24 +MERGE_CATS-NEXT: 2 +MERGE_CATS-NEXT: name {{.*}} cat01_InstanceMethod +MERGE_CATS-NEXT: types {{.*}} v16@0:8 +MERGE_CATS-NEXT: imp -[MyBaseClass(Category01) cat01_InstanceMethod] +MERGE_CATS-NEXT: name {{.*}} cat02_InstanceMethod +MERGE_CATS-NEXT: types {{.*}} v16@0:8 +MERGE_CATS-NEXT: imp -[MyBaseClass(Category02) cat02_InstanceMethod] +MERGE_CATS-NEXT: classMethods 0x0 +MERGE_CATS-NEXT: protocols 0x0 +MERGE_CATS-NEXT: instanceProperties 0x0 + +#### Check merge categories disabled ### +# Check that the merged category is not there +NO_MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_(Category01|Category02) + +# Check that the original categories are there +NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category01 +NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category02 + + + +#--- a64_fakedylib.s + + .section __DATA,__objc_data + .globl _OBJC_CLASS_$_MyBaseClass +_OBJC_CLASS_$_MyBaseClass: + .quad 0 + +#--- merge_cat_minimal.s + +; ================== Generated from ObjC: ================== +; __attribute__((objc_root_class)) +; @interface MyBaseClass +; - (void)baseInstanceMethod; +; @end +; +; @interface MyBaseClass(Category01) +; - (void)cat01_InstanceMethod; +; @end +; +; @implementation MyBaseClass(Category01) +; - (void)cat01_InstanceMethod {} +; @end +; +; @interface MyBaseClass(Category02) +; - (void)cat02_InstanceMethod; +; @end +; +; @implementation MyBaseClass(Category02) +; - (void)cat02_InstanceMethod {} +; @end +; ================== Generated from ObjC: ================== + + .section __TEXT,__text,regular,pure_instructions + .p2align 2 ; -- Begin function -[MyBaseClass(Category01) cat01_InstanceMethod] +"-[MyBaseClass(Category01) cat01_InstanceMethod]": ; @"\01-[MyBaseClass(Category01) cat01_InstanceMethod]" + .cfi_startproc + ret + .cfi_endproc + ; -- End function + .p2align 2 ; -- Begin function -[MyBaseClass(Category02) cat02_InstanceMethod] +"-[MyBaseClass(Category02) cat02_InstanceMethod]": ; @"\01-[MyBaseClass(Category02) cat02_InstanceMethod]" + .cfi_startproc + ret + .cfi_endproc + ; -- End function + .section __TEXT,__objc_classname,cstring_literals +l_OBJC_CLASS_NAME_: ; @OBJC_CLASS_NAME_ + .asciz "Category01" + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_METH_VAR_NAME_: ; @OBJC_METH_VAR_NAME_ + .asciz "cat01_InstanceMethod" + .section __TEXT,__objc_methtype,cstring_literals +l_OBJC_METH_VAR_TYPE_: ; @OBJC_METH_VAR_TYPE_ + .asciz "v16@0:8" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01" +__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01: + .long 24 ; 0x18 + .long 1 ; 0x1 + .quad l_OBJC_METH_VAR_NAME_ + .quad l_OBJC_METH_VAR_TYPE_ + .quad "-[MyBaseClass(Category01) cat01_InstanceMethod]" + .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category01" +__OBJC_$_CATEGORY_MyBaseClass_$_Category01: + .quad l_OBJC_CLASS_NAME_ + .quad _OBJC_CLASS_$_MyBaseClass + .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01 + .quad 0 + .quad 0 + .quad 0 + .quad 0 + .long 64 ; 0x40 + .space 4 + .section __TEXT,__objc_classname,cstring_literals +l_OBJC_CLASS_NAME_.1: ; @OBJC_CLASS_NAME_.1 + .asciz "Category02" + .section __TEXT,__objc_methname,cstring_literals +l_OBJC_METH_VAR_NAME_.2: ; @OBJC_METH_VAR_NAME_.2 + .asciz "cat02_InstanceMethod" + .section __DATA,__objc_const + .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02" +__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02: + .long 24 ; 0x18 + .long 1 ; 0x1 + .quad l_OBJC_METH_VAR_NAME_.2 + .quad l_OBJC_METH_VAR_TYPE_ + .quad "-[MyBaseClass(Category02) cat02_InstanceMethod]" + .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category02" +__OBJC_$_CATEGORY_MyBaseClass_$_Category02: + .quad l_OBJC_CLASS_NAME_.1 + .quad _OBJC_CLASS_$_MyBaseClass + .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02 + .quad 0 + .quad 0 + .quad 0 + .quad 0 + .long 64 ; 0x40 + .space 4 + .section __DATA,__objc_catlist,regular,no_dead_strip + .p2align 3, 0x0 ; @"OBJC_LABEL_CATEGORY_$" +l_OBJC_LABEL_CATEGORY_$: + .quad __OBJC_$_CATEGORY_MyBaseClass_$_Category01 + .quad __OBJC_$_CATEGORY_MyBaseClass_$_Category02 + .section __DATA,__objc_imageinfo,regular,no_dead_strip +L_OBJC_IMAGE_INFO: + .long 0 + .long 96 +.subsections_via_symbols -- GitLab From 4242d15e68580d1d1f7c4d782a59e6dffb698ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Clement=20=28=E3=83=90=E3=83=AC=E3=83=B3?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=B3=20=E3=82=AF=E3=83=AC=E3=83=A1?= =?UTF-8?q?=E3=83=B3=29?= <clementval@gmail.com> Date: Tue, 19 Mar 2024 13:15:58 -0700 Subject: [PATCH 143/307] [flang][cuda] Update syntax of fir.cuda_kernel_launch to match fir.call (#85814) `fir.cuda_kernel_launch` represents a call to a cuda kernel with the chervon syntax. Its assembly format is meant to match `fir.call`. This patch updates the format to match the syntax closer for args and their types. --- flang/include/flang/Optimizer/Dialect/FIROps.td | 2 +- flang/test/Lower/CUDA/cuda-kernel-calls.cuf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index 6e520d111701..8a7e36e42457 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -2466,7 +2466,7 @@ def fir_CUDAKernelLaunch : fir_Op<"cuda_kernel_launch", [CallOpInterface, let assemblyFormat = [{ $callee `<` `<` `<` $grid_x `,` $grid_y `,` $grid_z `,`$block_x `,` $block_y `,` $block_z ( `,` $bytes^ ( `,` $stream^ )? )? `>` `>` `>` - `` `(` ( $args^ `:` type($args) )? `)` attr-dict + `` `(` $args `)` `:` `(` type($args) `)` attr-dict }]; let extraClassDeclaration = [{ diff --git a/flang/test/Lower/CUDA/cuda-kernel-calls.cuf b/flang/test/Lower/CUDA/cuda-kernel-calls.cuf index 55b5246e59a0..f4327b326175 100644 --- a/flang/test/Lower/CUDA/cuda-kernel-calls.cuf +++ b/flang/test/Lower/CUDA/cuda-kernel-calls.cuf @@ -46,7 +46,7 @@ contains ! CHECK: fir.cuda_kernel_launch @_QMtest_callPdev_kernel0<<<%c10{{.*}}, %c1{{.*}}, %c1{{.*}}, %c20{{.*}}, %c1{{.*}}, %c1{{.*}}, %c2{{.*}}, %c0{{.*}}>>>() call dev_kernel1<<<1, 32>>>(a) -! CHECK: fir.cuda_kernel_launch @_QMtest_callPdev_kernel1<<<%c1{{.*}}, %c1{{.*}}, %c1{{.*}}, %c32{{.*}}, %c1{{.*}}, %c1{{.*}}>>>(%1#1 : !fir.ref<f32>) +! CHECK: fir.cuda_kernel_launch @_QMtest_callPdev_kernel1<<<%c1{{.*}}, %c1{{.*}}, %c1{{.*}}, %c32{{.*}}, %c1{{.*}}, %c1{{.*}}>>>(%1#1) : (!fir.ref<f32>) end end -- GitLab From 12a6546395c6225112731f33608afed452c4f8d1 Mon Sep 17 00:00:00 2001 From: Evan Wilde <etceterawilde@gmail.com> Date: Tue, 19 Mar 2024 13:17:11 -0700 Subject: [PATCH 144/307] Add support for sysroot-relative system header search paths (#82084) Clang supported header searchpaths of the form `-I =/path`, relative to the sysroot if one is passed, but did not implement that behavior for `-iquote`, `-isystem`, or `-idirafter`. This implements the `=` portion of the behavior implemented by GCC for these flags described in https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html. --- clang/lib/Frontend/CompilerInvocation.cpp | 43 +++++++++++++++-------- clang/test/Preprocessor/sysroot-prefix.c | 25 +++++++++++++ 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 2a21a9d619dc..0df6a82ccd89 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3191,6 +3191,22 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, bool IsIndexHeaderMap = false; bool IsSysrootSpecified = Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot); + + // Expand a leading `=` to the sysroot if one was passed (and it's not a + // framework flag). + auto PrefixHeaderPath = [IsSysrootSpecified, + &Opts](const llvm::opt::Arg *A, + bool IsFramework = false) -> std::string { + assert(A->getNumValues() && "Unexpected empty search path flag!"); + if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') { + SmallString<32> Buffer; + llvm::sys::path::append(Buffer, Opts.Sysroot, + llvm::StringRef(A->getValue()).substr(1)); + return std::string(Buffer); + } + return A->getValue(); + }; + for (const auto *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) { if (A->getOption().matches(OPT_index_header_map)) { // -index-header-map applies to the next -I or -F. @@ -3202,16 +3218,7 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, IsIndexHeaderMap ? frontend::IndexHeaderMap : frontend::Angled; bool IsFramework = A->getOption().matches(OPT_F); - std::string Path = A->getValue(); - - if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') { - SmallString<32> Buffer; - llvm::sys::path::append(Buffer, Opts.Sysroot, - llvm::StringRef(A->getValue()).substr(1)); - Path = std::string(Buffer); - } - - Opts.AddPath(Path, Group, IsFramework, + Opts.AddPath(PrefixHeaderPath(A, IsFramework), Group, IsFramework, /*IgnoreSysroot*/ true); IsIndexHeaderMap = false; } @@ -3229,12 +3236,18 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, } for (const auto *A : Args.filtered(OPT_idirafter)) - Opts.AddPath(A->getValue(), frontend::After, false, true); + Opts.AddPath(PrefixHeaderPath(A), frontend::After, false, true); for (const auto *A : Args.filtered(OPT_iquote)) - Opts.AddPath(A->getValue(), frontend::Quoted, false, true); - for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) - Opts.AddPath(A->getValue(), frontend::System, false, - !A->getOption().matches(OPT_iwithsysroot)); + Opts.AddPath(PrefixHeaderPath(A), frontend::Quoted, false, true); + + for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) { + if (A->getOption().matches(OPT_iwithsysroot)) { + Opts.AddPath(A->getValue(), frontend::System, false, + /*IgnoreSysRoot=*/false); + continue; + } + Opts.AddPath(PrefixHeaderPath(A), frontend::System, false, true); + } for (const auto *A : Args.filtered(OPT_iframework)) Opts.AddPath(A->getValue(), frontend::System, true, true); for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot)) diff --git a/clang/test/Preprocessor/sysroot-prefix.c b/clang/test/Preprocessor/sysroot-prefix.c index 08c72f53b44e..eff71f5e3d5a 100644 --- a/clang/test/Preprocessor/sysroot-prefix.c +++ b/clang/test/Preprocessor/sysroot-prefix.c @@ -4,6 +4,16 @@ // RUN: %clang_cc1 -v -isysroot /var/empty -I =null -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_SYSROOT_NULL %s // RUN: %clang_cc1 -v -isysroot /var/empty -isysroot /var/empty/root -I =null -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_ISYSROOT_SYSROOT_NULL %s // RUN: %clang_cc1 -v -isysroot /var/empty/root -isysroot /var/empty -I =null -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_ISYSROOT_SWAPPED_SYSROOT_NULL %s +// RUN: %clang_cc1 -v -isystem=/usr/include -isysroot /var/empty -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_ISYSTEM_SYSROOT %s +// RUN: %clang_cc1 -v -isystem=/usr/include -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_ISYSTEM_NO_SYSROOT %s +// RUN: %clang_cc1 -v -iquote=/usr/include -isysroot /var/empty -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_IQUOTE_SYSROOT %s +// RUN: %clang_cc1 -v -iquote=/usr/include -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_IQUOTE_NO_SYSROOT %s +// RUN: %clang_cc1 -v -idirafter=/usr/include -isysroot /var/empty -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_IDIRAFTER_SYSROOT %s +// RUN: %clang_cc1 -v -idirafter=/usr/include -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-ISYSROOT_IDIRAFTER_NO_SYSROOT %s +// RUN: %clang_cc1 -v -isysroot /var/empty -isystem=/usr/include -iwithsysroot /opt/include -isystem=/usr/local/include -E %s -o /dev/null 2>&1 | FileCheck -check-prefix CHECK-INTERLEAVE_I_PATHS %s + +// RUN: not %clang_cc1 -v -isysroot /var/empty -E %s -o /dev/null -I 2>&1 | FileCheck -check-prefix CHECK-EMPTY_I_PATH %s +// RUN: %clang_cc1 -v -isysroot /var/empty/usr -E %s -o /dev/null -I= 2>&1 | FileCheck -check-prefix CHECK-SYSROOT_I_PATH %s // CHECK-ISYSROOT_NO_SYSROOT: ignoring nonexistent directory "/var/empty/include" // CHECK-ISYSROOT_NO_SYSROOT-NOT: ignoring nonexistent directory "/var/empty/var/empty/include" @@ -23,3 +33,18 @@ // CHECK-ISYSROOT_ISYSROOT_SWAPPED_SYSROOT_NULL: ignoring nonexistent directory "/var/empty{{.}}null" // CHECK-ISYSROOT_ISYSROOT_SWAPPED_SYSROOT_NULL-NOT: ignoring nonexistent directory "=null" +// CHECK-ISYSROOT_ISYSTEM_SYSROOT: ignoring nonexistent directory "/var/empty/usr/include" +// CHECK-ISYSROOT_ISYSTEM_NO_SYSROOT: ignoring nonexistent directory "=/usr/include" + +// CHECK-ISYSROOT_IQUOTE_SYSROOT: ignoring nonexistent directory "/var/empty/usr/include" +// CHECK-ISYSROOT_IQUOTE_NO_SYSROOT: ignoring nonexistent directory "=/usr/include" + +// CHECK-ISYSROOT_IDIRAFTER_SYSROOT: ignoring nonexistent directory "/var/empty/usr/include" +// CHECK-ISYSROOT_IDIRAFTER_NO_SYSROOT: ignoring nonexistent directory "=/usr/include" + +// CHECK-INTERLEAVE_I_PATHS: ignoring nonexistent directory "/var/empty/usr/include" +// CHECK-INTERLEAVE_I_PATHS: ignoring nonexistent directory "/var/empty/opt/include" +// CHECK-INTERLEAVE_I_PATHS: ignoring nonexistent directory "/var/empty/usr/local/include" + +// CHECK-EMPTY_I_PATH: argument to '-I' is missing +// CHECK-SYSROOT_I_PATH: ignoring nonexistent directory "/var/empty/usr{{/|\\}}" -- GitLab From 2377b9773d40d2daa249ac20fe452f041bb6a88c Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <llvm-dev@redking.me.uk> Date: Tue, 19 Mar 2024 20:17:56 +0000 Subject: [PATCH 145/307] [DAG] SimplifyShift - shift i1/vXi1 X, Y --> X (any non-zero shift amount is undefined). Alive2: https://alive2.llvm.org/ce/z/SdESbg Fixes #85681 --- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 4 ++ llvm/test/CodeGen/X86/pr85681.ll | 41 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 llvm/test/CodeGen/X86/pr85681.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 6f6ed4bd4502..9d73a42df2a4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -9595,6 +9595,10 @@ SDValue SelectionDAG::simplifyShift(SDValue X, SDValue Y) { if (ISD::matchUnaryPredicate(Y, isShiftTooBig, true)) return getUNDEF(X.getValueType()); + // shift i1/vXi1 X, Y --> X (any non-zero shift amount is undefined). + if (X.getValueType().getScalarType() == MVT::i1) + return X; + return SDValue(); } diff --git a/llvm/test/CodeGen/X86/pr85681.ll b/llvm/test/CodeGen/X86/pr85681.ll new file mode 100644 index 000000000000..3b27a0257ab4 --- /dev/null +++ b/llvm/test/CodeGen/X86/pr85681.ll @@ -0,0 +1,41 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc < %s -mtriple=x86_64-- -mcpu=emeraldrapids | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s + +; PR85681 - shift i1/vXi1 X, Y -> X as only Y==0 is defined + +define i32 @shl(i32 %a0) { +; CHECK-LABEL: shl: +; CHECK: # %bb.0: +; CHECK-NEXT: movl $-1, %eax +; CHECK-NEXT: retq + %v0 = bitcast i32 %a0 to <32 x i1> + %s = shl <32 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, %v0 + %r = bitcast <32 x i1> %s to i32 + ret i32 %r +} + +define i32 @lshr(i32 %a0) { +; CHECK-LABEL: lshr: +; CHECK: # %bb.0: +; CHECK-NEXT: movl $-1, %eax +; CHECK-NEXT: retq + %v0 = bitcast i32 %a0 to <32 x i1> + %s = lshr <32 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, %v0 + %r = bitcast <32 x i1> %s to i32 + ret i32 %r +} + +define i32 @ashr(i32 %a0) { +; CHECK-LABEL: ashr: +; CHECK: # %bb.0: +; CHECK-NEXT: movl $-1, %eax +; CHECK-NEXT: retq + %v0 = bitcast i32 %a0 to <32 x i1> + %s = ashr <32 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, %v0 + %r = bitcast <32 x i1> %s to i32 + ret i32 %r +} -- GitLab From 8cbb8ac02cc481723a0e0c20beab03fdc50accd9 Mon Sep 17 00:00:00 2001 From: Finn Plummer <50529406+inbelic@users.noreply.github.com> Date: Tue, 19 Mar 2024 13:27:35 -0700 Subject: [PATCH 146/307] [mlir][spirv] Add folding for SelectOp (#85430) Add missing constant propogation folder for spirv.Select Implement additional folding when both selections are equivalent or the condition is a constant Scalar/SplatVector. Allows for constant folding in the IndexToSPIRV pass. Part of work #70704 --- .../mlir/Dialect/SPIRV/IR/SPIRVLogicalOps.td | 2 + .../SPIRV/IR/SPIRVCanonicalization.cpp | 43 +++++++++++++++++ .../SPIRVToLLVM/misc-ops-to-llvm.mlir | 10 ++-- .../SPIRV/Transforms/canonicalize.mlir | 46 +++++++++++++++++++ 4 files changed, 96 insertions(+), 5 deletions(-) diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVLogicalOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVLogicalOps.td index e48a56f0625d..3ee239d6e1e3 100644 --- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVLogicalOps.td +++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVLogicalOps.td @@ -800,6 +800,8 @@ def SPIRV_SelectOp : SPIRV_Op<"Select", // These ops require dynamic availability specification based on operand and // result types. bit autogenAvailability = 0; + + let hasFolder = 1; } // ----- diff --git a/mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.cpp b/mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.cpp index 4c62289a1e94..ff4bace9a4d8 100644 --- a/mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.cpp +++ b/mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.cpp @@ -797,6 +797,49 @@ OpFoldResult spirv::LogicalOrOp::fold(FoldAdaptor adaptor) { return Attribute(); } +//===----------------------------------------------------------------------===// +// spirv.SelectOp +//===----------------------------------------------------------------------===// + +OpFoldResult spirv::SelectOp::fold(FoldAdaptor adaptor) { + // spirv.Select _ x x -> x + Value trueVals = getTrueValue(); + Value falseVals = getFalseValue(); + if (trueVals == falseVals) + return trueVals; + + ArrayRef<Attribute> operands = adaptor.getOperands(); + + // spirv.Select true x y -> x + // spirv.Select false x y -> y + if (auto boolAttr = getScalarOrSplatBoolAttr(operands[0])) + return *boolAttr ? trueVals : falseVals; + + // Check that all the operands are constant + if (!operands[0] || !operands[1] || !operands[2]) + return Attribute(); + + // Note: getScalarOrSplatBoolAttr will always return a boolAttr if we are in + // the scalar case. Hence, we are only required to consider the case of + // DenseElementsAttr in foldSelectOp. + auto condAttrs = dyn_cast<DenseElementsAttr>(operands[0]); + auto trueAttrs = dyn_cast<DenseElementsAttr>(operands[1]); + auto falseAttrs = dyn_cast<DenseElementsAttr>(operands[2]); + if (!condAttrs || !trueAttrs || !falseAttrs) + return Attribute(); + + auto elementResults = llvm::to_vector<4>(trueAttrs.getValues<Attribute>()); + auto iters = llvm::zip_equal(elementResults, condAttrs.getValues<BoolAttr>(), + falseAttrs.getValues<Attribute>()); + for (auto [result, cond, falseRes] : iters) { + if (!cond.getValue()) + result = falseRes; + } + + auto resultType = trueAttrs.getType(); + return DenseElementsAttr::get(cast<ShapedType>(resultType), elementResults); +} + //===----------------------------------------------------------------------===// // spirv.IEqualOp //===----------------------------------------------------------------------===// diff --git a/mlir/test/Conversion/SPIRVToLLVM/misc-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/misc-ops-to-llvm.mlir index 9fe1e532dfc7..31da59dcdc72 100644 --- a/mlir/test/Conversion/SPIRVToLLVM/misc-ops-to-llvm.mlir +++ b/mlir/test/Conversion/SPIRVToLLVM/misc-ops-to-llvm.mlir @@ -43,18 +43,18 @@ spirv.func @composite_insert_vector(%arg0: vector<3xf32>, %arg1: f32) "None" { //===----------------------------------------------------------------------===// // CHECK-LABEL: @select_scalar -spirv.func @select_scalar(%arg0: i1, %arg1: vector<3xi32>, %arg2: f32) "None" { +spirv.func @select_scalar(%arg0: i1, %arg1: vector<3xi32>, %arg2: vector<3xi32>, %arg3: f32, %arg4: f32) "None" { // CHECK: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : i1, vector<3xi32> - %0 = spirv.Select %arg0, %arg1, %arg1 : i1, vector<3xi32> + %0 = spirv.Select %arg0, %arg1, %arg2 : i1, vector<3xi32> // CHECK: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : i1, f32 - %1 = spirv.Select %arg0, %arg2, %arg2 : i1, f32 + %1 = spirv.Select %arg0, %arg3, %arg4 : i1, f32 spirv.Return } // CHECK-LABEL: @select_vector -spirv.func @select_vector(%arg0: vector<2xi1>, %arg1: vector<2xi32>) "None" { +spirv.func @select_vector(%arg0: vector<2xi1>, %arg1: vector<2xi32>, %arg2: vector<2xi32>) "None" { // CHECK: llvm.select %{{.*}}, %{{.*}}, %{{.*}} : vector<2xi1>, vector<2xi32> - %0 = spirv.Select %arg0, %arg1, %arg1 : vector<2xi1>, vector<2xi32> + %0 = spirv.Select %arg0, %arg1, %arg2 : vector<2xi1>, vector<2xi32> spirv.Return } diff --git a/mlir/test/Dialect/SPIRV/Transforms/canonicalize.mlir b/mlir/test/Dialect/SPIRV/Transforms/canonicalize.mlir index 1cb69891a70e..de21d114e9fc 100644 --- a/mlir/test/Dialect/SPIRV/Transforms/canonicalize.mlir +++ b/mlir/test/Dialect/SPIRV/Transforms/canonicalize.mlir @@ -1346,6 +1346,52 @@ func.func @convert_logical_or_true_false_vector(%arg: vector<3xi1>) -> (vector<3 // ----- +//===----------------------------------------------------------------------===// +// spirv.Select +//===----------------------------------------------------------------------===// + +// CHECK-LABEL: @convert_select_scalar +// CHECK-SAME: %[[ARG1:.+]]: i32, %[[ARG2:.+]]: i32 +func.func @convert_select_scalar(%arg1: i32, %arg2: i32) -> (i32, i32) { + %true = spirv.Constant true + %false = spirv.Constant false + %0 = spirv.Select %true, %arg1, %arg2 : i1, i32 + %1 = spirv.Select %false, %arg1, %arg2 : i1, i32 + + // CHECK: return %[[ARG1]], %[[ARG2]] + return %0, %1 : i32, i32 +} + +// CHECK-LABEL: @convert_select_vector +// CHECK-SAME: %[[ARG1:.+]]: vector<3xi32>, %[[ARG2:.+]]: vector<3xi32> +func.func @convert_select_vector(%arg1: vector<3xi32>, %arg2: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) { + %true = spirv.Constant dense<true> : vector<3xi1> + %false = spirv.Constant dense<false> : vector<3xi1> + %0 = spirv.Select %true, %arg1, %arg2 : vector<3xi1>, vector<3xi32> + %1 = spirv.Select %false, %arg1, %arg2 : vector<3xi1>, vector<3xi32> + + // CHECK: return %[[ARG1]], %[[ARG2]] + return %0, %1: vector<3xi32>, vector<3xi32> +} + +// CHECK-LABEL: @convert_select_vector_extra +// CHECK-SAME: %[[CONDITIONS:.+]]: vector<2xi1>, %[[ARG1:.+]]: vector<2xi32> +func.func @convert_select_vector_extra(%conditions: vector<2xi1>, %arg1: vector<2xi32>) -> (vector<2xi32>, vector<2xi32>) { + %true_false = spirv.Constant dense<[true, false]> : vector<2xi1> + %cvec_1 = spirv.Constant dense<[42, -132]> : vector<2xi32> + %cvec_2 = spirv.Constant dense<[0, 42]> : vector<2xi32> + + // CHECK: %[[RES:.+]] = spirv.Constant dense<42> + %0 = spirv.Select %true_false, %cvec_1, %cvec_2: vector<2xi1>, vector<2xi32> + + %1 = spirv.Select %conditions, %arg1, %arg1 : vector<2xi1>, vector<2xi32> + + // CHECK: return %[[RES]], %[[ARG1]] + return %0, %1: vector<2xi32>, vector<2xi32> +} + +// ----- + //===----------------------------------------------------------------------===// // spirv.IEqual //===----------------------------------------------------------------------===// -- GitLab From 5cfcd9bc13ac0f1be519e2e2d69276c82cbba3b9 Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulkirth@google.com> Date: Mon, 18 Mar 2024 22:01:47 +0000 Subject: [PATCH 147/307] [cmake] Reenable FatLTO for Fuchsia toolchains We can reenable this now that FatLTO won't be enabled for Mac platforms Pull Request: https://github.com/llvm/llvm-project/pull/85709 --- clang/cmake/caches/Fuchsia-stage2.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index bc1a05345ce2..d5546e20873b 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -11,7 +11,7 @@ set(LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING " set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") set(LLVM_ENABLE_DIA_SDK OFF CACHE BOOL "") -set(LLVM_ENABLE_FATLTO OFF CACHE BOOL "") +set(LLVM_ENABLE_FATLTO ON CACHE BOOL "") set(LLVM_ENABLE_HTTPLIB ON CACHE BOOL "") set(LLVM_ENABLE_LIBCXX ON CACHE BOOL "") set(LLVM_ENABLE_LIBEDIT OFF CACHE BOOL "") -- GitLab From e3030f1e1958a2be51822bacce764395c16e682a Mon Sep 17 00:00:00 2001 From: Alfie Richards <alfie.richards@arm.com> Date: Tue, 19 Mar 2024 21:11:48 +0000 Subject: [PATCH 148/307] [ARM] FIX: Fix parsing `pkhtb` with a condition code This was broken by https://github.com/llvm/llvm-project/pull/83436 as in optional operands meant when the CC operand is provided the `parsePKHImm` parser is applied to register operands, which previously erroneously produced an error. --- .../lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 64 ++++++++++++------- .../ARM/MCTargetDesc/ARMAddressingModes.h | 2 +- llvm/test/MC/ARM/basic-arm-instructions.s | 4 ++ 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 026d4ca06e87..9cfdb15a0f43 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -63,6 +63,7 @@ #include <iterator> #include <limits> #include <memory> +#include <optional> #include <string> #include <utility> #include <vector> @@ -457,6 +458,7 @@ class ARMAsmParser : public MCTargetAsmParser { int tryParseRegister(bool AllowOutofBoundReg = false); bool tryParseRegisterWithWriteBack(OperandVector &); int tryParseShiftRegister(OperandVector &); + std::optional<ARM_AM::ShiftOpc> tryParseShiftToken(); bool parseRegisterList(OperandVector &, bool EnforceOrder = true, bool AllowRAAC = false, bool AllowOutOfBoundReg = false); @@ -647,12 +649,13 @@ class ARMAsmParser : public MCTargetAsmParser { ParseStatus parseProcIFlagsOperand(OperandVector &); ParseStatus parseMSRMaskOperand(OperandVector &); ParseStatus parseBankedRegOperand(OperandVector &); - ParseStatus parsePKHImm(OperandVector &O, StringRef Op, int Low, int High); + ParseStatus parsePKHImm(OperandVector &O, ARM_AM::ShiftOpc, int Low, + int High); ParseStatus parsePKHLSLImm(OperandVector &O) { - return parsePKHImm(O, "lsl", 0, 31); + return parsePKHImm(O, ARM_AM::lsl, 0, 31); } ParseStatus parsePKHASRImm(OperandVector &O) { - return parsePKHImm(O, "asr", 1, 32); + return parsePKHImm(O, ARM_AM::asr, 1, 32); } ParseStatus parseSetEndImm(OperandVector &); ParseStatus parseShifterImm(OperandVector &); @@ -4228,30 +4231,36 @@ int ARMAsmParser::tryParseRegister(bool AllowOutOfBoundReg) { return RegNum; } -// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. -// If a recoverable error occurs, return 1. If an irrecoverable error -// occurs, return -1. An irrecoverable error is one where tokens have been -// consumed in the process of trying to parse the shifter (i.e., when it is -// indeed a shifter operand, but malformed). -int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) { +std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() { MCAsmParser &Parser = getParser(); - SMLoc S = Parser.getTok().getLoc(); const AsmToken &Tok = Parser.getTok(); if (Tok.isNot(AsmToken::Identifier)) - return -1; + return std::nullopt; std::string lowerCase = Tok.getString().lower(); - ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) + return StringSwitch<std::optional<ARM_AM::ShiftOpc>>(lowerCase) .Case("asl", ARM_AM::lsl) .Case("lsl", ARM_AM::lsl) .Case("lsr", ARM_AM::lsr) .Case("asr", ARM_AM::asr) .Case("ror", ARM_AM::ror) .Case("rrx", ARM_AM::rrx) - .Default(ARM_AM::no_shift); + .Default(std::nullopt); +} + +// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. +// If a recoverable error occurs, return 1. If an irrecoverable error +// occurs, return -1. An irrecoverable error is one where tokens have been +// consumed in the process of trying to parse the shifter (i.e., when it is +// indeed a shifter operand, but malformed). +int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); + SMLoc S = Parser.getTok().getLoc(); - if (ShiftTy == ARM_AM::no_shift) + auto ShiftTyOpt = tryParseShiftToken(); + if (ShiftTyOpt == std::nullopt) return 1; + auto ShiftTy = ShiftTyOpt.value(); Parser.Lex(); // Eat the operator. @@ -5284,17 +5293,24 @@ ParseStatus ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) { return ParseStatus::Success; } -ParseStatus ARMAsmParser::parsePKHImm(OperandVector &Operands, StringRef Op, - int Low, int High) { +// FIXME: Unify the different methods for handling shift operators +// and use TableGen matching mechanisms to do the validation rather than +// separate parsing paths. +ParseStatus ARMAsmParser::parsePKHImm(OperandVector &Operands, + ARM_AM::ShiftOpc Op, int Low, int High) { MCAsmParser &Parser = getParser(); - const AsmToken &Tok = Parser.getTok(); - if (Tok.isNot(AsmToken::Identifier)) - return Error(Parser.getTok().getLoc(), Op + " operand expected."); - StringRef ShiftName = Tok.getString(); - std::string LowerOp = Op.lower(); - std::string UpperOp = Op.upper(); - if (ShiftName != LowerOp && ShiftName != UpperOp) - return Error(Parser.getTok().getLoc(), Op + " operand expected."); + auto ShiftCodeOpt = tryParseShiftToken(); + + if (!ShiftCodeOpt.has_value()) + return ParseStatus::NoMatch; + auto ShiftCode = ShiftCodeOpt.value(); + + // The wrong shift code has been provided. Can error here as has matched the + // correct operand in this case. + if (ShiftCode != Op) + return Error(Parser.getTok().getLoc(), + ARM_AM::getShiftOpcStr(Op) + " operand expected."); + Parser.Lex(); // Eat shift type token. // There must be a '#' and a shift amount. diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h index 163360c08ffb..28e5840fdde5 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h @@ -41,7 +41,7 @@ namespace ARM_AM { inline const char *getAddrOpcStr(AddrOpc Op) { return Op == sub ? "-" : ""; } - inline const char *getShiftOpcStr(ShiftOpc Op) { + inline const StringRef getShiftOpcStr(ShiftOpc Op) { switch (Op) { default: llvm_unreachable("Unknown shift opc!"); case ARM_AM::asr: return "asr"; diff --git a/llvm/test/MC/ARM/basic-arm-instructions.s b/llvm/test/MC/ARM/basic-arm-instructions.s index 055f3ce31615..84a7cf52fa30 100644 --- a/llvm/test/MC/ARM/basic-arm-instructions.s +++ b/llvm/test/MC/ARM/basic-arm-instructions.s @@ -1774,6 +1774,9 @@ Lforward: pkhtb r2, r2, r3, asr #31 pkhtb r2, r2, r3, asr #15 + it ne + pkhtbne r2, r2, r3, asr #15 + @ CHECK: pkhbt r2, r2, r3 @ encoding: [0x13,0x20,0x82,0xe6] @ CHECK: pkhbt r2, r2, r3, lsl #31 @ encoding: [0x93,0x2f,0x82,0xe6] @ CHECK: pkhbt r2, r2, r3 @ encoding: [0x13,0x20,0x82,0xe6] @@ -1782,6 +1785,7 @@ Lforward: @ CHECK: pkhbt r2, r3, r2 @ encoding: [0x12,0x20,0x83,0xe6] @ CHECK: pkhtb r2, r2, r3, asr #31 @ encoding: [0xd3,0x2f,0x82,0xe6] @ CHECK: pkhtb r2, r2, r3, asr #15 @ encoding: [0xd3,0x27,0x82,0xe6] +@ CHECK: pkhtbne r2, r2, r3, asr #15 @ encoding: [0xd3,0x27,0x82,0x16] @------------------------------------------------------------------------------ @ FIXME: PLD -- GitLab From 31f4b329c8234fab9afa59494d7f8bdaeaefeaad Mon Sep 17 00:00:00 2001 From: quic-areg <aregmi@quicinc.com> Date: Tue, 19 Mar 2024 16:22:30 -0500 Subject: [PATCH 149/307] [Hexagon] ELF attributes for Hexagon (#85359) Defines a subset of attributes and emits them to a section called .hexagon.attributes. The current attributes recorded are the attributes needed by llvm-objdump to automatically determine target features and eliminate the need to manually pass features. --- clang/lib/Driver/ToolChains/Clang.cpp | 8 ++ .../Driver/hexagon-default-build-attributes.s | 21 +++++ llvm/include/llvm/BinaryFormat/ELF.h | 2 + llvm/include/llvm/Object/ELFObjectFile.h | 4 + .../llvm/Support/HexagonAttributeParser.h | 37 ++++++++ llvm/include/llvm/Support/HexagonAttributes.h | 32 +++++++ llvm/lib/Object/ELF.cpp | 5 +- llvm/lib/Object/ELFObjectFile.cpp | 78 +++++++++++++++ llvm/lib/ObjectYAML/ELFYAML.cpp | 1 + llvm/lib/Support/CMakeLists.txt | 2 + llvm/lib/Support/HexagonAttributeParser.cpp | 55 +++++++++++ llvm/lib/Support/HexagonAttributes.cpp | 27 ++++++ .../Hexagon/AsmParser/HexagonAsmParser.cpp | 61 +++++++++++- llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp | 20 ++++ llvm/lib/Target/Hexagon/HexagonAsmPrinter.h | 4 + .../Target/Hexagon/HexagonTargetStreamer.h | 9 ++ .../MCTargetDesc/HexagonMCELFStreamer.cpp | 61 ++++++++++++ .../MCTargetDesc/HexagonMCTargetDesc.cpp | 72 ++++++++++++-- .../MCTargetDesc/HexagonMCTargetDesc.h | 6 +- llvm/test/CodeGen/Hexagon/build-attributes.ll | 16 ++++ .../test/MC/Hexagon/directive-attribute-err.s | 24 +++++ llvm/test/MC/Hexagon/directive-attribute.s | 41 ++++++++ llvm/test/MC/Hexagon/hexagon_attributes.s | 94 +++++++++++++++++++ .../ELF/machine-specific-section-types.test | 4 + llvm/tools/llvm-readobj/ELFDumper.cpp | 6 ++ 25 files changed, 681 insertions(+), 9 deletions(-) create mode 100644 clang/test/Driver/hexagon-default-build-attributes.s create mode 100644 llvm/include/llvm/Support/HexagonAttributeParser.h create mode 100644 llvm/include/llvm/Support/HexagonAttributes.h create mode 100644 llvm/lib/Support/HexagonAttributeParser.cpp create mode 100644 llvm/lib/Support/HexagonAttributes.cpp create mode 100644 llvm/test/CodeGen/Hexagon/build-attributes.ll create mode 100644 llvm/test/MC/Hexagon/directive-attribute-err.s create mode 100644 llvm/test/MC/Hexagon/directive-attribute.s create mode 100644 llvm/test/MC/Hexagon/hexagon_attributes.s diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 055884d275ce..bcdf2737bc7a 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -8481,6 +8481,14 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, case llvm::Triple::riscv64: AddRISCVTargetArgs(Args, CmdArgs); break; + + case llvm::Triple::hexagon: + if (Args.hasFlag(options::OPT_mdefault_build_attributes, + options::OPT_mno_default_build_attributes, true)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-hexagon-add-build-attributes"); + } + break; } // Consume all the warning flags. Usually this would be handled more diff --git a/clang/test/Driver/hexagon-default-build-attributes.s b/clang/test/Driver/hexagon-default-build-attributes.s new file mode 100644 index 000000000000..58f246c2f805 --- /dev/null +++ b/clang/test/Driver/hexagon-default-build-attributes.s @@ -0,0 +1,21 @@ +/// Enabled by default for assembly +// RUN: %clang --target=hexagon-unknown-elf -### %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-ENABLED + +/// Can be forced on or off for assembly. +// RUN: %clang --target=hexagon-unknown-elf -### %s 2>&1 -mno-default-build-attributes \ +// RUN: | FileCheck %s -check-prefix CHECK-DISABLED +// RUN: %clang --target=hexagon-unknown-elf -### %s 2>&1 -mdefault-build-attributes \ +// RUN: | FileCheck %s -check-prefix CHECK-ENABLED + +/// Option ignored C/C++ (since we always emit hardware and ABI build attributes +/// during codegen). +// RUN: %clang --target=hexagon-unknown-elf -### -x c %s -mdefault-build-attributes 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-DISABLED-C +// RUN: %clang --target=hexagon-unknown-elf -### -x c++ %s -mdefault-build-attributes 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-DISABLED-C + +// CHECK-DISABLED-NOT: "-hexagon-add-build-attributes" +// CHECK-DISABLED-C-NOT: "-hexagon-add-build-attributes" +// CHECK-ENABLED: "-hexagon-add-build-attributes" +// CHECK-DISABLED-C: argument unused during compilation: '-mdefault-build-attributes' diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index bace3a92677a..877f3f7862c8 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -1141,6 +1141,8 @@ enum : unsigned { SHT_CSKY_ATTRIBUTES = 0x70000001U, + SHT_HEXAGON_ATTRIBUTES = 0x70000003U, + SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type. SHT_LOUSER = 0x80000000, // Lowest type reserved for applications. SHT_HIUSER = 0xffffffff // Highest type reserved for applications. diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 1e73de9f08c1..f57a7ab8882a 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -60,6 +60,7 @@ class ELFObjectFileBase : public ObjectFile { SubtargetFeatures getMIPSFeatures() const; SubtargetFeatures getARMFeatures() const; + SubtargetFeatures getHexagonFeatures() const; Expected<SubtargetFeatures> getRISCVFeatures() const; SubtargetFeatures getLoongArchFeatures() const; @@ -397,6 +398,9 @@ protected: case ELF::EM_RISCV: Type = ELF::SHT_RISCV_ATTRIBUTES; break; + case ELF::EM_HEXAGON: + Type = ELF::SHT_HEXAGON_ATTRIBUTES; + break; default: return Error::success(); } diff --git a/llvm/include/llvm/Support/HexagonAttributeParser.h b/llvm/include/llvm/Support/HexagonAttributeParser.h new file mode 100644 index 000000000000..1116dd42b1ad --- /dev/null +++ b/llvm/include/llvm/Support/HexagonAttributeParser.h @@ -0,0 +1,37 @@ +//===-- HexagonAttributeParser.h - Hexagon Attribute Parser -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_HEXAGONATTRIBUTEPARSER_H +#define LLVM_SUPPORT_HEXAGONATTRIBUTEPARSER_H + +#include "llvm/Support/ELFAttributeParser.h" +#include "llvm/Support/HexagonAttributes.h" + +namespace llvm { +class HexagonAttributeParser : public ELFAttributeParser { + struct DisplayHandler { + HexagonAttrs::AttrType Attribute; + Error (HexagonAttributeParser::*Routine)(unsigned); + }; + + static const DisplayHandler DisplayRoutines[]; + + Error handler(uint64_t Tag, bool &Handled) override; + +public: + HexagonAttributeParser(ScopedPrinter *SP) + : ELFAttributeParser(SP, HexagonAttrs::getHexagonAttributeTags(), + "hexagon") {} + HexagonAttributeParser() + : ELFAttributeParser(HexagonAttrs::getHexagonAttributeTags(), "hexagon") { + } +}; + +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/Support/HexagonAttributes.h b/llvm/include/llvm/Support/HexagonAttributes.h new file mode 100644 index 000000000000..8a50d8993e63 --- /dev/null +++ b/llvm/include/llvm/Support/HexagonAttributes.h @@ -0,0 +1,32 @@ +//===-- HexagonAttributes.h - Qualcomm Hexagon Attributes -----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_HEXAGONATTRIBUTES_H +#define LLVM_SUPPORT_HEXAGONATTRIBUTES_H + +#include "llvm/Support/ELFAttributes.h" + +namespace llvm { +namespace HexagonAttrs { + +const TagNameMap &getHexagonAttributeTags(); + +enum AttrType : unsigned { + ARCH = 4, + HVXARCH = 5, + HVXIEEEFP = 6, + HVXQFLOAT = 7, + ZREG = 8, + AUDIO = 9, + CABAC = 10 +}; + +} // namespace HexagonAttrs +} // namespace llvm + +#endif diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index 137f606dd2d4..55dd0c8e06c0 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -251,7 +251,10 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) { } break; case ELF::EM_HEXAGON: - switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); } + switch (Type) { + STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); + STRINGIFY_ENUM_CASE(ELF, SHT_HEXAGON_ATTRIBUTES); + } break; case ELF::EM_X86_64: switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); } diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp index 33be48196ae7..efec612957de 100644 --- a/llvm/lib/Object/ELFObjectFile.cpp +++ b/llvm/lib/Object/ELFObjectFile.cpp @@ -20,6 +20,7 @@ #include "llvm/Support/ARMAttributeParser.h" #include "llvm/Support/ARMBuildAttributes.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/HexagonAttributeParser.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/RISCVAttributeParser.h" #include "llvm/Support/RISCVAttributes.h" @@ -287,6 +288,81 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const { return Features; } +static std::optional<std::string> hexagonAttrToFeatureString(unsigned Attr) { + switch (Attr) { + case 5: + return "v5"; + case 55: + return "v55"; + case 60: + return "v60"; + case 62: + return "v62"; + case 65: + return "v65"; + case 67: + return "v67"; + case 68: + return "v68"; + case 69: + return "v69"; + case 71: + return "v71"; + case 73: + return "v73"; + default: + return {}; + } +} + +SubtargetFeatures ELFObjectFileBase::getHexagonFeatures() const { + SubtargetFeatures Features; + HexagonAttributeParser Parser; + if (Error E = getBuildAttributes(Parser)) { + // Return no attributes if none can be read. + // This behavior is important for backwards compatibility. + consumeError(std::move(E)); + return Features; + } + std::optional<unsigned> Attr; + + if ((Attr = Parser.getAttributeValue(HexagonAttrs::ARCH))) { + if (std::optional<std::string> FeatureString = + hexagonAttrToFeatureString(*Attr)) + Features.AddFeature(*FeatureString); + } + + if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXARCH))) { + std::optional<std::string> FeatureString = + hexagonAttrToFeatureString(*Attr); + // There is no corresponding hvx arch for v5 and v55. + if (FeatureString && *Attr >= 60) + Features.AddFeature("hvx" + *FeatureString); + } + + if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXIEEEFP))) + if (*Attr) + Features.AddFeature("hvx-ieee-fp"); + + if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXQFLOAT))) + if (*Attr) + Features.AddFeature("hvx-qfloat"); + + if ((Attr = Parser.getAttributeValue(HexagonAttrs::ZREG))) + if (*Attr) + Features.AddFeature("zreg"); + + if ((Attr = Parser.getAttributeValue(HexagonAttrs::AUDIO))) + if (*Attr) + Features.AddFeature("audio"); + + if ((Attr = Parser.getAttributeValue(HexagonAttrs::CABAC))) + if (*Attr) + Features.AddFeature("cabac"); + + return Features; +} + Expected<SubtargetFeatures> ELFObjectFileBase::getRISCVFeatures() const { SubtargetFeatures Features; unsigned PlatformFlags = getPlatformFlags(); @@ -349,6 +425,8 @@ Expected<SubtargetFeatures> ELFObjectFileBase::getFeatures() const { return getRISCVFeatures(); case ELF::EM_LOONGARCH: return getLoongArchFeatures(); + case ELF::EM_HEXAGON: + return getHexagonFeatures(); default: return SubtargetFeatures(); } diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 9c1a28db592a..045211c44b90 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -716,6 +716,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration( break; case ELF::EM_HEXAGON: ECase(SHT_HEX_ORDERED); + ECase(SHT_HEXAGON_ATTRIBUTES); break; case ELF::EM_X86_64: ECase(SHT_X86_64_UNWIND); diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index b9c13c43e9a7..da2a4b4cdec5 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -188,6 +188,8 @@ add_llvm_component_library(LLVMSupport GlobPattern.cpp GraphWriter.cpp Hashing.cpp + HexagonAttributeParser.cpp + HexagonAttributes.cpp InitLLVM.cpp InstructionCost.cpp IntEqClasses.cpp diff --git a/llvm/lib/Support/HexagonAttributeParser.cpp b/llvm/lib/Support/HexagonAttributeParser.cpp new file mode 100644 index 000000000000..2143162d11c7 --- /dev/null +++ b/llvm/lib/Support/HexagonAttributeParser.cpp @@ -0,0 +1,55 @@ +//===-- HexagonAttributeParser.cpp - Hexagon Attribute Parser -------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/HexagonAttributeParser.h" + +using namespace llvm; + +const HexagonAttributeParser::DisplayHandler + HexagonAttributeParser::DisplayRoutines[] = { + { + HexagonAttrs::ARCH, + &ELFAttributeParser::integerAttribute, + }, + { + HexagonAttrs::HVXARCH, + &ELFAttributeParser::integerAttribute, + }, + { + HexagonAttrs::HVXIEEEFP, + &ELFAttributeParser::integerAttribute, + }, + { + HexagonAttrs::HVXQFLOAT, + &ELFAttributeParser::integerAttribute, + }, + { + HexagonAttrs::ZREG, + &ELFAttributeParser::integerAttribute, + }, + { + HexagonAttrs::AUDIO, + &ELFAttributeParser::integerAttribute, + }, + { + HexagonAttrs::CABAC, + &ELFAttributeParser::integerAttribute, + }}; + +Error HexagonAttributeParser::handler(uint64_t Tag, bool &Handled) { + Handled = false; + for (const auto &R : DisplayRoutines) { + if (uint64_t(R.Attribute) == Tag) { + if (Error E = (this->*R.Routine)(Tag)) + return E; + Handled = true; + break; + } + } + return Error::success(); +} diff --git a/llvm/lib/Support/HexagonAttributes.cpp b/llvm/lib/Support/HexagonAttributes.cpp new file mode 100644 index 000000000000..165215c8fb67 --- /dev/null +++ b/llvm/lib/Support/HexagonAttributes.cpp @@ -0,0 +1,27 @@ +//===-- HexagonAttributes.cpp - Qualcomm Hexagon Attributes ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/HexagonAttributes.h" + +using namespace llvm; +using namespace llvm::HexagonAttrs; + +static constexpr TagNameItem TagData[] = { + {ARCH, "Tag_arch"}, + {HVXARCH, "Tag_hvx_arch"}, + {HVXIEEEFP, "Tag_hvx_ieeefp"}, + {HVXQFLOAT, "Tag_hvx_qfloat"}, + {ZREG, "Tag_zreg"}, + {AUDIO, "Tag_audio"}, + {CABAC, "Tag_cabac"}, +}; + +constexpr TagNameMap HexagonAttributeTags{TagData}; +const TagNameMap &llvm::HexagonAttrs::getHexagonAttributeTags() { + return HexagonAttributeTags; +} diff --git a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp index fd7d25fa16d1..864591d4eb95 100644 --- a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp +++ b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp @@ -43,6 +43,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include "llvm/Support/HexagonAttributes.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/SourceMgr.h" @@ -79,7 +80,7 @@ static cl::opt<bool> ErrorNoncontigiousRegister( "merror-noncontigious-register", cl::desc("Error for register names that aren't contigious"), cl::init(false)); - +static cl::opt<bool> AddBuildAttributes("hexagon-add-build-attributes"); namespace { struct HexagonOperand; @@ -120,6 +121,9 @@ class HexagonAsmParser : public MCTargetAsmParser { SMLoc &EndLoc) override; bool ParseDirectiveSubsection(SMLoc L); bool ParseDirectiveComm(bool IsLocal, SMLoc L); + + bool parseDirectiveAttribute(SMLoc L); + bool RegisterMatchesArch(unsigned MatchNum) const; bool matchBundleOptions(); @@ -164,6 +168,9 @@ public: Parser.addAliasForDirective(".word", ".4byte"); MCAsmParserExtension::Initialize(_Parser); + + if (AddBuildAttributes) + getTargetStreamer().emitTargetAttributes(*STI); } bool splitIdentifier(OperandVector &Operands); @@ -652,6 +659,56 @@ bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return finishBundle(IDLoc, Out); return false; } +/// parseDirectiveAttribute +/// ::= .attribute int, int +/// ::= .attribute Tag_name, int +bool HexagonAsmParser::parseDirectiveAttribute(SMLoc L) { + MCAsmParser &Parser = getParser(); + int64_t Tag; + SMLoc TagLoc = Parser.getTok().getLoc(); + if (Parser.getTok().is(AsmToken::Identifier)) { + StringRef Name = Parser.getTok().getIdentifier(); + std::optional<unsigned> Ret = ELFAttrs::attrTypeFromString( + Name, HexagonAttrs::getHexagonAttributeTags()); + if (!Ret) + return Error(TagLoc, "attribute name not recognized: " + Name); + Tag = *Ret; + Parser.Lex(); + } else { + const MCExpr *AttrExpr; + + TagLoc = Parser.getTok().getLoc(); + if (Parser.parseExpression(AttrExpr)) + return true; + + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); + if (check(!CE, TagLoc, "expected numeric constant")) + return true; + + Tag = CE->getValue(); + } + + if (Parser.parseComma()) + return true; + + // We currently only have integer values. + int64_t IntegerValue = 0; + SMLoc ValueExprLoc = Parser.getTok().getLoc(); + const MCExpr *ValueExpr; + if (Parser.parseExpression(ValueExpr)) + return true; + + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); + if (!CE) + return Error(ValueExprLoc, "expected numeric constant"); + IntegerValue = CE->getValue(); + + if (Parser.parseEOL()) + return true; + + getTargetStreamer().emitAttribute(Tag, IntegerValue); + return false; +} /// ParseDirective parses the Hexagon specific directives bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) { @@ -664,6 +721,8 @@ bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) { return ParseDirectiveComm(false, DirectiveID.getLoc()); if (IDVal.lower() == ".subsection") return ParseDirectiveSubsection(DirectiveID.getLoc()); + if (IDVal == ".attribute") + return parseDirectiveAttribute(DirectiveID.getLoc()); return true; } diff --git a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp index 4ee67cb05d49..d2f64ac9e90b 100644 --- a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -17,6 +17,7 @@ #include "HexagonInstrInfo.h" #include "HexagonRegisterInfo.h" #include "HexagonSubtarget.h" +#include "HexagonTargetStreamer.h" #include "MCTargetDesc/HexagonInstPrinter.h" #include "MCTargetDesc/HexagonMCExpr.h" #include "MCTargetDesc/HexagonMCInstrInfo.h" @@ -46,6 +47,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetMachine.h" #include <algorithm> #include <cassert> #include <cstdint> @@ -775,6 +777,24 @@ void HexagonAsmPrinter::emitInstruction(const MachineInstr *MI) { OutStreamer->emitInstruction(MCB, getSubtargetInfo()); } +void HexagonAsmPrinter::emitStartOfAsmFile(Module &M) { + if (TM.getTargetTriple().isOSBinFormatELF()) + emitAttributes(); +} + +void HexagonAsmPrinter::emitEndOfAsmFile(Module &M) { + HexagonTargetStreamer &HTS = + static_cast<HexagonTargetStreamer &>(*OutStreamer->getTargetStreamer()); + if (TM.getTargetTriple().isOSBinFormatELF()) + HTS.finishAttributeSection(); +} + +void HexagonAsmPrinter::emitAttributes() { + HexagonTargetStreamer &HTS = + static_cast<HexagonTargetStreamer &>(*OutStreamer->getTargetStreamer()); + HTS.emitTargetAttributes(*TM.getMCSubtargetInfo()); +} + void HexagonAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) { static const int8_t NoopsInSledCount = 4; // We want to emit the following pattern: diff --git a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h index 5cb1edf54d1a..b555c8859650 100644 --- a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h +++ b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h @@ -29,6 +29,8 @@ class TargetMachine; class HexagonAsmPrinter : public AsmPrinter { const HexagonSubtarget *Subtarget = nullptr; + void emitAttributes(); + public: explicit HexagonAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) @@ -68,6 +70,8 @@ class TargetMachine; const char *ExtraCode, raw_ostream &OS) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override; + void emitStartOfAsmFile(Module &M) override; + void emitEndOfAsmFile(Module &M) override; }; } // end namespace llvm diff --git a/llvm/lib/Target/Hexagon/HexagonTargetStreamer.h b/llvm/lib/Target/Hexagon/HexagonTargetStreamer.h index ff8436310662..a2f93d476bfe 100644 --- a/llvm/lib/Target/Hexagon/HexagonTargetStreamer.h +++ b/llvm/lib/Target/Hexagon/HexagonTargetStreamer.h @@ -24,6 +24,15 @@ public: virtual void emitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlign, unsigned AccessGranularity){}; + void finish() override {} + + virtual void finishAttributeSection() {} + + virtual void emitAttribute(unsigned Attribute, unsigned Value) {} + + void emitTargetAttributes(const MCSubtargetInfo &STI); + + virtual void reset() {} }; } diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp index d1678fa0241c..22c82bf5ac1b 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp @@ -12,6 +12,8 @@ //===----------------------------------------------------------------------===// #include "MCTargetDesc/HexagonMCELFStreamer.h" +#include "HexagonTargetStreamer.h" +#include "MCTargetDesc/HexagonMCChecker.h" #include "MCTargetDesc/HexagonMCInstrInfo.h" #include "MCTargetDesc/HexagonMCShuffler.h" #include "llvm/ADT/StringRef.h" @@ -27,11 +29,13 @@ #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolELF.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/HexagonAttributes.h" #include "llvm/Support/MathExtras.h" #include <cassert> #include <cstdint> @@ -147,6 +151,63 @@ void HexagonMCELFStreamer::HexagonMCEmitLocalCommonSymbol(MCSymbol *Symbol, HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment, AccessSize); } +static unsigned featureToArchVersion(unsigned Feature) { + switch (Feature) { + case Hexagon::ArchV5: + return 5; + case Hexagon::ArchV55: + return 55; + case Hexagon::ArchV60: + case Hexagon::ExtensionHVXV60: + return 60; + case Hexagon::ArchV62: + case Hexagon::ExtensionHVXV62: + return 62; + case Hexagon::ArchV65: + case Hexagon::ExtensionHVXV65: + return 65; + case Hexagon::ArchV66: + case Hexagon::ExtensionHVXV66: + return 66; + case Hexagon::ArchV67: + case Hexagon::ExtensionHVXV67: + return 67; + case Hexagon::ArchV68: + case Hexagon::ExtensionHVXV68: + return 68; + case Hexagon::ArchV69: + case Hexagon::ExtensionHVXV69: + return 69; + case Hexagon::ArchV71: + case Hexagon::ExtensionHVXV71: + return 71; + case Hexagon::ArchV73: + case Hexagon::ExtensionHVXV73: + return 73; + } + llvm_unreachable("Expected valid arch feature"); + return 0; +} + +void HexagonTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) { + auto Features = STI.getFeatureBits(); + unsigned Arch = featureToArchVersion(Hexagon_MC::getArchVersion(Features)); + std::optional<unsigned> HVXArch = Hexagon_MC::getHVXVersion(Features); + emitAttribute(HexagonAttrs::ARCH, Arch); + if (HVXArch) + emitAttribute(HexagonAttrs::HVXARCH, featureToArchVersion(*HVXArch)); + if (Features.test(Hexagon::ExtensionHVXIEEEFP)) + emitAttribute(HexagonAttrs::HVXIEEEFP, 1); + if (Features.test(Hexagon::ExtensionHVXQFloat)) + emitAttribute(HexagonAttrs::HVXQFLOAT, 1); + if (Features.test(Hexagon::ExtensionZReg)) + emitAttribute(HexagonAttrs::ZREG, 1); + if (Features.test(Hexagon::ExtensionAudio)) + emitAttribute(HexagonAttrs::AUDIO, 1); + if (Features.test(Hexagon::FeatureCabac)) + emitAttribute(HexagonAttrs::CABAC, 1); +} + namespace llvm { MCStreamer *createHexagonELFStreamer(Triple const &TT, MCContext &Context, std::unique_ptr<MCAsmBackend> MAB, diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index 0740ac58a338..dc8328a6705d 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -35,6 +35,7 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/HexagonAttributes.h" #include "llvm/Support/raw_ostream.h" #include <cassert> #include <cstdint> @@ -224,12 +225,13 @@ bool isSlot0Only(unsigned units) { namespace { class HexagonTargetAsmStreamer : public HexagonTargetStreamer { + formatted_raw_ostream &OS; + bool IsVerboseAsm; + public: - HexagonTargetAsmStreamer(MCStreamer &S, - formatted_raw_ostream &OS, - bool isVerboseAsm, - MCInstPrinter &IP) - : HexagonTargetStreamer(S) {} + HexagonTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS, + bool IsVerboseAsm, MCInstPrinter &IP) + : HexagonTargetStreamer(S), OS(OS), IsVerboseAsm(IsVerboseAsm) {} void prettyPrintAsm(MCInstPrinter &InstPrinter, uint64_t Address, const MCInst &Inst, const MCSubtargetInfo &STI, @@ -266,6 +268,21 @@ public: else OS << "\t}" << PacketBundle.second; } + + void finish() override { finishAttributeSection(); } + + void finishAttributeSection() override {} + + void emitAttribute(unsigned Attribute, unsigned Value) override { + OS << "\t.attribute\t" << Attribute << ", " << Twine(Value); + if (IsVerboseAsm) { + StringRef Name = ELFAttrs::attrTypeAsString( + Attribute, HexagonAttrs::getHexagonAttributeTags()); + if (!Name.empty()) + OS << "\t// " << Name; + } + OS << "\n"; + } }; class HexagonTargetELFStreamer : public HexagonTargetStreamer { @@ -279,7 +296,6 @@ public: MCA.setELFHeaderEFlags(Hexagon_MC::GetELFFlags(STI)); } - void emitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, unsigned AccessSize) override { @@ -297,6 +313,27 @@ public: HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol( Symbol, Size, Align(ByteAlignment), AccessSize); } + + void finish() override { finishAttributeSection(); } + + void reset() override { AttributeSection = nullptr; } + +private: + MCSection *AttributeSection = nullptr; + + void finishAttributeSection() override { + MCELFStreamer &S = getStreamer(); + if (S.Contents.empty()) + return; + + S.emitAttributesSection("hexagon", ".hexagon.attributes", + ELF::SHT_HEXAGON_ATTRIBUTES, AttributeSection); + } + + void emitAttribute(uint32_t Attribute, uint32_t Value) override { + getStreamer().setAttributeItem(Attribute, Value, + /*OverwriteExisting=*/true); + } }; } // end anonymous namespace @@ -591,6 +628,29 @@ void Hexagon_MC::addArchSubtarget(MCSubtargetInfo const *STI, StringRef FS) { } } +std::optional<unsigned> +Hexagon_MC::getHVXVersion(const FeatureBitset &Features) { + for (auto Arch : {Hexagon::ExtensionHVXV73, Hexagon::ExtensionHVXV71, + Hexagon::ExtensionHVXV69, Hexagon::ExtensionHVXV68, + Hexagon::ExtensionHVXV67, Hexagon::ExtensionHVXV66, + Hexagon::ExtensionHVXV65, Hexagon::ExtensionHVXV62, + Hexagon::ExtensionHVXV60}) + if (Features.test(Arch)) + return Arch; + return {}; +} + +unsigned Hexagon_MC::getArchVersion(const FeatureBitset &Features) { + for (auto Arch : + {Hexagon::ArchV73, Hexagon::ArchV71, Hexagon::ArchV69, Hexagon::ArchV68, + Hexagon::ArchV67, Hexagon::ArchV66, Hexagon::ArchV65, Hexagon::ArchV62, + Hexagon::ArchV60, Hexagon::ArchV55, Hexagon::ArchV5}) + if (Features.test(Arch)) + return Arch; + llvm_unreachable("Expected arch v5-v73"); + return 0; +} + unsigned Hexagon_MC::GetELFFlags(const MCSubtargetInfo &STI) { return StringSwitch<unsigned>(STI.getCPU()) .Case("generic", llvm::ELF::EF_HEXAGON_MACH_V5) diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h index ffb81bca208d..6110c7a93982 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h @@ -81,7 +81,11 @@ namespace Hexagon_MC { unsigned GetELFFlags(const MCSubtargetInfo &STI); llvm::ArrayRef<MCPhysReg> GetVectRegRev(); -} + + std::optional<unsigned> getHVXVersion(const FeatureBitset &Features); + + unsigned getArchVersion(const FeatureBitset &Features); + } // namespace Hexagon_MC MCCodeEmitter *createHexagonMCCodeEmitter(const MCInstrInfo &MCII, MCContext &MCT); diff --git a/llvm/test/CodeGen/Hexagon/build-attributes.ll b/llvm/test/CodeGen/Hexagon/build-attributes.ll new file mode 100644 index 000000000000..48ee31a4d19b --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/build-attributes.ll @@ -0,0 +1,16 @@ +;; Generate build attributes from llc. + +; RUN: llc -mtriple=hexagon-unknown-elf \ +; RUN: -mattr=+hvxv73,+cabac,+v71,+hvx-ieee-fp,+hvx-length128b %s -o - | FileCheck %s + +; CHECK: .attribute 4, 71 // Tag_arch +; CHECK-NEXT: .attribute 5, 73 // Tag_hvx_arch +; CHECK-NEXT: .attribute 6, 1 // Tag_hvx_ieeefp +; CHECK-NEXT: .attribute 7, 1 // Tag_hvx_qfloat +; CHECK-NEXT: .attribute 8, 1 // Tag_zreg +; CHECK-NEXT: .attribute 10, 1 // Tag_cabac + +define i32 @addi(i32 %a) { + %1 = add i32 %a, 1 + ret i32 %1 +} \ No newline at end of file diff --git a/llvm/test/MC/Hexagon/directive-attribute-err.s b/llvm/test/MC/Hexagon/directive-attribute-err.s new file mode 100644 index 000000000000..52b145b1ff28 --- /dev/null +++ b/llvm/test/MC/Hexagon/directive-attribute-err.s @@ -0,0 +1,24 @@ +/// attribute parsing error cases. + +// RUN: not llvm-mc -triple=hexagon -filetype=asm %s 2>&1 \ +// RUN: | FileCheck %s + + .attribute Tag_unknown_name, 0 +// CHECK: [[#@LINE-1]]:14: error: attribute name not recognized: Tag_unknown_name +// CHECK-NEXT: .attribute Tag_unknown_name + + .attribute [non_constant_expression], 0 +// CHECK: [[#@LINE-1]]:14: error: expected numeric constant +// CHECK-NEXT: .attribute [non_constant_expression], 0 + + .attribute 42, "forty two" +// CHECK: [[#@LINE-1]]:18: error: expected numeric constant +// CHECK-NEXT: .attribute 42, "forty two" + + .attribute Tag_arch, "v75" +// CHECK: [[#@LINE-1]]:24: error: expected numeric constant +// CHECK-NEXT: .attribute Tag_arch, "v75" + + .attribute 0 +// CHECK: :[[#@LINE-1]]:15: error: expected comma +// CHECK-NEXT: .attribute 0 diff --git a/llvm/test/MC/Hexagon/directive-attribute.s b/llvm/test/MC/Hexagon/directive-attribute.s new file mode 100644 index 000000000000..d7c893061e18 --- /dev/null +++ b/llvm/test/MC/Hexagon/directive-attribute.s @@ -0,0 +1,41 @@ +/// Check .attribute parsing. + +// RUN: llvm-mc -triple=hexagon -filetype=obj %s | llvm-readelf -A - | \ +// RUN: FileCheck %s --match-full-lines --implicit-check-not={{.}} + +.attribute 4, 71 // Tag_arch +.attribute Tag_cabac, 1 +.attribute Tag_hvx_arch, 68 +.attribute 7, 1 // Tag_hvx_qfloat + +// CHECK: BuildAttributes { +// CHECK-NEXT: FormatVersion: 0x41 +// CHECK-NEXT: Section 1 { +// CHECK-NEXT: SectionLength: 25 +// CHECK-NEXT: Vendor: hexagon +// CHECK-NEXT: Tag: Tag_File (0x1) +// CHECK-NEXT: Size: 13 +// CHECK-NEXT: FileAttributes { +// CHECK-NEXT: Attribute { +// CHECK-NEXT: Tag: 4 +// CHECK-NEXT: TagName: arch +// CHECK-NEXT: Value: 71 +// CHECK-NEXT: } +// CHECK-NEXT: Attribute { +// CHECK-NEXT: Tag: 10 +// CHECK-NEXT: TagName: cabac +// CHECK-NEXT: Value: 1 +// CHECK-NEXT: } +// CHECK-NEXT: Attribute { +// CHECK-NEXT: Tag: 5 +// CHECK-NEXT: TagName: hvx_arch +// CHECK-NEXT: Value: 68 +// CHECK-NEXT: } +// CHECK-NEXT: Attribute { +// CHECK-NEXT: Tag: 7 +// CHECK-NEXT: TagName: hvx_qfloat +// CHECK-NEXT: Value: 1 +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } diff --git a/llvm/test/MC/Hexagon/hexagon_attributes.s b/llvm/test/MC/Hexagon/hexagon_attributes.s new file mode 100644 index 000000000000..e90536030d97 --- /dev/null +++ b/llvm/test/MC/Hexagon/hexagon_attributes.s @@ -0,0 +1,94 @@ +/// Check that file attributes are recorded in a .hexagon.attributes section. + +q0&=vcmp.gt(v0.bf,v0.bf) // hvxv73, hvx-qfloat +r3:2=cround(r1:0,#0x0) // v67, audio +v3:0.w=vrmpyz(v0.b,r0.b) // hvxv73, zreg +v1:0.sf=vadd(v0.bf,v0.bf) // hvxv73, hvx-ieee-fp + +// RUN: llvm-mc --mattr=+v67,+hvxv73,+hvx-qfloat,+hvx-ieee-fp,+zreg,+audio %s \ +// RUN: -triple=hexagon -filetype=obj --hexagon-add-build-attributes -o %t.o + +// RUN: llvm-readelf -A %t.o | \ +// RUN: FileCheck %s --match-full-lines --implicit-check-not={{.}} --check-prefix=READELF + +/// llvm-objudmp should be able to determine subtarget features +/// without manually passing in features when an attribute section is present. +// RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=OBJDUMP + +// RUN: llvm-mc --mattr=+v67,+hvxv73,+hvx-qfloat,+hvx-ieee-fp,+zreg,+audio %s \ +// RUN: -triple=hexagon -filetype=asm --hexagon-add-build-attributes | \ +// RUN: FileCheck %s --match-full-lines --implicit-check-not={{.}} --check-prefix=ASM + +// READELF: BuildAttributes { +// READELF-NEXT: FormatVersion: 0x41 +// READELF-NEXT: Section 1 { +// READELF-NEXT: SectionLength: 31 +// READELF-NEXT: Vendor: hexagon +// READELF-NEXT: Tag: Tag_File (0x1) +// READELF-NEXT: Size: 19 +// READELF-NEXT: FileAttributes { +// READELF-NEXT: Attribute { +// READELF-NEXT: Tag: 4 +// READELF-NEXT: TagName: arch +// READELF-NEXT: Value: 67 +// READELF-NEXT: } +// READELF-NEXT: Attribute { +// READELF-NEXT: Tag: 5 +// READELF-NEXT: TagName: hvx_arch +// READELF-NEXT: Value: 73 +// READELF-NEXT: } +// READELF-NEXT: Attribute { +// READELF-NEXT: Tag: 6 +// READELF-NEXT: TagName: hvx_ieeefp +// READELF-NEXT: Value: 1 +// READELF-NEXT: } +// READELF-NEXT: Attribute { +// READELF-NEXT: Tag: 7 +// READELF-NEXT: TagName: hvx_qfloat +// READELF-NEXT: Value: 1 +// READELF-NEXT: } +// READELF-NEXT: Attribute { +// READELF-NEXT: Tag: 8 +// READELF-NEXT: TagName: zreg +// READELF-NEXT: Value: 1 +// READELF-NEXT: } +// READELF-NEXT: Attribute { +// READELF-NEXT: Tag: 9 +// READELF-NEXT: TagName: audio +// READELF-NEXT: Value: 1 +// READELF-NEXT: } +// READELF-NEXT: Attribute { +// READELF-NEXT: Tag: 10 +// READELF-NEXT: TagName: cabac +// READELF-NEXT: Value: 1 +// READELF-NEXT: } +// READELF-NEXT: } +// READELF-NEXT: } +// READELF-NEXT: } + +// OBJDUMP: 1c80e0d0 { q0 &= vcmp.gt(v0.bf,v0.bf) } +// OBJDUMP-NEXT: 8ce0c042 { r3:2 = cround(r1:0,#0x0) } +// OBJDUMP-NEXT: 19e8c000 { v3:0.w = vrmpyz(v0.b,r0.b) } +// OBJDUMP-NEXT: 1d40e0c0 { v1:0.sf = vadd(v0.bf,v0.bf) } + +// ASM: .attribute 4, 67 // Tag_arch +// ASM-NEXT: .attribute 5, 73 // Tag_hvx_arch +// ASM-NEXT: .attribute 6, 1 // Tag_hvx_ieeefp +// ASM-NEXT: .attribute 7, 1 // Tag_hvx_qfloat +// ASM-NEXT: .attribute 8, 1 // Tag_zreg +// ASM-NEXT: .attribute 9, 1 // Tag_audio +// ASM-NEXT: .attribute 10, 1 // Tag_cabac +// ASM-NEXT: .text +// ASM-EMPTY: +// ASM-NEXT: { +// ASM-NEXT: q0 &= vcmp.gt(v0.bf,v0.bf) +// ASM-NEXT: } +// ASM-NEXT: { +// ASM-NEXT: r3:2 = cround(r1:0,#0) +// ASM-NEXT: } +// ASM-NEXT: { +// ASM-NEXT: v3:0.w = vrmpyz(v0.b,r0.b) +// ASM-NEXT: } +// ASM-NEXT: { +// ASM-NEXT: v1:0.sf = vadd(v0.bf,v0.bf) +// ASM-NEXT: } diff --git a/llvm/test/tools/llvm-readobj/ELF/machine-specific-section-types.test b/llvm/test/tools/llvm-readobj/ELF/machine-specific-section-types.test index 8ad50c5158db..f65793c5bdc6 100644 --- a/llvm/test/tools/llvm-readobj/ELF/machine-specific-section-types.test +++ b/llvm/test/tools/llvm-readobj/ELF/machine-specific-section-types.test @@ -70,6 +70,8 @@ # HEXAGON-LLVM: Name: hexagon_ordered # HEXAGON-LLVM: Type: SHT_HEX_ORDERED +# HEXAGON-LLVM: Name: .hexagon.attributes +# HEXAGON-LLVM: Type: SHT_HEXAGON_ATTRIBUTES # HEXAGON-GNU: hexagon_ordered HEX_ORDERED @@ -141,3 +143,5 @@ FileHeader: Sections: - Name: hexagon_ordered Type: SHT_HEX_ORDERED + - Name: .hexagon.attributes + Type: SHT_HEXAGON_ATTRIBUTES diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index e78732353cc8..d1c05f437042 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -49,6 +49,7 @@ #include "llvm/Support/Format.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/HexagonAttributeParser.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/MSP430AttributeParser.h" #include "llvm/Support/MSP430Attributes.h" @@ -2824,6 +2825,11 @@ template <typename ELFT> void ELFDumper<ELFT>::printLoadName() { template <class ELFT> void ELFDumper<ELFT>::printArchSpecificInfo() { switch (Obj.getHeader().e_machine) { + case EM_HEXAGON: + printAttributes(ELF::SHT_HEXAGON_ATTRIBUTES, + std::make_unique<HexagonAttributeParser>(&W), + llvm::endianness::little); + break; case EM_ARM: if (Obj.isLE()) printAttributes(ELF::SHT_ARM_ATTRIBUTES, -- GitLab From 73302d3ca4c59db9ddd963d132ba07eb6e2f23e7 Mon Sep 17 00:00:00 2001 From: LLVM GN Syncbot <llvmgnsyncbot@gmail.com> Date: Tue, 19 Mar 2024 21:22:55 +0000 Subject: [PATCH 150/307] [gn build] Port 31f4b329c823 --- llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn index 04ae43a13d5b..ba0f6d8c0f8c 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn @@ -90,6 +90,8 @@ static_library("Support") { "GlobPattern.cpp", "GraphWriter.cpp", "Hashing.cpp", + "HexagonAttributeParser.cpp", + "HexagonAttributes.cpp", "InitLLVM.cpp", "InstructionCost.cpp", "IntEqClasses.cpp", -- GitLab From 1678785ffc468cdd90adaa0a6806a34630b73e7b Mon Sep 17 00:00:00 2001 From: Michael Jones <michaelrj@google.com> Date: Tue, 19 Mar 2024 15:05:15 -0700 Subject: [PATCH 151/307] [libc][bazel] unglob libc macros (#85831) In a previous patch an "internal_includes" target was created to give access to the macro headers. This patch removes that in favor of individual targets for these headers, better matching the existing code. --- .../llvm-project-overlay/libc/BUILD.bazel | 69 +++++++++---------- .../libc/test/UnitTest/BUILD.bazel | 2 +- .../libc/test/src/__support/BUILD.bazel | 2 +- .../libc/test/src/math/BUILD.bazel | 14 ++-- .../test/src/math/libc_math_test_rules.bzl | 2 +- 5 files changed, 43 insertions(+), 46 deletions(-) diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 4766e168daad..1d98b986f481 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -65,11 +65,35 @@ config_setting( ################################# Include Files ################################ libc_support_library( - name = "internal_includes", - textual_hdrs = glob([ - "include/llvm-libc-macros/*.h", - "include/llvm-libc-types/*", - ]), + name = "llvm_libc_macros_math_macros", + hdrs = ["include/llvm-libc-macros/math-macros.h"], +) + +libc_support_library( + name = "llvm_libc_macros_limits_macros", + hdrs = ["include/llvm-libc-macros/limits-macros.h"], +) + +libc_support_library( + name = "llvm_libc_macros_float_macros", + hdrs = ["include/llvm-libc-macros/float-macros.h"], +) + +libc_support_library( + name = "llvm_libc_macros_stdint_macros", + hdrs = ["include/llvm-libc-macros/stdint-macros.h"], +) + +libc_support_library( + name = "llvm_libc_macros_stdfix_macros", + hdrs = ["include/llvm-libc-macros/stdfix-macros.h"], + deps = [":llvm_libc_macros_float_macros"], +) + +libc_support_library( + name = "llvm_libc_types_float128", + hdrs = ["include/llvm-libc-types/float128.h"], + deps = [":llvm_libc_macros_float_macros"], ) ############################### Support libraries ############################## @@ -691,7 +715,7 @@ libc_support_library( ":__support_macros_properties_architectures", ":__support_macros_sanitizer", ":errno", - ":internal_includes", + ":llvm_libc_macros_math_macros", ], ) @@ -764,7 +788,7 @@ libc_support_library( ":__support_fputil_normal_float", ":__support_macros_optimization", ":__support_uint128", - ":internal_includes", + ":llvm_libc_macros_math_macros", ], ) @@ -778,7 +802,7 @@ libc_support_library( ":__support_fputil_fp_bits", ":__support_fputil_rounding_mode", ":__support_macros_attributes", - ":internal_includes", + ":llvm_libc_macros_math_macros", ], ) @@ -1007,33 +1031,6 @@ libc_support_library( ], ) -libc_support_library( - name = "llvm_libc_macros_limits_macros", - hdrs = ["include/llvm-libc-macros/limits-macros.h"], -) - -libc_support_library( - name = "llvm_libc_macros_float_macros", - hdrs = ["include/llvm-libc-macros/float-macros.h"], -) - -libc_support_library( - name = "llvm_libc_macros_stdint_macros", - hdrs = ["include/llvm-libc-macros/stdint-macros.h"], -) - -libc_support_library( - name = "llvm_libc_macros_stdfix_macros", - hdrs = ["include/llvm-libc-macros/stdfix-macros.h"], - deps = [":llvm_libc_macros_float_macros"], -) - -libc_support_library( - name = "llvm_libc_types_float128", - hdrs = ["include/llvm-libc-types/float128.h"], - deps = [":llvm_libc_macros_float_macros"], -) - ############################### errno targets ################################ libc_function( @@ -1200,7 +1197,7 @@ libc_support_library( "__support_cpp_type_traits", ":__support_common", ":errno", - ":internal_includes", + ":llvm_libc_macros_math_macros", ], ) diff --git a/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel index 509a89b43f17..2a0c071f2286 100644 --- a/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel @@ -84,7 +84,7 @@ libc_support_library( "//libc:__support_fputil_fp_bits", "//libc:__support_fputil_fpbits_str", "//libc:__support_fputil_rounding_mode", - "//libc:internal_includes", + "//libc:llvm_libc_macros_math_macros", ], ) diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/__support/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/__support/BUILD.bazel index 15f662818605..4f976122967c 100644 --- a/utils/bazel/llvm-project-overlay/libc/test/src/__support/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/src/__support/BUILD.bazel @@ -89,7 +89,7 @@ libc_test( "//libc:__support_cpp_optional", "//libc:__support_macros_properties_types", "//libc:__support_uint", - "//libc:internal_includes", + "//libc:llvm_libc_macros_math_macros", ], ) diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel index 632f55a08a24..15e367f0aca2 100644 --- a/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel @@ -178,7 +178,7 @@ libc_support_library( deps = [ "//libc:__support_fputil_basic_operations", "//libc:__support_fputil_fp_bits", - "//libc:internal_includes", + "//libc:llvm_libc_macros_math_macros", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", "//libc/utils/MPFRWrapper:mpfr_wrapper", @@ -297,7 +297,7 @@ libc_support_library( "//libc:__support_cpp_limits", "//libc:__support_fputil_fp_bits", "//libc:__support_fputil_manipulation_functions", - "//libc:internal_includes", + "//libc:llvm_libc_macros_math_macros", "//libc/test/UnitTest:LibcUnitTest", ], ) @@ -324,7 +324,7 @@ libc_support_library( "//libc:__support_fputil_basic_operations", "//libc:__support_fputil_fenv_impl", "//libc:__support_fputil_fp_bits", - "//libc:internal_includes", + "//libc:llvm_libc_macros_math_macros", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", ], @@ -352,7 +352,7 @@ libc_support_library( "//libc:__support_cpp_limits", "//libc:__support_fputil_fp_bits", "//libc:__support_fputil_normal_float", - "//libc:internal_includes", + "//libc:llvm_libc_macros_math_macros", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", ], @@ -379,7 +379,7 @@ libc_support_library( deps = [ "//libc:__support_fputil_fenv_impl", "//libc:__support_fputil_fp_bits", - "//libc:internal_includes", + "//libc:llvm_libc_macros_math_macros", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", "//libc/utils/MPFRWrapper:mpfr_wrapper", @@ -416,7 +416,7 @@ libc_support_library( deps = [ "//libc:__support_fputil_fenv_impl", "//libc:__support_fputil_fp_bits", - "//libc:internal_includes", + "//libc:llvm_libc_macros_math_macros", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", "//libc/utils/MPFRWrapper:mpfr_wrapper", @@ -528,7 +528,7 @@ libc_support_library( "//libc:__support_cpp_type_traits", "//libc:__support_fputil_basic_operations", "//libc:__support_fputil_fp_bits", - "//libc:internal_includes", + "//libc:llvm_libc_macros_math_macros", "//libc/test/UnitTest:LibcUnitTest", "//libc/test/UnitTest:fp_test_helpers", ], diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/math/libc_math_test_rules.bzl b/utils/bazel/llvm-project-overlay/libc/test/src/math/libc_math_test_rules.bzl index faab18a95095..1a5868d242e8 100644 --- a/utils/bazel/llvm-project-overlay/libc/test/src/math/libc_math_test_rules.bzl +++ b/utils/bazel/llvm-project-overlay/libc/test/src/math/libc_math_test_rules.bzl @@ -34,7 +34,7 @@ def math_test(name, hdrs = [], deps = [], **kwargs): "//libc:__support_math_extras", "//libc:__support_uint128", "//libc/test/UnitTest:fp_test_helpers", - "//libc:internal_includes", + "//libc:llvm_libc_macros_math_macros", ] + deps, **kwargs ) -- GitLab From 23047dfbf1cffa4f060d5211bef43312b3bf9bc9 Mon Sep 17 00:00:00 2001 From: Noah Goldstein <goldstein.w.n@gmail.com> Date: Wed, 13 Mar 2024 16:34:39 -0500 Subject: [PATCH 152/307] [InstCombine] Add more tests for simplifying `(icmp (and/or x, Mask), y)`; NFC --- .../InstCombine/icmp-and-lowbit-mask.ll | 262 ++++++++++++++++++ 1 file changed, 262 insertions(+) diff --git a/llvm/test/Transforms/InstCombine/icmp-and-lowbit-mask.ll b/llvm/test/Transforms/InstCombine/icmp-and-lowbit-mask.ll index 410b6c29187b..c74b84e9f451 100644 --- a/llvm/test/Transforms/InstCombine/icmp-and-lowbit-mask.ll +++ b/llvm/test/Transforms/InstCombine/icmp-and-lowbit-mask.ll @@ -470,6 +470,24 @@ define i1 @src_is_notmask_x_xor_neg_x(i8 %x_in, i8 %y, i1 %cond) { ret i1 %r } +define i1 @src_is_notmask_x_xor_neg_x_inv(i8 %x_in, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_is_notmask_x_xor_neg_x_inv( +; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123 +; CHECK-NEXT: [[NEG_Y:%.*]] = add i8 [[Y:%.*]], -1 +; CHECK-NEXT: [[NOTMASK0:%.*]] = xor i8 [[NEG_Y]], [[Y]] +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i8 [[NOTMASK0]], i8 7 +; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[TMP3]] +; CHECK-NEXT: ret i1 [[R]] +; + %x = xor i8 %x_in, 123 + %neg_y = sub i8 0, %y + %nmask0 = xor i8 %y, %neg_y + %notmask = select i1 %cond, i8 %nmask0, i8 -8 + %and = and i8 %notmask, %x + %r = icmp eq i8 %and, 0 + ret i1 %r +} + define i1 @src_is_notmask_shl_fail_multiuse_invert(i8 %x_in, i8 %y, i1 %cond) { ; CHECK-LABEL: @src_is_notmask_shl_fail_multiuse_invert( ; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 122 @@ -655,3 +673,247 @@ define i1 @src_is_mask_const_sge(i8 %x_in) { %r = icmp sge i8 %and, %x ret i1 %r } + +define i1 @src_x_and_mask_slt(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_and_mask_slt( +; CHECK-NEXT: [[MASK0:%.*]] = lshr i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[MASK0]], i8 0 +; CHECK-NEXT: [[MASK_POS:%.*]] = icmp sgt i8 [[MASK]], -1 +; CHECK-NEXT: call void @llvm.assume(i1 [[MASK_POS]]) +; CHECK-NEXT: [[AND:%.*]] = and i8 [[MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[AND]], [[X]] +; CHECK-NEXT: ret i1 [[R]] +; + %mask0 = lshr i8 -1, %y + %mask = select i1 %cond, i8 %mask0, i8 0 + %mask_pos = icmp sge i8 %mask, 0 + call void @llvm.assume(i1 %mask_pos) + %and = and i8 %x, %mask + %r = icmp slt i8 %and, %x + ret i1 %r +} + +define i1 @src_x_and_mask_sge(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_and_mask_sge( +; CHECK-NEXT: [[MASK0:%.*]] = lshr i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[MASK0]], i8 0 +; CHECK-NEXT: [[MASK_POS:%.*]] = icmp sgt i8 [[MASK]], -1 +; CHECK-NEXT: call void @llvm.assume(i1 [[MASK_POS]]) +; CHECK-NEXT: [[AND:%.*]] = and i8 [[MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[AND]], [[X]] +; CHECK-NEXT: ret i1 [[R]] +; + %mask0 = lshr i8 -1, %y + %mask = select i1 %cond, i8 %mask0, i8 0 + %mask_pos = icmp sge i8 %mask, 0 + call void @llvm.assume(i1 %mask_pos) + %and = and i8 %x, %mask + %r = icmp sge i8 %and, %x + ret i1 %r +} + +define i1 @src_x_and_mask_slt_fail_maybe_neg(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_and_mask_slt_fail_maybe_neg( +; CHECK-NEXT: [[MASK0:%.*]] = lshr i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[MASK0]], i8 0 +; CHECK-NEXT: [[AND:%.*]] = and i8 [[MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[AND]], [[X]] +; CHECK-NEXT: ret i1 [[R]] +; + %mask0 = lshr i8 -1, %y + %mask = select i1 %cond, i8 %mask0, i8 0 + %and = and i8 %x, %mask + %r = icmp slt i8 %and, %x + ret i1 %r +} + +define i1 @src_x_and_mask_sge_fail_maybe_neg(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_and_mask_sge_fail_maybe_neg( +; CHECK-NEXT: [[MASK0:%.*]] = lshr i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[MASK0]], i8 0 +; CHECK-NEXT: [[AND:%.*]] = and i8 [[MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[AND]], [[X]] +; CHECK-NEXT: ret i1 [[R]] +; + %mask0 = lshr i8 -1, %y + %mask = select i1 %cond, i8 %mask0, i8 0 + %and = and i8 %x, %mask + %r = icmp sge i8 %and, %x + ret i1 %r +} + +define i1 @src_x_and_nmask_eq(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_and_nmask_eq( +; CHECK-NEXT: [[NOT_MASK0:%.*]] = shl nsw i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[NOT_MASK:%.*]] = select i1 [[COND:%.*]], i8 [[NOT_MASK0]], i8 0 +; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[NOT_MASK]], [[AND]] +; CHECK-NEXT: ret i1 [[R]] +; + %not_mask0 = shl i8 -1, %y + %not_mask = select i1 %cond, i8 %not_mask0, i8 0 + %and = and i8 %x, %not_mask + %r = icmp eq i8 %not_mask, %and + ret i1 %r +} + +define i1 @src_x_and_nmask_ne(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_and_nmask_ne( +; CHECK-NEXT: [[NOT_MASK0:%.*]] = shl nsw i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[NOT_MASK:%.*]] = select i1 [[COND:%.*]], i8 [[NOT_MASK0]], i8 0 +; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: ret i1 [[R]] +; + %not_mask0 = shl i8 -1, %y + %not_mask = select i1 %cond, i8 %not_mask0, i8 0 + %and = and i8 %x, %not_mask + %r = icmp ne i8 %and, %not_mask + ret i1 %r +} + +define i1 @src_x_and_nmask_ult(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_and_nmask_ult( +; CHECK-NEXT: [[NOT_MASK0:%.*]] = shl nsw i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[NOT_MASK:%.*]] = select i1 [[COND:%.*]], i8 [[NOT_MASK0]], i8 0 +; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: ret i1 [[R]] +; + %not_mask0 = shl i8 -1, %y + %not_mask = select i1 %cond, i8 %not_mask0, i8 0 + %and = and i8 %x, %not_mask + %r = icmp ult i8 %and, %not_mask + ret i1 %r +} + +define i1 @src_x_and_nmask_uge(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_and_nmask_uge( +; CHECK-NEXT: [[NOT_MASK0:%.*]] = shl nsw i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[NOT_MASK:%.*]] = select i1 [[COND:%.*]], i8 [[NOT_MASK0]], i8 0 +; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: ret i1 [[R]] +; + %not_mask0 = shl i8 -1, %y + %not_mask = select i1 %cond, i8 %not_mask0, i8 0 + %and = and i8 %x, %not_mask + %r = icmp uge i8 %and, %not_mask + ret i1 %r +} + +define i1 @src_x_and_nmask_slt(i8 %x, i8 %y) { +; CHECK-LABEL: @src_x_and_nmask_slt( +; CHECK-NEXT: [[NOT_MASK:%.*]] = shl nsw i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: ret i1 [[R]] +; + %not_mask = shl i8 -1, %y + %and = and i8 %x, %not_mask + %r = icmp slt i8 %and, %not_mask + ret i1 %r +} + +define i1 @src_x_and_nmask_sge(i8 %x, i8 %y) { +; CHECK-LABEL: @src_x_and_nmask_sge( +; CHECK-NEXT: [[NOT_MASK:%.*]] = shl nsw i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: ret i1 [[R]] +; + %not_mask = shl i8 -1, %y + %and = and i8 %x, %not_mask + %r = icmp sge i8 %and, %not_mask + ret i1 %r +} + +define i1 @src_x_and_nmask_slt_fail_maybe_z(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_and_nmask_slt_fail_maybe_z( +; CHECK-NEXT: [[NOT_MASK0:%.*]] = shl nsw i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[NOT_MASK:%.*]] = select i1 [[COND:%.*]], i8 [[NOT_MASK0]], i8 0 +; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: ret i1 [[R]] +; + %not_mask0 = shl i8 -1, %y + %not_mask = select i1 %cond, i8 %not_mask0, i8 0 + %and = and i8 %x, %not_mask + %r = icmp slt i8 %and, %not_mask + ret i1 %r +} + +define i1 @src_x_and_nmask_sge_fail_maybe_z(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_and_nmask_sge_fail_maybe_z( +; CHECK-NEXT: [[NOT_MASK0:%.*]] = shl nsw i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[NOT_MASK:%.*]] = select i1 [[COND:%.*]], i8 [[NOT_MASK0]], i8 0 +; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: ret i1 [[R]] +; + %not_mask0 = shl i8 -1, %y + %not_mask = select i1 %cond, i8 %not_mask0, i8 0 + %and = and i8 %x, %not_mask + %r = icmp sge i8 %and, %not_mask + ret i1 %r +} + +define i1 @src_x_or_mask_eq(i8 %x, i8 %y, i8 %z, i1 %c2, i1 %cond) { +; CHECK-LABEL: @src_x_or_mask_eq( +; CHECK-NEXT: [[MASK0:%.*]] = lshr i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[MASK0]], i8 0 +; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X:%.*]], -124 +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C2:%.*]], i8 [[TMP1]], i8 -46 +; CHECK-NEXT: [[TMP3:%.*]] = call i8 @llvm.umax.i8(i8 [[Z:%.*]], i8 [[TMP2]]) +; CHECK-NEXT: [[NX_CCC:%.*]] = sub i8 11, [[TMP3]] +; CHECK-NEXT: [[OR:%.*]] = or i8 [[NX_CCC]], [[MASK]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[OR]], -1 +; CHECK-NEXT: ret i1 [[R]] +; + %mask0 = lshr i8 -1, %y + %mask = select i1 %cond, i8 %mask0, i8 0 + %nx = xor i8 %x, 123 + %nx_c = select i1 %c2, i8 %nx, i8 45 + %nz = xor i8 %z, -1 + %nx_cc = call i8 @llvm.umin.i8(i8 %nz, i8 %nx_c) + %nx_ccc = add i8 %nx_cc, 12 + %or = or i8 %nx_ccc, %mask + %r = icmp eq i8 %or, -1 + ret i1 %r +} + +define i1 @src_x_or_mask_ne(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_or_mask_ne( +; CHECK-NEXT: [[MASK0:%.*]] = lshr i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[MASK0]], i8 0 +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[OR:%.*]] = or i8 [[MASK]], [[NX]] +; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[OR]], -1 +; CHECK-NEXT: ret i1 [[R]] +; + %mask0 = lshr i8 -1, %y + %mask = select i1 %cond, i8 %mask0, i8 0 + %nx = xor i8 %x, -1 + %or = or i8 %mask, %nx + %r = icmp ne i8 %or, -1 + ret i1 %r +} + +define i1 @src_x_or_mask_ne_fail_multiuse(i8 %x, i8 %y, i1 %cond) { +; CHECK-LABEL: @src_x_or_mask_ne_fail_multiuse( +; CHECK-NEXT: [[MASK0:%.*]] = lshr i8 -1, [[Y:%.*]] +; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[MASK0]], i8 0 +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[OR:%.*]] = or i8 [[MASK]], [[NX]] +; CHECK-NEXT: call void @use.i8(i8 [[OR]]) +; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[OR]], -1 +; CHECK-NEXT: ret i1 [[R]] +; + %mask0 = lshr i8 -1, %y + %mask = select i1 %cond, i8 %mask0, i8 0 + %nx = xor i8 %x, -1 + %or = or i8 %mask, %nx + call void @use.i8(i8 %or) + %r = icmp ne i8 %or, -1 + ret i1 %r +} -- GitLab From b60cf84e0965ac12b83494f803ea0dd6dec0db77 Mon Sep 17 00:00:00 2001 From: Noah Goldstein <goldstein.w.n@gmail.com> Date: Wed, 13 Mar 2024 16:36:56 -0500 Subject: [PATCH 153/307] [InstCombine] Add more cases for simplifying `(icmp (and/or x, Mask), y)` This cleans up basically all the regressions assosiated from #84688 Proof of all new cases: https://alive2.llvm.org/ce/z/5yYWLb Closes #85445 --- .../InstCombine/InstCombineCompares.cpp | 152 +++++++++++------- .../InstCombine/icmp-and-lowbit-mask.ll | 43 ++--- 2 files changed, 115 insertions(+), 80 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 0dce0077bf15..db302d7e5268 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4177,7 +4177,9 @@ static bool isMaskOrZero(const Value *V, bool Not, const SimplifyQuery &Q, /// a check for a lossy truncation. /// Folds: /// icmp SrcPred (x & Mask), x to icmp DstPred x, Mask +/// icmp SrcPred (x & ~Mask), ~Mask to icmp DstPred x, ~Mask /// icmp eq/ne (x & ~Mask), 0 to icmp DstPred x, Mask +/// icmp eq/ne (~x | Mask), -1 to icmp DstPred x, Mask /// Where Mask is some pattern that produces all-ones in low bits: /// (-1 >> y) /// ((-1 << y) >> y) <- non-canonical, has extra uses @@ -4189,82 +4191,126 @@ static bool isMaskOrZero(const Value *V, bool Not, const SimplifyQuery &Q, static Value *foldICmpWithLowBitMaskedVal(ICmpInst::Predicate Pred, Value *Op0, Value *Op1, const SimplifyQuery &Q, InstCombiner &IC) { - Value *X, *M; - bool NeedsNot = false; - - auto CheckMask = [&](Value *V, bool Not) { - if (ICmpInst::isSigned(Pred) && !match(V, m_ImmConstant())) - return false; - return isMaskOrZero(V, Not, Q); - }; - - if (match(Op0, m_c_And(m_Specific(Op1), m_Value(M))) && - CheckMask(M, /*Not*/ false)) { - X = Op1; - } else if (match(Op1, m_Zero()) && ICmpInst::isEquality(Pred) && - match(Op0, m_OneUse(m_And(m_Value(X), m_Value(M))))) { - NeedsNot = true; - if (IC.isFreeToInvert(X, X->hasOneUse()) && CheckMask(X, /*Not*/ true)) - std::swap(X, M); - else if (!IC.isFreeToInvert(M, M->hasOneUse()) || - !CheckMask(M, /*Not*/ true)) - return nullptr; - } else { - return nullptr; - } ICmpInst::Predicate DstPred; switch (Pred) { case ICmpInst::Predicate::ICMP_EQ: - // x & (-1 >> y) == x -> x u<= (-1 >> y) + // x & Mask == x + // x & ~Mask == 0 + // ~x | Mask == -1 + // -> x u<= Mask + // x & ~Mask == ~Mask + // -> ~Mask u<= x DstPred = ICmpInst::Predicate::ICMP_ULE; break; case ICmpInst::Predicate::ICMP_NE: - // x & (-1 >> y) != x -> x u> (-1 >> y) + // x & Mask != x + // x & ~Mask != 0 + // ~x | Mask != -1 + // -> x u> Mask + // x & ~Mask != ~Mask + // -> ~Mask u> x DstPred = ICmpInst::Predicate::ICMP_UGT; break; case ICmpInst::Predicate::ICMP_ULT: - // x & (-1 >> y) u< x -> x u> (-1 >> y) - // x u> x & (-1 >> y) -> x u> (-1 >> y) + // x & Mask u< x + // -> x u> Mask + // x & ~Mask u< ~Mask + // -> ~Mask u> x DstPred = ICmpInst::Predicate::ICMP_UGT; break; case ICmpInst::Predicate::ICMP_UGE: - // x & (-1 >> y) u>= x -> x u<= (-1 >> y) - // x u<= x & (-1 >> y) -> x u<= (-1 >> y) + // x & Mask u>= x + // -> x u<= Mask + // x & ~Mask u>= ~Mask + // -> ~Mask u<= x DstPred = ICmpInst::Predicate::ICMP_ULE; break; case ICmpInst::Predicate::ICMP_SLT: - // x & (-1 >> y) s< x -> x s> (-1 >> y) - // x s> x & (-1 >> y) -> x s> (-1 >> y) - if (!match(M, m_Constant())) // Can not do this fold with non-constant. - return nullptr; - if (!match(M, m_NonNegative())) // Must not have any -1 vector elements. - return nullptr; + // x & Mask s< x [iff Mask s>= 0] + // -> x s> Mask + // x & ~Mask s< ~Mask [iff ~Mask != 0] + // -> ~Mask s> x DstPred = ICmpInst::Predicate::ICMP_SGT; break; case ICmpInst::Predicate::ICMP_SGE: - // x & (-1 >> y) s>= x -> x s<= (-1 >> y) - // x s<= x & (-1 >> y) -> x s<= (-1 >> y) - if (!match(M, m_Constant())) // Can not do this fold with non-constant. - return nullptr; - if (!match(M, m_NonNegative())) // Must not have any -1 vector elements. - return nullptr; + // x & Mask s>= x [iff Mask s>= 0] + // -> x s<= Mask + // x & ~Mask s>= ~Mask [iff ~Mask != 0] + // -> ~Mask s<= x DstPred = ICmpInst::Predicate::ICMP_SLE; break; - case ICmpInst::Predicate::ICMP_SGT: - case ICmpInst::Predicate::ICMP_SLE: - return nullptr; - case ICmpInst::Predicate::ICMP_UGT: - case ICmpInst::Predicate::ICMP_ULE: - llvm_unreachable("Instsimplify took care of commut. variant"); - break; default: - llvm_unreachable("All possible folds are handled."); + // We don't support sgt,sle + // ult/ugt are simplified to true/false respectively. + return nullptr; } - // The mask value may be a vector constant that has undefined elements. But it - // may not be safe to propagate those undefs into the new compare, so replace - // those elements by copying an existing, defined, and safe scalar constant. + Value *X, *M; + // Put search code in lambda for early positive returns. + auto IsLowBitMask = [&]() { + if (match(Op0, m_c_And(m_Specific(Op1), m_Value(M)))) { + X = Op1; + // Look for: x & Mask pred x + if (isMaskOrZero(M, /*Not=*/false, Q)) { + return !ICmpInst::isSigned(Pred) || + (match(M, m_NonNegative()) || isKnownNonNegative(M, Q)); + } + + // Look for: x & ~Mask pred ~Mask + if (isMaskOrZero(X, /*Not=*/true, Q)) { + return !ICmpInst::isSigned(Pred) || + isKnownNonZero(X, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT); + } + return false; + } + if (ICmpInst::isEquality(Pred) && match(Op1, m_AllOnes()) && + match(Op0, m_OneUse(m_Or(m_Value(X), m_Value(M))))) { + + auto Check = [&]() { + // Look for: ~x | Mask == -1 + if (isMaskOrZero(M, /*Not=*/false, Q)) { + if (Value *NotX = + IC.getFreelyInverted(X, X->hasOneUse(), &IC.Builder)) { + X = NotX; + return true; + } + } + return false; + }; + if (Check()) + return true; + std::swap(X, M); + return Check(); + } + if (ICmpInst::isEquality(Pred) && match(Op1, m_Zero()) && + match(Op0, m_OneUse(m_And(m_Value(X), m_Value(M))))) { + auto Check = [&]() { + // Look for: x & ~Mask == 0 + if (isMaskOrZero(M, /*Not=*/true, Q)) { + if (Value *NotM = + IC.getFreelyInverted(M, M->hasOneUse(), &IC.Builder)) { + M = NotM; + return true; + } + } + return false; + }; + if (Check()) + return true; + std::swap(X, M); + return Check(); + } + return false; + }; + + if (!IsLowBitMask()) + return nullptr; + + // The mask value may be a vector constant that has undefined elements. But + // it may not be safe to propagate those undefs into the new compare, so + // replace those elements by copying an existing, defined, and safe scalar + // constant. Type *OpTy = M->getType(); auto *VecC = dyn_cast<Constant>(M); auto *OpVTy = dyn_cast<FixedVectorType>(OpTy); @@ -4280,8 +4326,6 @@ static Value *foldICmpWithLowBitMaskedVal(ICmpInst::Predicate Pred, Value *Op0, M = Constant::replaceUndefsWith(VecC, SafeReplacementConstant); } - if (NeedsNot) - M = IC.Builder.CreateNot(M); return IC.Builder.CreateICmp(DstPred, X, M); } diff --git a/llvm/test/Transforms/InstCombine/icmp-and-lowbit-mask.ll b/llvm/test/Transforms/InstCombine/icmp-and-lowbit-mask.ll index c74b84e9f451..5de3e89d7027 100644 --- a/llvm/test/Transforms/InstCombine/icmp-and-lowbit-mask.ll +++ b/llvm/test/Transforms/InstCombine/icmp-and-lowbit-mask.ll @@ -680,8 +680,7 @@ define i1 @src_x_and_mask_slt(i8 %x, i8 %y, i1 %cond) { ; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[MASK0]], i8 0 ; CHECK-NEXT: [[MASK_POS:%.*]] = icmp sgt i8 [[MASK]], -1 ; CHECK-NEXT: call void @llvm.assume(i1 [[MASK_POS]]) -; CHECK-NEXT: [[AND:%.*]] = and i8 [[MASK]], [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[AND]], [[X]] +; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[MASK]], [[X:%.*]] ; CHECK-NEXT: ret i1 [[R]] ; %mask0 = lshr i8 -1, %y @@ -699,8 +698,7 @@ define i1 @src_x_and_mask_sge(i8 %x, i8 %y, i1 %cond) { ; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[MASK0]], i8 0 ; CHECK-NEXT: [[MASK_POS:%.*]] = icmp sgt i8 [[MASK]], -1 ; CHECK-NEXT: call void @llvm.assume(i1 [[MASK_POS]]) -; CHECK-NEXT: [[AND:%.*]] = and i8 [[MASK]], [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[AND]], [[X]] +; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[MASK]], [[X:%.*]] ; CHECK-NEXT: ret i1 [[R]] ; %mask0 = lshr i8 -1, %y @@ -745,9 +743,9 @@ define i1 @src_x_and_mask_sge_fail_maybe_neg(i8 %x, i8 %y, i1 %cond) { define i1 @src_x_and_nmask_eq(i8 %x, i8 %y, i1 %cond) { ; CHECK-LABEL: @src_x_and_nmask_eq( ; CHECK-NEXT: [[NOT_MASK0:%.*]] = shl nsw i8 -1, [[Y:%.*]] -; CHECK-NEXT: [[NOT_MASK:%.*]] = select i1 [[COND:%.*]], i8 [[NOT_MASK0]], i8 0 -; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[NOT_MASK]], [[AND]] +; CHECK-NEXT: [[R1:%.*]] = icmp ule i8 [[NOT_MASK0]], [[X:%.*]] +; CHECK-NEXT: [[NOT_COND:%.*]] = xor i1 [[COND:%.*]], true +; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_COND]], i1 true, i1 [[R1]] ; CHECK-NEXT: ret i1 [[R]] ; %not_mask0 = shl i8 -1, %y @@ -760,9 +758,8 @@ define i1 @src_x_and_nmask_eq(i8 %x, i8 %y, i1 %cond) { define i1 @src_x_and_nmask_ne(i8 %x, i8 %y, i1 %cond) { ; CHECK-LABEL: @src_x_and_nmask_ne( ; CHECK-NEXT: [[NOT_MASK0:%.*]] = shl nsw i8 -1, [[Y:%.*]] -; CHECK-NEXT: [[NOT_MASK:%.*]] = select i1 [[COND:%.*]], i8 [[NOT_MASK0]], i8 0 -; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: [[R1:%.*]] = icmp ugt i8 [[NOT_MASK0]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = select i1 [[COND:%.*]], i1 [[R1]], i1 false ; CHECK-NEXT: ret i1 [[R]] ; %not_mask0 = shl i8 -1, %y @@ -775,9 +772,8 @@ define i1 @src_x_and_nmask_ne(i8 %x, i8 %y, i1 %cond) { define i1 @src_x_and_nmask_ult(i8 %x, i8 %y, i1 %cond) { ; CHECK-LABEL: @src_x_and_nmask_ult( ; CHECK-NEXT: [[NOT_MASK0:%.*]] = shl nsw i8 -1, [[Y:%.*]] -; CHECK-NEXT: [[NOT_MASK:%.*]] = select i1 [[COND:%.*]], i8 [[NOT_MASK0]], i8 0 -; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: [[R1:%.*]] = icmp ugt i8 [[NOT_MASK0]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = select i1 [[COND:%.*]], i1 [[R1]], i1 false ; CHECK-NEXT: ret i1 [[R]] ; %not_mask0 = shl i8 -1, %y @@ -790,9 +786,9 @@ define i1 @src_x_and_nmask_ult(i8 %x, i8 %y, i1 %cond) { define i1 @src_x_and_nmask_uge(i8 %x, i8 %y, i1 %cond) { ; CHECK-LABEL: @src_x_and_nmask_uge( ; CHECK-NEXT: [[NOT_MASK0:%.*]] = shl nsw i8 -1, [[Y:%.*]] -; CHECK-NEXT: [[NOT_MASK:%.*]] = select i1 [[COND:%.*]], i8 [[NOT_MASK0]], i8 0 -; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: [[R1:%.*]] = icmp ule i8 [[NOT_MASK0]], [[X:%.*]] +; CHECK-NEXT: [[NOT_COND:%.*]] = xor i1 [[COND:%.*]], true +; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_COND]], i1 true, i1 [[R1]] ; CHECK-NEXT: ret i1 [[R]] ; %not_mask0 = shl i8 -1, %y @@ -805,8 +801,7 @@ define i1 @src_x_and_nmask_uge(i8 %x, i8 %y, i1 %cond) { define i1 @src_x_and_nmask_slt(i8 %x, i8 %y) { ; CHECK-LABEL: @src_x_and_nmask_slt( ; CHECK-NEXT: [[NOT_MASK:%.*]] = shl nsw i8 -1, [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[NOT_MASK]], [[X:%.*]] ; CHECK-NEXT: ret i1 [[R]] ; %not_mask = shl i8 -1, %y @@ -818,8 +813,7 @@ define i1 @src_x_and_nmask_slt(i8 %x, i8 %y) { define i1 @src_x_and_nmask_sge(i8 %x, i8 %y) { ; CHECK-LABEL: @src_x_and_nmask_sge( ; CHECK-NEXT: [[NOT_MASK:%.*]] = shl nsw i8 -1, [[Y:%.*]] -; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_MASK]], [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[AND]], [[NOT_MASK]] +; CHECK-NEXT: [[R:%.*]] = icmp sle i8 [[NOT_MASK]], [[X:%.*]] ; CHECK-NEXT: ret i1 [[R]] ; %not_mask = shl i8 -1, %y @@ -865,9 +859,8 @@ define i1 @src_x_or_mask_eq(i8 %x, i8 %y, i8 %z, i1 %c2, i1 %cond) { ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X:%.*]], -124 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C2:%.*]], i8 [[TMP1]], i8 -46 ; CHECK-NEXT: [[TMP3:%.*]] = call i8 @llvm.umax.i8(i8 [[Z:%.*]], i8 [[TMP2]]) -; CHECK-NEXT: [[NX_CCC:%.*]] = sub i8 11, [[TMP3]] -; CHECK-NEXT: [[OR:%.*]] = or i8 [[NX_CCC]], [[MASK]] -; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[OR]], -1 +; CHECK-NEXT: [[TMP4:%.*]] = add i8 [[TMP3]], -12 +; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[TMP4]], [[MASK]] ; CHECK-NEXT: ret i1 [[R]] ; %mask0 = lshr i8 -1, %y @@ -886,9 +879,7 @@ define i1 @src_x_or_mask_ne(i8 %x, i8 %y, i1 %cond) { ; CHECK-LABEL: @src_x_or_mask_ne( ; CHECK-NEXT: [[MASK0:%.*]] = lshr i8 -1, [[Y:%.*]] ; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[MASK0]], i8 0 -; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 -; CHECK-NEXT: [[OR:%.*]] = or i8 [[MASK]], [[NX]] -; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[OR]], -1 +; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[MASK]], [[X:%.*]] ; CHECK-NEXT: ret i1 [[R]] ; %mask0 = lshr i8 -1, %y -- GitLab From ebd13796639ea7015b3672ff179612ee7d897bf9 Mon Sep 17 00:00:00 2001 From: Noah Goldstein <goldstein.w.n@gmail.com> Date: Fri, 15 Mar 2024 12:44:15 -0500 Subject: [PATCH 154/307] [DAGCombiner] Add tests for simplifying `{si|ui}tofp`; NFC --- llvm/test/CodeGen/X86/int-to-fp-demanded.ll | 382 ++++++++++++++++++++ 1 file changed, 382 insertions(+) create mode 100644 llvm/test/CodeGen/X86/int-to-fp-demanded.ll diff --git a/llvm/test/CodeGen/X86/int-to-fp-demanded.ll b/llvm/test/CodeGen/X86/int-to-fp-demanded.ll new file mode 100644 index 000000000000..cdde03fb0534 --- /dev/null +++ b/llvm/test/CodeGen/X86/int-to-fp-demanded.ll @@ -0,0 +1,382 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X86 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64 + +declare void @use.i1(i1) +declare void @use.i32(i32) +define i32 @sitofp_signbit_only(i32 %i_in) nounwind { +; X86-LABEL: sitofp_signbit_only: +; X86: # %bb.0: +; X86-NEXT: subl $8, %esp +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl %eax, (%esp) +; X86-NEXT: fildl (%esp) +; X86-NEXT: fstps {{[0-9]+}}(%esp) +; X86-NEXT: movl $-2147483648, %eax # imm = 0x80000000 +; X86-NEXT: andl {{[0-9]+}}(%esp), %eax +; X86-NEXT: addl $8, %esp +; X86-NEXT: retl +; +; X64-LABEL: sitofp_signbit_only: +; X64: # %bb.0: +; X64-NEXT: cvtsi2ss %edi, %xmm0 +; X64-NEXT: movmskps %xmm0, %eax +; X64-NEXT: shll $31, %eax +; X64-NEXT: retq + %f = sitofp i32 %i_in to float + %i = bitcast float %f to i32 + %r = and i32 %i, 2147483648 + ret i32 %r +} + +define i32 @sitofp_signbit_only_okay_width(i16 %i_in) nounwind { +; X86-LABEL: sitofp_signbit_only_okay_width: +; X86: # %bb.0: +; X86-NEXT: subl $8, %esp +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-NEXT: filds {{[0-9]+}}(%esp) +; X86-NEXT: fstps {{[0-9]+}}(%esp) +; X86-NEXT: movl $-2147483648, %eax # imm = 0x80000000 +; X86-NEXT: andl {{[0-9]+}}(%esp), %eax +; X86-NEXT: addl $8, %esp +; X86-NEXT: retl +; +; X64-LABEL: sitofp_signbit_only_okay_width: +; X64: # %bb.0: +; X64-NEXT: movswl %di, %eax +; X64-NEXT: cvtsi2ss %eax, %xmm0 +; X64-NEXT: movmskps %xmm0, %eax +; X64-NEXT: shll $31, %eax +; X64-NEXT: retq + %f = sitofp i16 %i_in to float + %i = bitcast float %f to i32 + %r = and i32 %i, 2147483648 + ret i32 %r +} + +define i32 @sitofp_signbit_only_fail_bad_width1(i64 %i_in) nounwind { +; X86-LABEL: sitofp_signbit_only_fail_bad_width1: +; X86: # %bb.0: +; X86-NEXT: pushl %eax +; X86-NEXT: fildll {{[0-9]+}}(%esp) +; X86-NEXT: fstps (%esp) +; X86-NEXT: movl $-2147483648, %eax # imm = 0x80000000 +; X86-NEXT: andl (%esp), %eax +; X86-NEXT: popl %ecx +; X86-NEXT: retl +; +; X64-LABEL: sitofp_signbit_only_fail_bad_width1: +; X64: # %bb.0: +; X64-NEXT: cvtsi2ss %rdi, %xmm0 +; X64-NEXT: movmskps %xmm0, %eax +; X64-NEXT: shll $31, %eax +; X64-NEXT: retq + %f = sitofp i64 %i_in to float + %i = bitcast float %f to i32 + %r = and i32 %i, 2147483648 + ret i32 %r +} + +define <2 x i16> @sitofp_signbit_only_fail_bad_width2(i32 %i_in) nounwind { +; X86-LABEL: sitofp_signbit_only_fail_bad_width2: +; X86: # %bb.0: +; X86-NEXT: subl $8, %esp +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl %eax, (%esp) +; X86-NEXT: fildl (%esp) +; X86-NEXT: fstps {{[0-9]+}}(%esp) +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl %eax, %edx +; X86-NEXT: shrl $16, %edx +; X86-NEXT: andl $32768, %eax # imm = 0x8000 +; X86-NEXT: andl $32768, %edx # imm = 0x8000 +; X86-NEXT: # kill: def $ax killed $ax killed $eax +; X86-NEXT: # kill: def $dx killed $dx killed $edx +; X86-NEXT: addl $8, %esp +; X86-NEXT: retl +; +; X64-LABEL: sitofp_signbit_only_fail_bad_width2: +; X64: # %bb.0: +; X64-NEXT: cvtsi2ss %edi, %xmm0 +; X64-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; X64-NEXT: retq + %f = sitofp i32 %i_in to float + %i2xi16 = bitcast float %f to <2 x i16> + %r = and <2 x i16> %i2xi16, <i16 32768, i16 32768> + ret <2 x i16> %r +} + +define i32 @sitofp_many_bits_fail(i32 %i_in) nounwind { +; X86-LABEL: sitofp_many_bits_fail: +; X86: # %bb.0: +; X86-NEXT: subl $8, %esp +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl %eax, (%esp) +; X86-NEXT: fildl (%esp) +; X86-NEXT: fstps {{[0-9]+}}(%esp) +; X86-NEXT: movl $-2147483647, %eax # imm = 0x80000001 +; X86-NEXT: andl {{[0-9]+}}(%esp), %eax +; X86-NEXT: addl $8, %esp +; X86-NEXT: retl +; +; X64-LABEL: sitofp_many_bits_fail: +; X64: # %bb.0: +; X64-NEXT: cvtsi2ss %edi, %xmm0 +; X64-NEXT: movd %xmm0, %eax +; X64-NEXT: andl $-2147483647, %eax # imm = 0x80000001 +; X64-NEXT: retq + %f = sitofp i32 %i_in to float + %i = bitcast float %f to i32 + %r = and i32 %i, 2147483649 + ret i32 %r +} + +define i32 @sitofp_multiuse_fail(i32 %i_in) nounwind { +; X86-LABEL: sitofp_multiuse_fail: +; X86: # %bb.0: +; X86-NEXT: subl $12, %esp +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl %eax, {{[0-9]+}}(%esp) +; X86-NEXT: fildl {{[0-9]+}}(%esp) +; X86-NEXT: fsts {{[0-9]+}}(%esp) +; X86-NEXT: fstps (%esp) +; X86-NEXT: calll use.i32@PLT +; X86-NEXT: movl $-2147483648, %eax # imm = 0x80000000 +; X86-NEXT: andl {{[0-9]+}}(%esp), %eax +; X86-NEXT: addl $12, %esp +; X86-NEXT: retl +; +; X64-LABEL: sitofp_multiuse_fail: +; X64: # %bb.0: +; X64-NEXT: pushq %rbx +; X64-NEXT: cvtsi2ss %edi, %xmm0 +; X64-NEXT: movd %xmm0, %ebx +; X64-NEXT: movl %ebx, %edi +; X64-NEXT: callq use.i32@PLT +; X64-NEXT: andl $-2147483648, %ebx # imm = 0x80000000 +; X64-NEXT: movl %ebx, %eax +; X64-NEXT: popq %rbx +; X64-NEXT: retq + %f = sitofp i32 %i_in to float + %i = bitcast float %f to i32 + call void @use.i32(i32 %i) + %r = and i32 %i, 2147483648 + ret i32 %r +} + +define i32 @sitofp_multiuse_okay(i32 %i_in) nounwind { +; X86-LABEL: sitofp_multiuse_okay: +; X86: # %bb.0: +; X86-NEXT: subl $12, %esp +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl %eax, {{[0-9]+}}(%esp) +; X86-NEXT: fildl {{[0-9]+}}(%esp) +; X86-NEXT: fsts {{[0-9]+}}(%esp) +; X86-NEXT: fstps (%esp) +; X86-NEXT: calll use.i1@PLT +; X86-NEXT: movl $-2147483648, %eax # imm = 0x80000000 +; X86-NEXT: andl {{[0-9]+}}(%esp), %eax +; X86-NEXT: addl $12, %esp +; X86-NEXT: retl +; +; X64-LABEL: sitofp_multiuse_okay: +; X64: # %bb.0: +; X64-NEXT: pushq %rbx +; X64-NEXT: cvtsi2ss %edi, %xmm0 +; X64-NEXT: movd %xmm0, %ebx +; X64-NEXT: movl %ebx, %edi +; X64-NEXT: callq use.i1@PLT +; X64-NEXT: andl $-2147483648, %ebx # imm = 0x80000000 +; X64-NEXT: movl %ebx, %eax +; X64-NEXT: popq %rbx +; X64-NEXT: retq + %f = sitofp i32 %i_in to float + %i = bitcast float %f to i32 + %cmp = icmp slt i32 %i, 0 + call void @use.i1(i32 %i) + %r = and i32 %i, 2147483648 + ret i32 %r +} + +define i32 @uitofp_signbit_only(i32 %i_in) nounwind { +; X86-LABEL: uitofp_signbit_only: +; X86: # %bb.0: +; X86-NEXT: xorl %eax, %eax +; X86-NEXT: retl +; +; X64-LABEL: uitofp_signbit_only: +; X64: # %bb.0: +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: retq + %f = uitofp i32 %i_in to float + %i = bitcast float %f to i32 + %r = and i32 %i, 2147483648 + ret i32 %r +} + +define i32 @uitofp_signbit_only_okay_width(i16 %i_in) nounwind { +; X86-LABEL: uitofp_signbit_only_okay_width: +; X86: # %bb.0: +; X86-NEXT: xorl %eax, %eax +; X86-NEXT: retl +; +; X64-LABEL: uitofp_signbit_only_okay_width: +; X64: # %bb.0: +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: retq + %f = uitofp i16 %i_in to float + %i = bitcast float %f to i32 + %r = and i32 %i, 2147483648 + ret i32 %r +} + +define i32 @uitofp_signbit_only_okay_width1(i64 %i_in) nounwind { +; X86-LABEL: uitofp_signbit_only_okay_width1: +; X86: # %bb.0: +; X86-NEXT: xorl %eax, %eax +; X86-NEXT: retl +; +; X64-LABEL: uitofp_signbit_only_okay_width1: +; X64: # %bb.0: +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: retq + %f = uitofp i64 %i_in to float + %i = bitcast float %f to i32 + %r = and i32 %i, 2147483648 + ret i32 %r +} + +define <2 x i16> @uitofp_signbit_only_fail_bad_width2(i32 %i_in) nounwind { +; X86-LABEL: uitofp_signbit_only_fail_bad_width2: +; X86: # %bb.0: +; X86-NEXT: pushl %ebp +; X86-NEXT: movl %esp, %ebp +; X86-NEXT: andl $-8, %esp +; X86-NEXT: subl $16, %esp +; X86-NEXT: movl 8(%ebp), %eax +; X86-NEXT: movl %eax, {{[0-9]+}}(%esp) +; X86-NEXT: movl $0, {{[0-9]+}}(%esp) +; X86-NEXT: fildll {{[0-9]+}}(%esp) +; X86-NEXT: fstps {{[0-9]+}}(%esp) +; X86-NEXT: movl $32768, %eax # imm = 0x8000 +; X86-NEXT: andl {{[0-9]+}}(%esp), %eax +; X86-NEXT: # kill: def $ax killed $ax killed $eax +; X86-NEXT: xorl %edx, %edx +; X86-NEXT: movl %ebp, %esp +; X86-NEXT: popl %ebp +; X86-NEXT: retl +; +; X64-LABEL: uitofp_signbit_only_fail_bad_width2: +; X64: # %bb.0: +; X64-NEXT: movl %edi, %eax +; X64-NEXT: cvtsi2ss %rax, %xmm0 +; X64-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; X64-NEXT: retq + %f = uitofp i32 %i_in to float + %i2xi16 = bitcast float %f to <2 x i16> + %r = and <2 x i16> %i2xi16, <i16 32768, i16 32768> + ret <2 x i16> %r +} + +define i32 @uitofp_many_bits_fail(i32 %i_in) nounwind { +; X86-LABEL: uitofp_many_bits_fail: +; X86: # %bb.0: +; X86-NEXT: pushl %ebp +; X86-NEXT: movl %esp, %ebp +; X86-NEXT: andl $-8, %esp +; X86-NEXT: subl $16, %esp +; X86-NEXT: movl 8(%ebp), %eax +; X86-NEXT: movl %eax, {{[0-9]+}}(%esp) +; X86-NEXT: movl $0, {{[0-9]+}}(%esp) +; X86-NEXT: fildll {{[0-9]+}}(%esp) +; X86-NEXT: fstps {{[0-9]+}}(%esp) +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: andl $1, %eax +; X86-NEXT: movl %ebp, %esp +; X86-NEXT: popl %ebp +; X86-NEXT: retl +; +; X64-LABEL: uitofp_many_bits_fail: +; X64: # %bb.0: +; X64-NEXT: movl %edi, %eax +; X64-NEXT: cvtsi2ss %rax, %xmm0 +; X64-NEXT: movd %xmm0, %eax +; X64-NEXT: andl $1, %eax +; X64-NEXT: retq + %f = uitofp i32 %i_in to float + %i = bitcast float %f to i32 + %r = and i32 %i, 2147483649 + ret i32 %r +} + +define i32 @uitofp_multiuse_fail(i32 %i_in) nounwind { +; X86-LABEL: uitofp_multiuse_fail: +; X86: # %bb.0: +; X86-NEXT: pushl %ebp +; X86-NEXT: movl %esp, %ebp +; X86-NEXT: andl $-8, %esp +; X86-NEXT: subl $16, %esp +; X86-NEXT: movl 8(%ebp), %eax +; X86-NEXT: movl %eax, {{[0-9]+}}(%esp) +; X86-NEXT: movl $0, {{[0-9]+}}(%esp) +; X86-NEXT: fildll {{[0-9]+}}(%esp) +; X86-NEXT: fstps (%esp) +; X86-NEXT: calll use.i32@PLT +; X86-NEXT: xorl %eax, %eax +; X86-NEXT: movl %ebp, %esp +; X86-NEXT: popl %ebp +; X86-NEXT: retl +; +; X64-LABEL: uitofp_multiuse_fail: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: cvtsi2ss %rax, %xmm0 +; X64-NEXT: movd %xmm0, %edi +; X64-NEXT: callq use.i32@PLT +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: popq %rcx +; X64-NEXT: retq + %f = uitofp i32 %i_in to float + %i = bitcast float %f to i32 + call void @use.i32(i32 %i) + %r = and i32 %i, 2147483648 + ret i32 %r +} + +define i32 @uitofp_multiuse_okay(i32 %i_in) nounwind { +; X86-LABEL: uitofp_multiuse_okay: +; X86: # %bb.0: +; X86-NEXT: pushl %ebp +; X86-NEXT: movl %esp, %ebp +; X86-NEXT: andl $-8, %esp +; X86-NEXT: subl $16, %esp +; X86-NEXT: movl 8(%ebp), %eax +; X86-NEXT: movl %eax, {{[0-9]+}}(%esp) +; X86-NEXT: movl $0, {{[0-9]+}}(%esp) +; X86-NEXT: fildll {{[0-9]+}}(%esp) +; X86-NEXT: fstps (%esp) +; X86-NEXT: calll use.i1@PLT +; X86-NEXT: xorl %eax, %eax +; X86-NEXT: movl %ebp, %esp +; X86-NEXT: popl %ebp +; X86-NEXT: retl +; +; X64-LABEL: uitofp_multiuse_okay: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: cvtsi2ss %rax, %xmm0 +; X64-NEXT: movd %xmm0, %edi +; X64-NEXT: callq use.i1@PLT +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: popq %rcx +; X64-NEXT: retq + %f = uitofp i32 %i_in to float + %i = bitcast float %f to i32 + %cmp = icmp slt i32 %i, 0 + call void @use.i1(i32 %i) + %r = and i32 %i, 2147483648 + ret i32 %r +} -- GitLab From 353fbeb0a294d2c7cef6d88607fa0fd50ee81462 Mon Sep 17 00:00:00 2001 From: Noah Goldstein <goldstein.w.n@gmail.com> Date: Fri, 15 Mar 2024 12:45:31 -0500 Subject: [PATCH 155/307] [DAGCombiner] Simplifying `{si|ui}tofp` when only signbit is needed If we only need the signbit `uitofp` simplified to 0, and `sitofp` simplifies to `bitcast`. Closes #85138 --- .../CodeGen/SelectionDAG/TargetLowering.cpp | 30 +++++++++++++++++++ .../CodeGen/X86/combine-sse41-intrinsics.ll | 3 +- llvm/test/CodeGen/X86/int-to-fp-demanded.ll | 21 +++++-------- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 57f8fc409de4..16069c6c0dc3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -611,6 +611,25 @@ bool TargetLowering::ShrinkDemandedOp(SDValue Op, unsigned BitWidth, return false; } +static SDValue simplifyUseOfIntToFP(SDValue Op, const APInt &DemandedBits, + SelectionDAG &DAG) { + unsigned Opc = Op.getOpcode(); + assert((Opc == ISD::SINT_TO_FP || Opc == ISD::UINT_TO_FP) && + "Invalid Int -> FP Opcode"); + if (!DemandedBits.isSignMask()) + return SDValue(); + + EVT VT = Op.getValueType(); + if (Opc == ISD::UINT_TO_FP) + return DAG.getConstant(0, SDLoc(Op), VT); + + EVT InnerVT = Op.getOperand(0).getValueType(); + if (VT.getScalarSizeInBits() == InnerVT.getScalarSizeInBits()) + return DAG.getBitcast(VT, Op.getOperand(0)); + + return SDValue(); +} + bool TargetLowering::SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; @@ -816,6 +835,11 @@ SDValue TargetLowering::SimplifyMultipleUseDemandedBits( } break; } + case ISD::UINT_TO_FP: + case ISD::SINT_TO_FP: + if (SDValue R = simplifyUseOfIntToFP(Op, DemandedBits, DAG)) + return R; + break; case ISD::SIGN_EXTEND_INREG: { // If none of the extended bits are demanded, eliminate the sextinreg. SDValue Op0 = Op.getOperand(0); @@ -2313,6 +2337,12 @@ bool TargetLowering::SimplifyDemandedBits( Known = TLO.DAG.computeKnownBits(Op, DemandedElts, Depth); break; } + case ISD::UINT_TO_FP: + case ISD::SINT_TO_FP: + if (SDValue R = simplifyUseOfIntToFP(Op, DemandedBits, TLO.DAG)) + return TLO.CombineTo(Op, R); + Known = TLO.DAG.computeKnownBits(Op, DemandedElts, Depth); + break; case ISD::SIGN_EXTEND_INREG: { SDValue Op0 = Op.getOperand(0); EVT ExVT = cast<VTSDNode>(Op.getOperand(1))->getVT(); diff --git a/llvm/test/CodeGen/X86/combine-sse41-intrinsics.ll b/llvm/test/CodeGen/X86/combine-sse41-intrinsics.ll index cbb5bd09c239..a332b3e89080 100644 --- a/llvm/test/CodeGen/X86/combine-sse41-intrinsics.ll +++ b/llvm/test/CodeGen/X86/combine-sse41-intrinsics.ll @@ -164,14 +164,13 @@ define <4 x float> @demandedbits_sitofp_blendvps(<4 x float> %a0, <4 x float> %a ; SSE-LABEL: demandedbits_sitofp_blendvps: ; SSE: # %bb.0: ; SSE-NEXT: movaps %xmm0, %xmm3 -; SSE-NEXT: cvtdq2ps %xmm2, %xmm0 +; SSE-NEXT: movaps %xmm2, %xmm0 ; SSE-NEXT: blendvps %xmm0, %xmm1, %xmm3 ; SSE-NEXT: movaps %xmm3, %xmm0 ; SSE-NEXT: retq ; ; AVX-LABEL: demandedbits_sitofp_blendvps: ; AVX: # %bb.0: -; AVX-NEXT: vcvtdq2ps %xmm2, %xmm2 ; AVX-NEXT: vblendvps %xmm2, %xmm1, %xmm0, %xmm0 ; AVX-NEXT: retq %cvt = sitofp <4 x i32> %a2 to <4 x float> diff --git a/llvm/test/CodeGen/X86/int-to-fp-demanded.ll b/llvm/test/CodeGen/X86/int-to-fp-demanded.ll index cdde03fb0534..8652136ae5cd 100644 --- a/llvm/test/CodeGen/X86/int-to-fp-demanded.ll +++ b/llvm/test/CodeGen/X86/int-to-fp-demanded.ll @@ -7,19 +7,13 @@ declare void @use.i32(i32) define i32 @sitofp_signbit_only(i32 %i_in) nounwind { ; X86-LABEL: sitofp_signbit_only: ; X86: # %bb.0: -; X86-NEXT: subl $8, %esp -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, (%esp) -; X86-NEXT: fildl (%esp) -; X86-NEXT: fstps {{[0-9]+}}(%esp) ; X86-NEXT: movl $-2147483648, %eax # imm = 0x80000000 ; X86-NEXT: andl {{[0-9]+}}(%esp), %eax -; X86-NEXT: addl $8, %esp ; X86-NEXT: retl ; ; X64-LABEL: sitofp_signbit_only: ; X64: # %bb.0: -; X64-NEXT: cvtsi2ss %edi, %xmm0 +; X64-NEXT: movd %edi, %xmm0 ; X64-NEXT: movmskps %xmm0, %eax ; X64-NEXT: shll $31, %eax ; X64-NEXT: retq @@ -44,8 +38,8 @@ define i32 @sitofp_signbit_only_okay_width(i16 %i_in) nounwind { ; ; X64-LABEL: sitofp_signbit_only_okay_width: ; X64: # %bb.0: -; X64-NEXT: movswl %di, %eax -; X64-NEXT: cvtsi2ss %eax, %xmm0 +; X64-NEXT: shll $16, %edi +; X64-NEXT: movd %edi, %xmm0 ; X64-NEXT: movmskps %xmm0, %eax ; X64-NEXT: shll $31, %eax ; X64-NEXT: retq @@ -82,15 +76,14 @@ define <2 x i16> @sitofp_signbit_only_fail_bad_width2(i32 %i_in) nounwind { ; X86-LABEL: sitofp_signbit_only_fail_bad_width2: ; X86: # %bb.0: ; X86-NEXT: subl $8, %esp -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, (%esp) +; X86-NEXT: movl {{[0-9]+}}(%esp), %edx +; X86-NEXT: movl %edx, (%esp) ; X86-NEXT: fildl (%esp) ; X86-NEXT: fstps {{[0-9]+}}(%esp) -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx ; X86-NEXT: shrl $16, %edx -; X86-NEXT: andl $32768, %eax # imm = 0x8000 ; X86-NEXT: andl $32768, %edx # imm = 0x8000 +; X86-NEXT: movl $32768, %eax # imm = 0x8000 +; X86-NEXT: andl {{[0-9]+}}(%esp), %eax ; X86-NEXT: # kill: def $ax killed $ax killed $eax ; X86-NEXT: # kill: def $dx killed $dx killed $edx ; X86-NEXT: addl $8, %esp -- GitLab From 888e2849036c7a216dd6208a2fe5a59393d4767a Mon Sep 17 00:00:00 2001 From: Alex MacLean <amaclean@nvidia.com> Date: Tue, 19 Mar 2024 15:18:53 -0700 Subject: [PATCH 156/307] [NVPTX] Use PTX prmt for llvm.bswap (#85545) --- llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp | 3 - llvm/lib/Target/NVPTX/NVPTXInstrInfo.td | 19 +++++ llvm/test/CodeGen/NVPTX/bswap.ll | 77 +++++++++++++++++++++ 3 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 llvm/test/CodeGen/NVPTX/bswap.ll diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp index 7ad3d99ab71f..e1cdbd6a4b4d 100644 --- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp @@ -580,9 +580,6 @@ NVPTXTargetLowering::NVPTXTargetLowering(const NVPTXTargetMachine &TM, setOperationAction(ISD::ROTL, MVT::i8, Expand); setOperationAction(ISD::ROTR, MVT::i8, Expand); setOperationAction(ISD::BSWAP, MVT::i16, Expand); - setOperationAction(ISD::BSWAP, MVT::v2i16, Expand); - setOperationAction(ISD::BSWAP, MVT::i32, Expand); - setOperationAction(ISD::BSWAP, MVT::i64, Expand); // Indirect branch is not supported. // This also disables Jump Table creation. diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td index 3d387ed574fa..4daf47cfd4df 100644 --- a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td +++ b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td @@ -3549,6 +3549,11 @@ let hasSideEffects = false in { (ins Int64Regs:$s), "{{ .reg .b32 tmp; mov.b64 {tmp, $high}, $s; }}", []>; + def I64toI32L : NVPTXInst<(outs Int32Regs:$low), + (ins Int64Regs:$s), + "{{ .reg .b32 tmp; mov.b64 {$low, tmp}, $s; }}", + []>; + } // Using partial vectorized move produces better SASS code for extraction of @@ -3838,3 +3843,17 @@ include "NVPTXIntrinsics.td" // - for sm_20, use pmpt (use vector scalar mov to get the pack and // unpack). sm_20 supports native 32-bit register, but not native 16-bit // register. + +def : Pat < + (i32 (bswap i32:$a)), + (INT_NVVM_PRMT Int32Regs:$a, (i32 0), (i32 0x0123))>; + +def : Pat < + (v2i16 (bswap v2i16:$a)), + (INT_NVVM_PRMT Int32Regs:$a, (i32 0), (i32 0x2301))>; + +def : Pat < + (i64 (bswap i64:$a)), + (V2I32toI64 + (INT_NVVM_PRMT (I64toI32H Int64Regs:$a), (i32 0), (i32 0x0123)), + (INT_NVVM_PRMT (I64toI32L Int64Regs:$a), (i32 0), (i32 0x0123)))>; diff --git a/llvm/test/CodeGen/NVPTX/bswap.ll b/llvm/test/CodeGen/NVPTX/bswap.ll new file mode 100644 index 000000000000..3f929ec6a75d --- /dev/null +++ b/llvm/test/CodeGen/NVPTX/bswap.ll @@ -0,0 +1,77 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 | FileCheck %s +; RUN: %if ptxas %{ llc < %s -march=nvptx64 -mcpu=sm_20 | %ptxas-verify %} + +target triple = "nvptx64-nvidia-cuda" + +define i16 @bswap16(i16 %a) { +; CHECK-LABEL: bswap16( +; CHECK: { +; CHECK-NEXT: .reg .b16 %rs<5>; +; CHECK-NEXT: .reg .b32 %r<2>; +; CHECK-EMPTY: +; CHECK-NEXT: // %bb.0: +; CHECK-NEXT: ld.param.u16 %rs1, [bswap16_param_0]; +; CHECK-NEXT: shr.u16 %rs2, %rs1, 8; +; CHECK-NEXT: shl.b16 %rs3, %rs1, 8; +; CHECK-NEXT: or.b16 %rs4, %rs3, %rs2; +; CHECK-NEXT: cvt.u32.u16 %r1, %rs4; +; CHECK-NEXT: st.param.b32 [func_retval0+0], %r1; +; CHECK-NEXT: ret; + %b = tail call i16 @llvm.bswap.i16(i16 %a) + ret i16 %b +} + + +define i32 @bswap32(i32 %a) { +; CHECK-LABEL: bswap32( +; CHECK: { +; CHECK-NEXT: .reg .b32 %r<3>; +; CHECK-EMPTY: +; CHECK-NEXT: // %bb.0: +; CHECK-NEXT: ld.param.u32 %r1, [bswap32_param_0]; +; CHECK-NEXT: prmt.b32 %r2, %r1, 0, 291; +; CHECK-NEXT: st.param.b32 [func_retval0+0], %r2; +; CHECK-NEXT: ret; + %b = tail call i32 @llvm.bswap.i32(i32 %a) + ret i32 %b +} + + +define <2 x i16> @bswapv2i16(<2 x i16> %a) #0 { +; CHECK-LABEL: bswapv2i16( +; CHECK: { +; CHECK-NEXT: .reg .b32 %r<3>; +; CHECK-EMPTY: +; CHECK-NEXT: // %bb.0: +; CHECK-NEXT: ld.param.u32 %r1, [bswapv2i16_param_0]; +; CHECK-NEXT: prmt.b32 %r2, %r1, 0, 8961; +; CHECK-NEXT: st.param.b32 [func_retval0+0], %r2; +; CHECK-NEXT: ret; + %b = tail call <2 x i16> @llvm.bswap.v2i16(<2 x i16> %a) + ret <2 x i16> %b +} + +define i64 @bswap64(i64 %a) { +; CHECK-LABEL: bswap64( +; CHECK: { +; CHECK-NEXT: .reg .b32 %r<5>; +; CHECK-NEXT: .reg .b64 %rd<3>; +; CHECK-EMPTY: +; CHECK-NEXT: // %bb.0: +; CHECK-NEXT: ld.param.u64 %rd1, [bswap64_param_0]; +; CHECK-NEXT: { .reg .b32 tmp; mov.b64 {%r1, tmp}, %rd1; } +; CHECK-NEXT: prmt.b32 %r2, %r1, 0, 291; +; CHECK-NEXT: { .reg .b32 tmp; mov.b64 {tmp, %r3}, %rd1; } +; CHECK-NEXT: prmt.b32 %r4, %r3, 0, 291; +; CHECK-NEXT: mov.b64 %rd2, {%r4, %r2}; +; CHECK-NEXT: st.param.b64 [func_retval0+0], %rd2; +; CHECK-NEXT: ret; + %b = tail call i64 @llvm.bswap.i64(i64 %a) + ret i64 %b +} + +declare i16 @llvm.bswap.i16(i16) +declare i32 @llvm.bswap.i32(i32) +declare <2 x i16> @llvm.bswap.v2i16(<2 x i16>) +declare i64 @llvm.bswap.i64(i64) -- GitLab From 35bf8e798dc61aee9fcfbc0b162169295d1ce290 Mon Sep 17 00:00:00 2001 From: Fangrui Song <i@maskray.me> Date: Tue, 19 Mar 2024 15:40:23 -0700 Subject: [PATCH 157/307] [Support] Add decodeULEB128AndInc/decodeSLEB128AndInc Many decodeULEB128/decodeSLEB128 users need to increment the pointer. Add helpers to simplify this common pattern. We don't add `end` and `error` parameters at present because many users don't need them. Pull Request: https://github.com/llvm/llvm-project/pull/85739 --- llvm/include/llvm/Support/LEB128.h | 14 +++++++++++ llvm/unittests/Support/LEB128Test.cpp | 15 ++++++++++++ llvm/utils/TableGen/DecoderEmitter.cpp | 33 ++++++++------------------ 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/llvm/include/llvm/Support/LEB128.h b/llvm/include/llvm/Support/LEB128.h index 7fc572b6ff06..c4e741549f3f 100644 --- a/llvm/include/llvm/Support/LEB128.h +++ b/llvm/include/llvm/Support/LEB128.h @@ -200,6 +200,20 @@ inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr, return Value; } +inline uint64_t decodeULEB128AndInc(const uint8_t *&p) { + unsigned n; + auto ret = decodeULEB128(p, &n); + p += n; + return ret; +} + +inline int64_t decodeSLEB128AndInc(const uint8_t *&p) { + unsigned n; + auto ret = decodeSLEB128(p, &n); + p += n; + return ret; +} + /// Utility function to get the size of the ULEB128-encoded value. extern unsigned getULEB128Size(uint64_t Value); diff --git a/llvm/unittests/Support/LEB128Test.cpp b/llvm/unittests/Support/LEB128Test.cpp index 21523e5f7a08..08b8c5573ce6 100644 --- a/llvm/unittests/Support/LEB128Test.cpp +++ b/llvm/unittests/Support/LEB128Test.cpp @@ -242,6 +242,21 @@ TEST(LEB128Test, DecodeInvalidSLEB128) { #undef EXPECT_INVALID_SLEB128 } +TEST(LEB128Test, DecodeAndInc) { +#define EXPECT_LEB128(FUN, VALUE, SIZE) \ + do { \ + const uint8_t *V = reinterpret_cast<const uint8_t *>(VALUE), *P = V; \ + auto Expected = FUN(P), Actual = FUN##AndInc(P); \ + EXPECT_EQ(Actual, Expected); \ + EXPECT_EQ(P - V, SIZE); \ + } while (0) + EXPECT_LEB128(decodeULEB128, "\x7f", 1); + EXPECT_LEB128(decodeULEB128, "\x80\x01", 2); + EXPECT_LEB128(decodeSLEB128, "\x7f", 1); + EXPECT_LEB128(decodeSLEB128, "\x80\x01", 2); +#undef EXPECT_LEB128 +} + TEST(LEB128Test, SLEB128Size) { // Positive Value Testing Plan: // (1) 128 ^ n - 1 ........ need (n+1) bytes diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 628bff520a12..732f34ed04c5 100644 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -2283,10 +2283,8 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI, } case MCD::OPC_CheckField: { // Decode the start value. - unsigned Len; - unsigned Start = decodeULEB128(++Ptr, &Len); - Ptr += Len; - Len = *Ptr;)"; + unsigned Start = decodeULEB128AndInc(++Ptr); + unsigned Len = *Ptr;)"; if (IsVarLenInst) OS << "\n makeUp(insn, Start + Len);"; OS << R"( @@ -2311,10 +2309,8 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI, break; } case MCD::OPC_CheckPredicate: { - unsigned Len; // Decode the Predicate Index value. - unsigned PIdx = decodeULEB128(++Ptr, &Len); - Ptr += Len; + unsigned PIdx = decodeULEB128AndInc(++Ptr); // NumToSkip is a plain 24-bit integer. unsigned NumToSkip = *Ptr++; NumToSkip |= (*Ptr++) << 8; @@ -2330,18 +2326,15 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI, break; } case MCD::OPC_Decode: { - unsigned Len; // Decode the Opcode value. - unsigned Opc = decodeULEB128(++Ptr, &Len); - Ptr += Len; - unsigned DecodeIdx = decodeULEB128(Ptr, &Len); - Ptr += Len; + unsigned Opc = decodeULEB128AndInc(++Ptr); + unsigned DecodeIdx = decodeULEB128AndInc(Ptr); MI.clear(); MI.setOpcode(Opc); bool DecodeComplete;)"; if (IsVarLenInst) { - OS << "\n Len = InstrLenTable[Opc];\n" + OS << "\n unsigned Len = InstrLenTable[Opc];\n" << " makeUp(insn, Len);"; } OS << R"( @@ -2354,12 +2347,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI, return S; } case MCD::OPC_TryDecode: { - unsigned Len; // Decode the Opcode value. - unsigned Opc = decodeULEB128(++Ptr, &Len); - Ptr += Len; - unsigned DecodeIdx = decodeULEB128(Ptr, &Len); - Ptr += Len; + unsigned Opc = decodeULEB128AndInc(++Ptr); + unsigned DecodeIdx = decodeULEB128AndInc(Ptr); // NumToSkip is a plain 24-bit integer. unsigned NumToSkip = *Ptr++; NumToSkip |= (*Ptr++) << 8; @@ -2391,11 +2381,8 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI, } case MCD::OPC_SoftFail: { // Decode the mask values. - unsigned Len; - uint64_t PositiveMask = decodeULEB128(++Ptr, &Len); - Ptr += Len; - uint64_t NegativeMask = decodeULEB128(Ptr, &Len); - Ptr += Len; + uint64_t PositiveMask = decodeULEB128AndInc(++Ptr); + uint64_t NegativeMask = decodeULEB128AndInc(Ptr); bool Fail = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0; if (Fail) S = MCDisassembler::SoftFail; -- GitLab From e28d3e9b4e5779028a38ca39ed060938ff62c498 Mon Sep 17 00:00:00 2001 From: Florian Mayer <fmayer@google.com> Date: Thu, 14 Mar 2024 16:18:43 -0700 Subject: [PATCH 158/307] [NFC] [hwasan] factor get[PC|FP] out of HWASan class (#84404) Also be consistent about naming SP / FP. This is to prepare for stack history buffer for memtag-stack --- .../Transforms/Utils/MemoryTaggingSupport.h | 5 ++ .../Instrumentation/HWAddressSanitizer.cpp | 71 ++++++------------- .../Transforms/Utils/MemoryTaggingSupport.cpp | 32 +++++++++ 3 files changed, 59 insertions(+), 49 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h index d649e6995e55..0a0e16d2a9e6 100644 --- a/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h +++ b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h @@ -17,6 +17,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/StackSafetyAnalysis.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/Support/Alignment.h" namespace llvm { @@ -80,6 +81,10 @@ uint64_t getAllocaSizeInBytes(const AllocaInst &AI); void alignAndPadAlloca(memtag::AllocaInfo &Info, llvm::Align Align); bool isLifetimeIntrinsic(Value *V); +Value *readRegister(IRBuilder<> &IRB, StringRef Name); +Value *getFP(IRBuilder<> &IRB); +Value *getPC(const Triple &TargetTriple, IRBuilder<> &IRB); + } // namespace memtag } // namespace llvm diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index d2e3471d5600..4bdeb6bbab85 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -357,7 +357,6 @@ private: bool instrumentStack(memtag::StackInfo &Info, Value *StackTag, Value *UARTag, const DominatorTree &DT, const PostDominatorTree &PDT, const LoopInfo &LI); - Value *readRegister(IRBuilder<> &IRB, StringRef Name); bool instrumentLandingPads(SmallVectorImpl<Instruction *> &RetVec); Value *getNextTagWithCall(IRBuilder<> &IRB); Value *getStackBaseTag(IRBuilder<> &IRB); @@ -373,8 +372,7 @@ private: void instrumentGlobal(GlobalVariable *GV, uint8_t Tag); void instrumentGlobals(); - Value *getPC(IRBuilder<> &IRB); - Value *getFP(IRBuilder<> &IRB); + Value *getCachedFP(IRBuilder<> &IRB); Value *getFrameRecordInfo(IRBuilder<> &IRB); void instrumentPersonalityFunctions(); @@ -449,7 +447,7 @@ private: Value *ShadowBase = nullptr; Value *StackBaseTag = nullptr; - Value *CachedSP = nullptr; + Value *CachedFP = nullptr; GlobalValue *ThreadPtrGlobal = nullptr; }; @@ -1159,10 +1157,10 @@ Value *HWAddressSanitizer::getStackBaseTag(IRBuilder<> &IRB) { // Extract some entropy from the stack pointer for the tags. // Take bits 20..28 (ASLR entropy) and xor with bits 0..8 (these differ // between functions). - Value *StackPointerLong = getFP(IRB); + Value *FramePointerLong = getCachedFP(IRB); Value *StackTag = - applyTagMask(IRB, IRB.CreateXor(StackPointerLong, - IRB.CreateLShr(StackPointerLong, 20))); + applyTagMask(IRB, IRB.CreateXor(FramePointerLong, + IRB.CreateLShr(FramePointerLong, 20))); StackTag->setName("hwasan.stack.base.tag"); return StackTag; } @@ -1176,9 +1174,9 @@ Value *HWAddressSanitizer::getAllocaTag(IRBuilder<> &IRB, Value *StackTag, } Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB) { - Value *StackPointerLong = getFP(IRB); + Value *FramePointerLong = getCachedFP(IRB); Value *UARTag = - applyTagMask(IRB, IRB.CreateLShr(StackPointerLong, PointerTagShift)); + applyTagMask(IRB, IRB.CreateLShr(FramePointerLong, PointerTagShift)); UARTag->setName("hwasan.uar.tag"); return UARTag; @@ -1237,41 +1235,25 @@ Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty) { return nullptr; } -Value *HWAddressSanitizer::getPC(IRBuilder<> &IRB) { - if (TargetTriple.getArch() == Triple::aarch64) - return readRegister(IRB, "pc"); - return IRB.CreatePtrToInt(IRB.GetInsertBlock()->getParent(), IntptrTy); -} - -Value *HWAddressSanitizer::getFP(IRBuilder<> &IRB) { - if (!CachedSP) { - // FIXME: use addressofreturnaddress (but implement it in aarch64 backend - // first). - Function *F = IRB.GetInsertBlock()->getParent(); - Module *M = F->getParent(); - auto *GetStackPointerFn = Intrinsic::getDeclaration( - M, Intrinsic::frameaddress, - IRB.getPtrTy(M->getDataLayout().getAllocaAddrSpace())); - CachedSP = IRB.CreatePtrToInt( - IRB.CreateCall(GetStackPointerFn, {Constant::getNullValue(Int32Ty)}), - IntptrTy); - } - return CachedSP; +Value *HWAddressSanitizer::getCachedFP(IRBuilder<> &IRB) { + if (!CachedFP) + CachedFP = memtag::getFP(IRB); + return CachedFP; } Value *HWAddressSanitizer::getFrameRecordInfo(IRBuilder<> &IRB) { // Prepare ring buffer data. - Value *PC = getPC(IRB); - Value *SP = getFP(IRB); + Value *PC = memtag::getPC(TargetTriple, IRB); + Value *FP = getCachedFP(IRB); - // Mix SP and PC. + // Mix FP and PC. // Assumptions: // PC is 0x0000PPPPPPPPPPPP (48 bits are meaningful, others are zero) - // SP is 0xsssssssssssSSSS0 (4 lower bits are zero) - // We only really need ~20 lower non-zero bits (SSSS), so we mix like this: - // 0xSSSSPPPPPPPPPPPP - SP = IRB.CreateShl(SP, 44); - return IRB.CreateOr(PC, SP); + // FP is 0xfffffffffffFFFF0 (4 lower bits are zero) + // We only really need ~20 lower non-zero bits (FFFF), so we mix like this: + // 0xFFFFPPPPPPPPPPPP + FP = IRB.CreateShl(FP, 44); + return IRB.CreateOr(PC, FP); } void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) { @@ -1356,23 +1338,14 @@ void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) { } } -Value *HWAddressSanitizer::readRegister(IRBuilder<> &IRB, StringRef Name) { - Module *M = IRB.GetInsertBlock()->getParent()->getParent(); - Function *ReadRegister = - Intrinsic::getDeclaration(M, Intrinsic::read_register, IntptrTy); - MDNode *MD = MDNode::get(*C, {MDString::get(*C, Name)}); - Value *Args[] = {MetadataAsValue::get(*C, MD)}; - return IRB.CreateCall(ReadRegister, Args); -} - bool HWAddressSanitizer::instrumentLandingPads( SmallVectorImpl<Instruction *> &LandingPadVec) { for (auto *LP : LandingPadVec) { IRBuilder<> IRB(LP->getNextNonDebugInstruction()); IRB.CreateCall( HwasanHandleVfork, - {readRegister(IRB, (TargetTriple.getArch() == Triple::x86_64) ? "rsp" - : "sp")}); + {memtag::readRegister( + IRB, (TargetTriple.getArch() == Triple::x86_64) ? "rsp" : "sp")}); } return true; } @@ -1637,7 +1610,7 @@ void HWAddressSanitizer::sanitizeFunction(Function &F, ShadowBase = nullptr; StackBaseTag = nullptr; - CachedSP = nullptr; + CachedFP = nullptr; } void HWAddressSanitizer::instrumentGlobal(GlobalVariable *GV, uint8_t Tag) { diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp index a3858a7985ce..8dd1002a6e4a 100644 --- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp +++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp @@ -18,7 +18,9 @@ #include "llvm/Analysis/StackSafetyAnalysis.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/BasicBlock.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/TargetParser/Triple.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" namespace llvm { @@ -241,5 +243,35 @@ bool isLifetimeIntrinsic(Value *V) { return II && II->isLifetimeStartOrEnd(); } +Value *readRegister(IRBuilder<> &IRB, StringRef Name) { + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + Function *ReadRegister = Intrinsic::getDeclaration( + M, Intrinsic::read_register, IRB.getIntPtrTy(M->getDataLayout())); + MDNode *MD = + MDNode::get(M->getContext(), {MDString::get(M->getContext(), Name)}); + Value *Args[] = {MetadataAsValue::get(M->getContext(), MD)}; + return IRB.CreateCall(ReadRegister, Args); +} + +Value *getPC(const Triple &TargetTriple, IRBuilder<> &IRB) { + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + if (TargetTriple.getArch() == Triple::aarch64) + return memtag::readRegister(IRB, "pc"); + return IRB.CreatePtrToInt(IRB.GetInsertBlock()->getParent(), + IRB.getIntPtrTy(M->getDataLayout())); +} + +Value *getFP(IRBuilder<> &IRB) { + Function *F = IRB.GetInsertBlock()->getParent(); + Module *M = F->getParent(); + auto *GetStackPointerFn = Intrinsic::getDeclaration( + M, Intrinsic::frameaddress, + IRB.getPtrTy(M->getDataLayout().getAllocaAddrSpace())); + return IRB.CreatePtrToInt( + IRB.CreateCall(GetStackPointerFn, + {Constant::getNullValue(IRB.getInt32Ty())}), + IRB.getIntPtrTy(M->getDataLayout())); +} + } // namespace memtag } // namespace llvm -- GitLab From b5d02bbd0d9595501597ddbcf93ac51b160fc8bf Mon Sep 17 00:00:00 2001 From: dhruvachak <Dhruva.Chakrabarti@amd.com> Date: Tue, 19 Mar 2024 16:40:22 -0700 Subject: [PATCH 159/307] [OpenMP] Increment kernel args version, used by runtime for detecting dyn_ptr. (#85363) A kernel implicit parameter (dyn_ptr) was introduced some time back. This patch increments the kernel args version for a compiler supporting dyn_ptr. The version will be used by the runtime to determine whether the implicit parameter is generated by the compiler. The versioning is required to support use cases where code generated by an older compiler is linked with a newer runtime. If approved, this patch should be backported to release 18. --- clang/test/OpenMP/bug60602.cpp | 4 +- clang/test/OpenMP/distribute_codegen.cpp | 20 +-- .../distribute_firstprivate_codegen.cpp | 8 +- .../OpenMP/distribute_lastprivate_codegen.cpp | 8 +- .../distribute_parallel_for_codegen.cpp | 56 ++++---- ...bute_parallel_for_firstprivate_codegen.cpp | 8 +- .../distribute_parallel_for_if_codegen.cpp | 16 +-- ...ibute_parallel_for_lastprivate_codegen.cpp | 8 +- ...ibute_parallel_for_num_threads_codegen.cpp | 48 +++---- ...istribute_parallel_for_private_codegen.cpp | 8 +- ...tribute_parallel_for_proc_bind_codegen.cpp | 6 +- .../distribute_parallel_for_simd_codegen.cpp | 56 ++++---- ...parallel_for_simd_firstprivate_codegen.cpp | 8 +- ...istribute_parallel_for_simd_if_codegen.cpp | 64 +++++----- ..._parallel_for_simd_lastprivate_codegen.cpp | 8 +- ..._parallel_for_simd_num_threads_codegen.cpp | 48 +++---- ...bute_parallel_for_simd_private_codegen.cpp | 8 +- ...te_parallel_for_simd_proc_bind_codegen.cpp | 6 +- .../OpenMP/distribute_private_codegen.cpp | 12 +- clang/test/OpenMP/distribute_simd_codegen.cpp | 40 +++--- .../distribute_simd_firstprivate_codegen.cpp | 8 +- .../distribute_simd_lastprivate_codegen.cpp | 8 +- .../distribute_simd_private_codegen.cpp | 12 +- .../distribute_simd_reduction_codegen.cpp | 8 +- clang/test/OpenMP/map_struct_ordering.cpp | 2 +- clang/test/OpenMP/nvptx_lambda_capturing.cpp | 10 +- clang/test/OpenMP/reduction_implicit_map.cpp | 12 +- .../OpenMP/target_codegen_global_capture.cpp | 12 +- .../OpenMP/target_firstprivate_codegen.cpp | 48 +++---- .../OpenMP/target_has_device_addr_codegen.cpp | 30 ++--- .../target_has_device_addr_codegen_01.cpp | 4 +- .../OpenMP/target_is_device_ptr_codegen.cpp | 88 ++++++------- clang/test/OpenMP/target_map_codegen_03.cpp | 4 +- clang/test/OpenMP/target_map_codegen_hold.cpp | 24 ++-- .../OpenMP/target_map_deref_array_codegen.cpp | 6 +- .../OpenMP/target_map_member_expr_codegen.cpp | 6 +- .../target_offload_mandatory_codegen.cpp | 6 +- .../target_ompx_dyn_cgroup_mem_codegen.cpp | 24 ++-- clang/test/OpenMP/target_parallel_codegen.cpp | 28 ++-- .../OpenMP/target_parallel_for_codegen.cpp | 56 ++++---- .../target_parallel_for_simd_codegen.cpp | 56 ++++---- ...target_parallel_generic_loop_codegen-1.cpp | 24 ++-- ...target_parallel_generic_loop_codegen-2.cpp | 4 +- ...l_generic_loop_uses_allocators_codegen.cpp | 2 +- .../OpenMP/target_parallel_if_codegen.cpp | 24 ++-- .../target_parallel_num_threads_codegen.cpp | 24 ++-- .../OpenMP/target_task_affinity_codegen.cpp | 4 +- clang/test/OpenMP/target_teams_codegen.cpp | 44 +++---- .../target_teams_distribute_codegen.cpp | 28 ++-- ...rget_teams_distribute_collapse_codegen.cpp | 12 +- ...teams_distribute_dist_schedule_codegen.cpp | 36 +++--- ..._teams_distribute_firstprivate_codegen.cpp | 8 +- ...t_teams_distribute_lastprivate_codegen.cpp | 8 +- ..._teams_distribute_parallel_for_codegen.cpp | 8 +- ...stribute_parallel_for_collapse_codegen.cpp | 12 +- ...ute_parallel_for_dist_schedule_codegen.cpp | 36 +++--- ...bute_parallel_for_firstprivate_codegen.cpp | 8 +- ...ams_distribute_parallel_for_if_codegen.cpp | 12 +- ...ibute_parallel_for_lastprivate_codegen.cpp | 8 +- ..._distribute_parallel_for_order_codegen.cpp | 2 +- ...istribute_parallel_for_private_codegen.cpp | 8 +- ...tribute_parallel_for_proc_bind_codegen.cpp | 6 +- ...tribute_parallel_for_reduction_codegen.cpp | 8 +- ...stribute_parallel_for_schedule_codegen.cpp | 120 +++++++++--------- ...s_distribute_parallel_for_simd_codegen.cpp | 12 +- ...ute_parallel_for_simd_collapse_codegen.cpp | 12 +- ...arallel_for_simd_dist_schedule_codegen.cpp | 36 +++--- ...parallel_for_simd_firstprivate_codegen.cpp | 8 +- ...istribute_parallel_for_simd_if_codegen.cpp | 48 +++---- ..._parallel_for_simd_lastprivate_codegen.cpp | 8 +- ...bute_parallel_for_simd_private_codegen.cpp | 8 +- ...te_parallel_for_simd_proc_bind_codegen.cpp | 6 +- ...te_parallel_for_simd_reduction_codegen.cpp | 8 +- ...ute_parallel_for_simd_schedule_codegen.cpp | 120 +++++++++--------- ...arget_teams_distribute_private_codegen.cpp | 8 +- ...get_teams_distribute_reduction_codegen.cpp | 80 ++++++------ .../target_teams_distribute_simd_codegen.cpp | 56 ++++---- ...teams_distribute_simd_collapse_codegen.cpp | 12 +- ..._distribute_simd_dist_schedule_codegen.cpp | 36 +++--- ...s_distribute_simd_firstprivate_codegen.cpp | 8 +- ...ms_distribute_simd_lastprivate_codegen.cpp | 8 +- ..._teams_distribute_simd_private_codegen.cpp | 8 +- ...eams_distribute_simd_reduction_codegen.cpp | 8 +- .../target_teams_generic_loop_codegen-1.cpp | 8 +- ...et_teams_generic_loop_collapse_codegen.cpp | 12 +- .../target_teams_generic_loop_if_codegen.cpp | 10 +- ...arget_teams_generic_loop_order_codegen.cpp | 2 +- ...get_teams_generic_loop_private_codegen.cpp | 8 +- ...t_teams_generic_loop_reduction_codegen.cpp | 8 +- ...s_generic_loop_uses_allocators_codegen.cpp | 2 +- .../test/OpenMP/target_teams_map_codegen.cpp | 36 +++--- .../OpenMP/target_teams_num_teams_codegen.cpp | 24 ++-- .../target_teams_thread_limit_codegen.cpp | 24 ++-- clang/test/OpenMP/teams_codegen.cpp | 40 +++--- .../test/OpenMP/teams_distribute_codegen.cpp | 24 ++-- .../teams_distribute_collapse_codegen.cpp | 12 +- ...teams_distribute_dist_schedule_codegen.cpp | 36 +++--- .../teams_distribute_firstprivate_codegen.cpp | 8 +- .../teams_distribute_lastprivate_codegen.cpp | 8 +- .../teams_distribute_parallel_for_codegen.cpp | 24 ++-- ...stribute_parallel_for_collapse_codegen.cpp | 12 +- ...distribute_parallel_for_copyin_codegen.cpp | 8 +- ...ute_parallel_for_dist_schedule_codegen.cpp | 36 +++--- ...bute_parallel_for_firstprivate_codegen.cpp | 8 +- ...ams_distribute_parallel_for_if_codegen.cpp | 16 +-- ...ibute_parallel_for_lastprivate_codegen.cpp | 8 +- ...ibute_parallel_for_num_threads_codegen.cpp | 24 ++-- ...istribute_parallel_for_private_codegen.cpp | 8 +- ...tribute_parallel_for_proc_bind_codegen.cpp | 6 +- ...tribute_parallel_for_reduction_codegen.cpp | 8 +- ...stribute_parallel_for_schedule_codegen.cpp | 120 +++++++++--------- ...s_distribute_parallel_for_simd_codegen.cpp | 24 ++-- ...ute_parallel_for_simd_collapse_codegen.cpp | 12 +- ...arallel_for_simd_dist_schedule_codegen.cpp | 36 +++--- ...parallel_for_simd_firstprivate_codegen.cpp | 8 +- ...istribute_parallel_for_simd_if_codegen.cpp | 64 +++++----- ..._parallel_for_simd_lastprivate_codegen.cpp | 8 +- ..._parallel_for_simd_num_threads_codegen.cpp | 24 ++-- ...bute_parallel_for_simd_private_codegen.cpp | 8 +- ...te_parallel_for_simd_proc_bind_codegen.cpp | 6 +- ...te_parallel_for_simd_reduction_codegen.cpp | 8 +- ...ute_parallel_for_simd_schedule_codegen.cpp | 120 +++++++++--------- .../teams_distribute_private_codegen.cpp | 8 +- .../teams_distribute_reduction_codegen.cpp | 8 +- .../OpenMP/teams_distribute_simd_codegen.cpp | 36 +++--- ...teams_distribute_simd_collapse_codegen.cpp | 12 +- ..._distribute_simd_dist_schedule_codegen.cpp | 36 +++--- ...s_distribute_simd_firstprivate_codegen.cpp | 8 +- ...ms_distribute_simd_lastprivate_codegen.cpp | 8 +- .../teams_distribute_simd_private_codegen.cpp | 8 +- ...eams_distribute_simd_reduction_codegen.cpp | 8 +- .../OpenMP/teams_firstprivate_codegen.cpp | 24 ++-- .../OpenMP/teams_generic_loop_codegen-1.cpp | 24 ++-- .../teams_generic_loop_collapse_codegen.cpp | 12 +- .../teams_generic_loop_private_codegen.cpp | 8 +- .../teams_generic_loop_reduction_codegen.cpp | 8 +- clang/test/OpenMP/teams_private_codegen.cpp | 20 +-- .../llvm/Frontend/OpenMP/OMPConstants.h | 5 +- .../common/include/PluginInterface.h | 2 +- .../common/src/PluginInterface.cpp | 15 ++- openmp/libomptarget/src/interface.cpp | 16 ++- openmp/libomptarget/src/omptarget.cpp | 3 +- 142 files changed, 1487 insertions(+), 1468 deletions(-) diff --git a/clang/test/OpenMP/bug60602.cpp b/clang/test/OpenMP/bug60602.cpp index 48dc341a0822..9c92ec27b86e 100644 --- a/clang/test/OpenMP/bug60602.cpp +++ b/clang/test/OpenMP/bug60602.cpp @@ -95,7 +95,7 @@ int kernel_within_loop(int *a, int *b, int N, int num_iters) { // CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -181,7 +181,7 @@ int kernel_within_loop(int *a, int *b, int N, int num_iters) { // CHECK-NEXT: [[ADD:%.*]] = add i32 [[TMP71]], 1 // CHECK-NEXT: [[TMP72:%.*]] = zext i32 [[ADD]] to i64 // CHECK-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP73]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP73]], align 4 // CHECK-NEXT: [[TMP74:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK-NEXT: store i32 3, ptr [[TMP74]], align 4 // CHECK-NEXT: [[TMP75:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_codegen.cpp b/clang/test/OpenMP/distribute_codegen.cpp index 31ec6ff91190..34d14c89feda 100644 --- a/clang/test/OpenMP/distribute_codegen.cpp +++ b/clang/test/OpenMP/distribute_codegen.cpp @@ -163,7 +163,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -354,7 +354,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -545,7 +545,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -744,7 +744,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP9]], 1 // CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[ADD4]] to i64 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP11]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP12]], align 4 // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -911,7 +911,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1084,7 +1084,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1271,7 +1271,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1458,7 +1458,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1653,7 +1653,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP9]], 1 // CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[ADD4]] to i64 // CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP11]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP12]], align 4 // CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1820,7 +1820,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_firstprivate_codegen.cpp b/clang/test/OpenMP/distribute_firstprivate_codegen.cpp index 800a002e4396..567d12119db2 100644 --- a/clang/test/OpenMP/distribute_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_firstprivate_codegen.cpp @@ -542,7 +542,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -838,7 +838,7 @@ int main() { // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1207,7 +1207,7 @@ int main() { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1501,7 +1501,7 @@ int main() { // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_lastprivate_codegen.cpp b/clang/test/OpenMP/distribute_lastprivate_codegen.cpp index 772372076e94..5d1a12d27145 100644 --- a/clang/test/OpenMP/distribute_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_lastprivate_codegen.cpp @@ -527,7 +527,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -841,7 +841,7 @@ int main() { // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1229,7 +1229,7 @@ int main() { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1541,7 +1541,7 @@ int main() { // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_codegen.cpp index 9cb0a1553065..a8892a06d4b3 100644 --- a/clang/test/OpenMP/distribute_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_codegen.cpp @@ -4372,7 +4372,7 @@ int main() { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4447,7 +4447,7 @@ int main() { // CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 [[TMP59]], 1 // CHECK9-NEXT: [[TMP60:%.*]] = zext i32 [[ADD13]] to i64 // CHECK9-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP61]], align 4 // CHECK9-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP62]], align 4 // CHECK9-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -4531,7 +4531,7 @@ int main() { // CHECK9-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP102]], 1 // CHECK9-NEXT: [[TMP103:%.*]] = zext i32 [[ADD27]] to i64 // CHECK9-NEXT: [[TMP104:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP104]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP104]], align 4 // CHECK9-NEXT: [[TMP105:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP105]], align 4 // CHECK9-NEXT: [[TMP106:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -4606,7 +4606,7 @@ int main() { // CHECK9-NEXT: [[ADD41:%.*]] = add nsw i32 [[TMP140]], 1 // CHECK9-NEXT: [[TMP141:%.*]] = zext i32 [[ADD41]] to i64 // CHECK9-NEXT: [[TMP142:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP142]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP142]], align 4 // CHECK9-NEXT: [[TMP143:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP143]], align 4 // CHECK9-NEXT: [[TMP144:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 2 @@ -4690,7 +4690,7 @@ int main() { // CHECK9-NEXT: [[ADD56:%.*]] = add nsw i32 [[TMP183]], 1 // CHECK9-NEXT: [[TMP184:%.*]] = zext i32 [[ADD56]] to i64 // CHECK9-NEXT: [[TMP185:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP185]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP185]], align 4 // CHECK9-NEXT: [[TMP186:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP186]], align 4 // CHECK9-NEXT: [[TMP187:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 2 @@ -4765,7 +4765,7 @@ int main() { // CHECK9-NEXT: [[ADD70:%.*]] = add nsw i32 [[TMP221]], 1 // CHECK9-NEXT: [[TMP222:%.*]] = zext i32 [[ADD70]] to i64 // CHECK9-NEXT: [[TMP223:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP223]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP223]], align 4 // CHECK9-NEXT: [[TMP224:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP224]], align 4 // CHECK9-NEXT: [[TMP225:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 2 @@ -4849,7 +4849,7 @@ int main() { // CHECK9-NEXT: [[ADD85:%.*]] = add nsw i32 [[TMP264]], 1 // CHECK9-NEXT: [[TMP265:%.*]] = zext i32 [[ADD85]] to i64 // CHECK9-NEXT: [[TMP266:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP266]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP266]], align 4 // CHECK9-NEXT: [[TMP267:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP267]], align 4 // CHECK9-NEXT: [[TMP268:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 2 @@ -6671,7 +6671,7 @@ int main() { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6746,7 +6746,7 @@ int main() { // CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 [[TMP59]], 1 // CHECK9-NEXT: [[TMP60:%.*]] = zext i32 [[ADD13]] to i64 // CHECK9-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP61]], align 4 // CHECK9-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP62]], align 4 // CHECK9-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -6830,7 +6830,7 @@ int main() { // CHECK9-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP102]], 1 // CHECK9-NEXT: [[TMP103:%.*]] = zext i32 [[ADD27]] to i64 // CHECK9-NEXT: [[TMP104:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP104]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP104]], align 4 // CHECK9-NEXT: [[TMP105:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP105]], align 4 // CHECK9-NEXT: [[TMP106:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -6905,7 +6905,7 @@ int main() { // CHECK9-NEXT: [[ADD41:%.*]] = add nsw i32 [[TMP140]], 1 // CHECK9-NEXT: [[TMP141:%.*]] = zext i32 [[ADD41]] to i64 // CHECK9-NEXT: [[TMP142:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP142]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP142]], align 4 // CHECK9-NEXT: [[TMP143:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP143]], align 4 // CHECK9-NEXT: [[TMP144:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 2 @@ -6989,7 +6989,7 @@ int main() { // CHECK9-NEXT: [[ADD56:%.*]] = add nsw i32 [[TMP183]], 1 // CHECK9-NEXT: [[TMP184:%.*]] = zext i32 [[ADD56]] to i64 // CHECK9-NEXT: [[TMP185:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP185]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP185]], align 4 // CHECK9-NEXT: [[TMP186:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP186]], align 4 // CHECK9-NEXT: [[TMP187:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 2 @@ -7064,7 +7064,7 @@ int main() { // CHECK9-NEXT: [[ADD70:%.*]] = add nsw i32 [[TMP221]], 1 // CHECK9-NEXT: [[TMP222:%.*]] = zext i32 [[ADD70]] to i64 // CHECK9-NEXT: [[TMP223:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP223]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP223]], align 4 // CHECK9-NEXT: [[TMP224:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP224]], align 4 // CHECK9-NEXT: [[TMP225:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 2 @@ -7148,7 +7148,7 @@ int main() { // CHECK9-NEXT: [[ADD85:%.*]] = add nsw i32 [[TMP264]], 1 // CHECK9-NEXT: [[TMP265:%.*]] = zext i32 [[ADD85]] to i64 // CHECK9-NEXT: [[TMP266:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP266]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP266]], align 4 // CHECK9-NEXT: [[TMP267:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP267]], align 4 // CHECK9-NEXT: [[TMP268:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 2 @@ -8986,7 +8986,7 @@ int main() { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -9061,7 +9061,7 @@ int main() { // CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 [[TMP59]], 1 // CHECK11-NEXT: [[TMP60:%.*]] = zext i32 [[ADD13]] to i64 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP61]], align 4 // CHECK11-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP62]], align 4 // CHECK11-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -9145,7 +9145,7 @@ int main() { // CHECK11-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP102]], 1 // CHECK11-NEXT: [[TMP103:%.*]] = zext i32 [[ADD27]] to i64 // CHECK11-NEXT: [[TMP104:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP104]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP104]], align 4 // CHECK11-NEXT: [[TMP105:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP105]], align 4 // CHECK11-NEXT: [[TMP106:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -9220,7 +9220,7 @@ int main() { // CHECK11-NEXT: [[ADD41:%.*]] = add nsw i32 [[TMP140]], 1 // CHECK11-NEXT: [[TMP141:%.*]] = zext i32 [[ADD41]] to i64 // CHECK11-NEXT: [[TMP142:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP142]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP142]], align 4 // CHECK11-NEXT: [[TMP143:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP143]], align 4 // CHECK11-NEXT: [[TMP144:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 2 @@ -9304,7 +9304,7 @@ int main() { // CHECK11-NEXT: [[ADD56:%.*]] = add nsw i32 [[TMP183]], 1 // CHECK11-NEXT: [[TMP184:%.*]] = zext i32 [[ADD56]] to i64 // CHECK11-NEXT: [[TMP185:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP185]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP185]], align 4 // CHECK11-NEXT: [[TMP186:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP186]], align 4 // CHECK11-NEXT: [[TMP187:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 2 @@ -9379,7 +9379,7 @@ int main() { // CHECK11-NEXT: [[ADD70:%.*]] = add nsw i32 [[TMP221]], 1 // CHECK11-NEXT: [[TMP222:%.*]] = zext i32 [[ADD70]] to i64 // CHECK11-NEXT: [[TMP223:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP223]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP223]], align 4 // CHECK11-NEXT: [[TMP224:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP224]], align 4 // CHECK11-NEXT: [[TMP225:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 2 @@ -9463,7 +9463,7 @@ int main() { // CHECK11-NEXT: [[ADD85:%.*]] = add nsw i32 [[TMP264]], 1 // CHECK11-NEXT: [[TMP265:%.*]] = zext i32 [[ADD85]] to i64 // CHECK11-NEXT: [[TMP266:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP266]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP266]], align 4 // CHECK11-NEXT: [[TMP267:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP267]], align 4 // CHECK11-NEXT: [[TMP268:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 2 @@ -11234,7 +11234,7 @@ int main() { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -11309,7 +11309,7 @@ int main() { // CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 [[TMP59]], 1 // CHECK11-NEXT: [[TMP60:%.*]] = zext i32 [[ADD13]] to i64 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP61]], align 4 // CHECK11-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP62]], align 4 // CHECK11-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -11393,7 +11393,7 @@ int main() { // CHECK11-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP102]], 1 // CHECK11-NEXT: [[TMP103:%.*]] = zext i32 [[ADD27]] to i64 // CHECK11-NEXT: [[TMP104:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP104]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP104]], align 4 // CHECK11-NEXT: [[TMP105:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP105]], align 4 // CHECK11-NEXT: [[TMP106:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -11468,7 +11468,7 @@ int main() { // CHECK11-NEXT: [[ADD41:%.*]] = add nsw i32 [[TMP140]], 1 // CHECK11-NEXT: [[TMP141:%.*]] = zext i32 [[ADD41]] to i64 // CHECK11-NEXT: [[TMP142:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP142]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP142]], align 4 // CHECK11-NEXT: [[TMP143:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP143]], align 4 // CHECK11-NEXT: [[TMP144:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 2 @@ -11552,7 +11552,7 @@ int main() { // CHECK11-NEXT: [[ADD56:%.*]] = add nsw i32 [[TMP183]], 1 // CHECK11-NEXT: [[TMP184:%.*]] = zext i32 [[ADD56]] to i64 // CHECK11-NEXT: [[TMP185:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP185]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP185]], align 4 // CHECK11-NEXT: [[TMP186:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP186]], align 4 // CHECK11-NEXT: [[TMP187:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 2 @@ -11627,7 +11627,7 @@ int main() { // CHECK11-NEXT: [[ADD70:%.*]] = add nsw i32 [[TMP221]], 1 // CHECK11-NEXT: [[TMP222:%.*]] = zext i32 [[ADD70]] to i64 // CHECK11-NEXT: [[TMP223:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP223]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP223]], align 4 // CHECK11-NEXT: [[TMP224:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP224]], align 4 // CHECK11-NEXT: [[TMP225:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 2 @@ -11711,7 +11711,7 @@ int main() { // CHECK11-NEXT: [[ADD85:%.*]] = add nsw i32 [[TMP264]], 1 // CHECK11-NEXT: [[TMP265:%.*]] = zext i32 [[ADD85]] to i64 // CHECK11-NEXT: [[TMP266:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP266]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP266]], align 4 // CHECK11-NEXT: [[TMP267:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP267]], align 4 // CHECK11-NEXT: [[TMP268:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp index 6084a9a6cf93..faae599bb32a 100644 --- a/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp @@ -825,7 +825,7 @@ int main() { // CHECK8-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK8-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK8-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK8-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK8-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK8-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK8-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK8-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1251,7 +1251,7 @@ int main() { // CHECK8-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK8-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK8-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK8-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK8-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK8-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK8-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK8-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1744,7 +1744,7 @@ int main() { // CHECK10-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK10-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK10-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK10-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK10-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK10-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK10-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK10-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2164,7 +2164,7 @@ int main() { // CHECK10-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK10-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK10-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK10-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK10-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK10-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK10-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK10-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_if_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_if_codegen.cpp index d3b6654e57e2..4b3911daefba 100644 --- a/clang/test/OpenMP/distribute_parallel_for_if_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_if_codegen.cpp @@ -128,7 +128,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -161,7 +161,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -492,7 +492,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -525,7 +525,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -569,7 +569,7 @@ int main() { // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP38]], align 4 // CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -1060,7 +1060,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1093,7 +1093,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1137,7 +1137,7 @@ int main() { // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP38]], align 4 // CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp index 1f069c4070ae..18a86c5e5666 100644 --- a/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp @@ -801,7 +801,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1263,7 +1263,7 @@ int main() { // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1793,7 +1793,7 @@ int main() { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2249,7 +2249,7 @@ int main() { // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp index b6ae783b74d0..dfe79d6a9493 100644 --- a/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp @@ -116,7 +116,7 @@ int main() { // CHECK1: invoke.cont: // CHECK1-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -169,7 +169,7 @@ int main() { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -565,7 +565,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -598,7 +598,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -641,7 +641,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -674,7 +674,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1368,7 +1368,7 @@ int main() { // CHECK5: invoke.cont: // CHECK5-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1421,7 +1421,7 @@ int main() { // CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK5-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK5-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1817,7 +1817,7 @@ int main() { // CHECK5-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1850,7 +1850,7 @@ int main() { // CHECK5-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK5: omp_offload.cont: // CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1893,7 +1893,7 @@ int main() { // CHECK5-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1926,7 +1926,7 @@ int main() { // CHECK5-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK5: omp_offload.cont: // CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -2620,7 +2620,7 @@ int main() { // CHECK9: invoke.cont: // CHECK9-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2673,7 +2673,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -3069,7 +3069,7 @@ int main() { // CHECK9-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK9-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3102,7 +3102,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -3145,7 +3145,7 @@ int main() { // CHECK9-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK9-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3178,7 +3178,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -3872,7 +3872,7 @@ int main() { // CHECK13: invoke.cont: // CHECK13-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK13-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK13-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK13-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3925,7 +3925,7 @@ int main() { // CHECK13-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK13-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK13-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -4321,7 +4321,7 @@ int main() { // CHECK13-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK13-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK13-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK13-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4354,7 +4354,7 @@ int main() { // CHECK13-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK13: omp_offload.cont: // CHECK13-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK13-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK13-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK13-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -4397,7 +4397,7 @@ int main() { // CHECK13-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK13-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK13-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK13-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4430,7 +4430,7 @@ int main() { // CHECK13-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK13: omp_offload.cont: // CHECK13-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK13-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK13-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK13-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp index e2b0d64093eb..0969a0ca21e7 100644 --- a/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp @@ -521,7 +521,7 @@ int main() { // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -842,7 +842,7 @@ int main() { // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1232,7 +1232,7 @@ int main() { // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1547,7 +1547,7 @@ int main() { // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_proc_bind_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_proc_bind_codegen.cpp index 040f90b9ef78..c1203349b7c1 100644 --- a/clang/test/OpenMP/distribute_parallel_for_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_proc_bind_codegen.cpp @@ -63,7 +63,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -96,7 +96,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -414,7 +414,7 @@ int main() { // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_codegen.cpp index 77336877e2be..a23d538910ed 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_codegen.cpp @@ -4762,7 +4762,7 @@ int main() { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4837,7 +4837,7 @@ int main() { // CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 [[TMP59]], 1 // CHECK9-NEXT: [[TMP60:%.*]] = zext i32 [[ADD13]] to i64 // CHECK9-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP61]], align 4 // CHECK9-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP62]], align 4 // CHECK9-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -4921,7 +4921,7 @@ int main() { // CHECK9-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP102]], 1 // CHECK9-NEXT: [[TMP103:%.*]] = zext i32 [[ADD27]] to i64 // CHECK9-NEXT: [[TMP104:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP104]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP104]], align 4 // CHECK9-NEXT: [[TMP105:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP105]], align 4 // CHECK9-NEXT: [[TMP106:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -4996,7 +4996,7 @@ int main() { // CHECK9-NEXT: [[ADD41:%.*]] = add nsw i32 [[TMP140]], 1 // CHECK9-NEXT: [[TMP141:%.*]] = zext i32 [[ADD41]] to i64 // CHECK9-NEXT: [[TMP142:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP142]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP142]], align 4 // CHECK9-NEXT: [[TMP143:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP143]], align 4 // CHECK9-NEXT: [[TMP144:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 2 @@ -5080,7 +5080,7 @@ int main() { // CHECK9-NEXT: [[ADD56:%.*]] = add nsw i32 [[TMP183]], 1 // CHECK9-NEXT: [[TMP184:%.*]] = zext i32 [[ADD56]] to i64 // CHECK9-NEXT: [[TMP185:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP185]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP185]], align 4 // CHECK9-NEXT: [[TMP186:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP186]], align 4 // CHECK9-NEXT: [[TMP187:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 2 @@ -5155,7 +5155,7 @@ int main() { // CHECK9-NEXT: [[ADD70:%.*]] = add nsw i32 [[TMP221]], 1 // CHECK9-NEXT: [[TMP222:%.*]] = zext i32 [[ADD70]] to i64 // CHECK9-NEXT: [[TMP223:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP223]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP223]], align 4 // CHECK9-NEXT: [[TMP224:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP224]], align 4 // CHECK9-NEXT: [[TMP225:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 2 @@ -5239,7 +5239,7 @@ int main() { // CHECK9-NEXT: [[ADD85:%.*]] = add nsw i32 [[TMP264]], 1 // CHECK9-NEXT: [[TMP265:%.*]] = zext i32 [[ADD85]] to i64 // CHECK9-NEXT: [[TMP266:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP266]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP266]], align 4 // CHECK9-NEXT: [[TMP267:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP267]], align 4 // CHECK9-NEXT: [[TMP268:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 2 @@ -7229,7 +7229,7 @@ int main() { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7304,7 +7304,7 @@ int main() { // CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 [[TMP59]], 1 // CHECK9-NEXT: [[TMP60:%.*]] = zext i32 [[ADD13]] to i64 // CHECK9-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP61]], align 4 // CHECK9-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP62]], align 4 // CHECK9-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -7388,7 +7388,7 @@ int main() { // CHECK9-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP102]], 1 // CHECK9-NEXT: [[TMP103:%.*]] = zext i32 [[ADD27]] to i64 // CHECK9-NEXT: [[TMP104:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP104]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP104]], align 4 // CHECK9-NEXT: [[TMP105:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP105]], align 4 // CHECK9-NEXT: [[TMP106:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -7463,7 +7463,7 @@ int main() { // CHECK9-NEXT: [[ADD41:%.*]] = add nsw i32 [[TMP140]], 1 // CHECK9-NEXT: [[TMP141:%.*]] = zext i32 [[ADD41]] to i64 // CHECK9-NEXT: [[TMP142:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP142]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP142]], align 4 // CHECK9-NEXT: [[TMP143:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP143]], align 4 // CHECK9-NEXT: [[TMP144:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 2 @@ -7547,7 +7547,7 @@ int main() { // CHECK9-NEXT: [[ADD56:%.*]] = add nsw i32 [[TMP183]], 1 // CHECK9-NEXT: [[TMP184:%.*]] = zext i32 [[ADD56]] to i64 // CHECK9-NEXT: [[TMP185:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP185]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP185]], align 4 // CHECK9-NEXT: [[TMP186:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP186]], align 4 // CHECK9-NEXT: [[TMP187:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 2 @@ -7622,7 +7622,7 @@ int main() { // CHECK9-NEXT: [[ADD70:%.*]] = add nsw i32 [[TMP221]], 1 // CHECK9-NEXT: [[TMP222:%.*]] = zext i32 [[ADD70]] to i64 // CHECK9-NEXT: [[TMP223:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP223]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP223]], align 4 // CHECK9-NEXT: [[TMP224:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP224]], align 4 // CHECK9-NEXT: [[TMP225:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 2 @@ -7706,7 +7706,7 @@ int main() { // CHECK9-NEXT: [[ADD85:%.*]] = add nsw i32 [[TMP264]], 1 // CHECK9-NEXT: [[TMP265:%.*]] = zext i32 [[ADD85]] to i64 // CHECK9-NEXT: [[TMP266:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP266]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP266]], align 4 // CHECK9-NEXT: [[TMP267:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP267]], align 4 // CHECK9-NEXT: [[TMP268:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 2 @@ -9697,7 +9697,7 @@ int main() { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -9772,7 +9772,7 @@ int main() { // CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 [[TMP59]], 1 // CHECK11-NEXT: [[TMP60:%.*]] = zext i32 [[ADD13]] to i64 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP61]], align 4 // CHECK11-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP62]], align 4 // CHECK11-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -9856,7 +9856,7 @@ int main() { // CHECK11-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP102]], 1 // CHECK11-NEXT: [[TMP103:%.*]] = zext i32 [[ADD27]] to i64 // CHECK11-NEXT: [[TMP104:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP104]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP104]], align 4 // CHECK11-NEXT: [[TMP105:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP105]], align 4 // CHECK11-NEXT: [[TMP106:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -9931,7 +9931,7 @@ int main() { // CHECK11-NEXT: [[ADD41:%.*]] = add nsw i32 [[TMP140]], 1 // CHECK11-NEXT: [[TMP141:%.*]] = zext i32 [[ADD41]] to i64 // CHECK11-NEXT: [[TMP142:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP142]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP142]], align 4 // CHECK11-NEXT: [[TMP143:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP143]], align 4 // CHECK11-NEXT: [[TMP144:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 2 @@ -10015,7 +10015,7 @@ int main() { // CHECK11-NEXT: [[ADD56:%.*]] = add nsw i32 [[TMP183]], 1 // CHECK11-NEXT: [[TMP184:%.*]] = zext i32 [[ADD56]] to i64 // CHECK11-NEXT: [[TMP185:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP185]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP185]], align 4 // CHECK11-NEXT: [[TMP186:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP186]], align 4 // CHECK11-NEXT: [[TMP187:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 2 @@ -10090,7 +10090,7 @@ int main() { // CHECK11-NEXT: [[ADD70:%.*]] = add nsw i32 [[TMP221]], 1 // CHECK11-NEXT: [[TMP222:%.*]] = zext i32 [[ADD70]] to i64 // CHECK11-NEXT: [[TMP223:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP223]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP223]], align 4 // CHECK11-NEXT: [[TMP224:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP224]], align 4 // CHECK11-NEXT: [[TMP225:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 2 @@ -10174,7 +10174,7 @@ int main() { // CHECK11-NEXT: [[ADD85:%.*]] = add nsw i32 [[TMP264]], 1 // CHECK11-NEXT: [[TMP265:%.*]] = zext i32 [[ADD85]] to i64 // CHECK11-NEXT: [[TMP266:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP266]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP266]], align 4 // CHECK11-NEXT: [[TMP267:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP267]], align 4 // CHECK11-NEXT: [[TMP268:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 2 @@ -12113,7 +12113,7 @@ int main() { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -12188,7 +12188,7 @@ int main() { // CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 [[TMP59]], 1 // CHECK11-NEXT: [[TMP60:%.*]] = zext i32 [[ADD13]] to i64 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP61]], align 4 // CHECK11-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP62]], align 4 // CHECK11-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -12272,7 +12272,7 @@ int main() { // CHECK11-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP102]], 1 // CHECK11-NEXT: [[TMP103:%.*]] = zext i32 [[ADD27]] to i64 // CHECK11-NEXT: [[TMP104:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP104]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP104]], align 4 // CHECK11-NEXT: [[TMP105:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP105]], align 4 // CHECK11-NEXT: [[TMP106:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -12347,7 +12347,7 @@ int main() { // CHECK11-NEXT: [[ADD41:%.*]] = add nsw i32 [[TMP140]], 1 // CHECK11-NEXT: [[TMP141:%.*]] = zext i32 [[ADD41]] to i64 // CHECK11-NEXT: [[TMP142:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP142]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP142]], align 4 // CHECK11-NEXT: [[TMP143:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP143]], align 4 // CHECK11-NEXT: [[TMP144:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS42]], i32 0, i32 2 @@ -12431,7 +12431,7 @@ int main() { // CHECK11-NEXT: [[ADD56:%.*]] = add nsw i32 [[TMP183]], 1 // CHECK11-NEXT: [[TMP184:%.*]] = zext i32 [[ADD56]] to i64 // CHECK11-NEXT: [[TMP185:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP185]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP185]], align 4 // CHECK11-NEXT: [[TMP186:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP186]], align 4 // CHECK11-NEXT: [[TMP187:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS57]], i32 0, i32 2 @@ -12506,7 +12506,7 @@ int main() { // CHECK11-NEXT: [[ADD70:%.*]] = add nsw i32 [[TMP221]], 1 // CHECK11-NEXT: [[TMP222:%.*]] = zext i32 [[ADD70]] to i64 // CHECK11-NEXT: [[TMP223:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP223]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP223]], align 4 // CHECK11-NEXT: [[TMP224:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP224]], align 4 // CHECK11-NEXT: [[TMP225:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS71]], i32 0, i32 2 @@ -12590,7 +12590,7 @@ int main() { // CHECK11-NEXT: [[ADD85:%.*]] = add nsw i32 [[TMP264]], 1 // CHECK11-NEXT: [[TMP265:%.*]] = zext i32 [[ADD85]] to i64 // CHECK11-NEXT: [[TMP266:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP266]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP266]], align 4 // CHECK11-NEXT: [[TMP267:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP267]], align 4 // CHECK11-NEXT: [[TMP268:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS86]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp index f47b64b1e299..545ea9f0f43f 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp @@ -888,7 +888,7 @@ int main() { // CHECK8-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK8-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK8-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK8-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK8-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK8-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK8-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK8-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1328,7 +1328,7 @@ int main() { // CHECK8-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK8-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK8-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK8-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK8-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK8-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK8-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK8-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1835,7 +1835,7 @@ int main() { // CHECK10-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK10-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK10-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK10-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK10-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK10-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK10-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK10-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2269,7 +2269,7 @@ int main() { // CHECK10-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK10-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK10-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK10-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK10-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK10-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK10-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK10-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp index b3e964fddcf0..4a321b24b8c3 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_if_codegen.cpp @@ -125,7 +125,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -158,7 +158,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -517,7 +517,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -550,7 +550,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -594,7 +594,7 @@ int main() { // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP38]], align 4 // CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -1127,7 +1127,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1160,7 +1160,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1204,7 +1204,7 @@ int main() { // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP38]], align 4 // CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -1727,7 +1727,7 @@ int main() { // CHECK3-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1760,7 +1760,7 @@ int main() { // CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK3: omp_offload.cont: // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -2119,7 +2119,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2152,7 +2152,7 @@ int main() { // CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK3: omp_offload.cont: // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -2196,7 +2196,7 @@ int main() { // CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP38]], align 4 // CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -2964,7 +2964,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK3-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2997,7 +2997,7 @@ int main() { // CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK3: omp_offload.cont: // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -3041,7 +3041,7 @@ int main() { // CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP38]], align 4 // CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -4140,7 +4140,7 @@ int main() { // CHECK9-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK9-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4173,7 +4173,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -4532,7 +4532,7 @@ int main() { // CHECK9-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4565,7 +4565,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -4609,7 +4609,7 @@ int main() { // CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP38]], align 4 // CHECK9-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -5142,7 +5142,7 @@ int main() { // CHECK9-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5175,7 +5175,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -5219,7 +5219,7 @@ int main() { // CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP38]], align 4 // CHECK9-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -5742,7 +5742,7 @@ int main() { // CHECK11-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK11-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5775,7 +5775,7 @@ int main() { // CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK11: omp_offload.cont: // CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -6134,7 +6134,7 @@ int main() { // CHECK11-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK11-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6167,7 +6167,7 @@ int main() { // CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK11: omp_offload.cont: // CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -6211,7 +6211,7 @@ int main() { // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK11-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP38]], align 4 // CHECK11-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -6979,7 +6979,7 @@ int main() { // CHECK11-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK11-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7012,7 +7012,7 @@ int main() { // CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK11: omp_offload.cont: // CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -7056,7 +7056,7 @@ int main() { // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK11-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP38]], align 4 // CHECK11-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp index 7656fb7bc2c5..675f1313460e 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp @@ -868,7 +868,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1344,7 +1344,7 @@ int main() { // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1888,7 +1888,7 @@ int main() { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2358,7 +2358,7 @@ int main() { // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp index 9f4fffbea63d..5c1ca41b1c62 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp @@ -116,7 +116,7 @@ int main() { // CHECK1: invoke.cont: // CHECK1-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -169,7 +169,7 @@ int main() { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -593,7 +593,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -626,7 +626,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -669,7 +669,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -702,7 +702,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1791,7 +1791,7 @@ int main() { // CHECK5: invoke.cont: // CHECK5-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1844,7 +1844,7 @@ int main() { // CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK5-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK5-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -2268,7 +2268,7 @@ int main() { // CHECK5-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2301,7 +2301,7 @@ int main() { // CHECK5-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK5: omp_offload.cont: // CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -2344,7 +2344,7 @@ int main() { // CHECK5-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2377,7 +2377,7 @@ int main() { // CHECK5-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK5: omp_offload.cont: // CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -3127,7 +3127,7 @@ int main() { // CHECK9: invoke.cont: // CHECK9-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3180,7 +3180,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -3604,7 +3604,7 @@ int main() { // CHECK9-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK9-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3637,7 +3637,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -3680,7 +3680,7 @@ int main() { // CHECK9-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK9-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3713,7 +3713,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -4802,7 +4802,7 @@ int main() { // CHECK13: invoke.cont: // CHECK13-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK13-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK13-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK13-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4855,7 +4855,7 @@ int main() { // CHECK13-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK13-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK13-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -5279,7 +5279,7 @@ int main() { // CHECK13-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK13-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK13-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK13-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5312,7 +5312,7 @@ int main() { // CHECK13-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK13: omp_offload.cont: // CHECK13-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK13-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK13-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK13-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -5355,7 +5355,7 @@ int main() { // CHECK13-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK13-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK13-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK13-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK13-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5388,7 +5388,7 @@ int main() { // CHECK13-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK13: omp_offload.cont: // CHECK13-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK13-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK13-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK13-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp index 61f35d8b456c..a74af2d7c393 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp @@ -575,7 +575,7 @@ int main() { // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -910,7 +910,7 @@ int main() { // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1314,7 +1314,7 @@ int main() { // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1643,7 +1643,7 @@ int main() { // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp index 334965f59a82..777d4a25ea9f 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_proc_bind_codegen.cpp @@ -63,7 +63,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -96,7 +96,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -442,7 +442,7 @@ int main() { // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_private_codegen.cpp b/clang/test/OpenMP/distribute_private_codegen.cpp index 8a47b15a24d2..b6e796fb8027 100644 --- a/clang/test/OpenMP/distribute_private_codegen.cpp +++ b/clang/test/OpenMP/distribute_private_codegen.cpp @@ -351,7 +351,7 @@ int main() { // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -384,7 +384,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 2 @@ -668,7 +668,7 @@ int main() { // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -957,7 +957,7 @@ int main() { // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -990,7 +990,7 @@ int main() { // CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK11: omp_offload.cont: // CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 2 @@ -1272,7 +1272,7 @@ int main() { // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_simd_codegen.cpp b/clang/test/OpenMP/distribute_simd_codegen.cpp index 16d909e32951..9a192502125f 100644 --- a/clang/test/OpenMP/distribute_simd_codegen.cpp +++ b/clang/test/OpenMP/distribute_simd_codegen.cpp @@ -191,7 +191,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -391,7 +391,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -589,7 +589,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -806,7 +806,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], 1 // CHECK1-NEXT: [[TMP15:%.*]] = zext i32 [[ADD4]] to i64 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -996,7 +996,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1176,7 +1176,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1372,7 +1372,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1566,7 +1566,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1779,7 +1779,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], 1 // CHECK3-NEXT: [[TMP15:%.*]] = zext i32 [[ADD4]] to i64 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP17]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1969,7 +1969,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2149,7 +2149,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK5-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2349,7 +2349,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK5-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2547,7 +2547,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK5-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2764,7 +2764,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK5-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], 1 // CHECK5-NEXT: [[TMP15:%.*]] = zext i32 [[ADD4]] to i64 // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 2, ptr [[TMP17]], align 4 // CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2985,7 +2985,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK5-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK5-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3165,7 +3165,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK7-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK7-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK7-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3361,7 +3361,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK7-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK7-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK7-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3555,7 +3555,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK7-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK7-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK7-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3768,7 +3768,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK7-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], 1 // CHECK7-NEXT: [[TMP15:%.*]] = zext i32 [[ADD4]] to i64 // CHECK7-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK7-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 2, ptr [[TMP17]], align 4 // CHECK7-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3989,7 +3989,7 @@ int fint(void) { return ftemplate<int>(); } // CHECK7-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK7-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK7-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/distribute_simd_firstprivate_codegen.cpp index e388393c37f1..1b5950ce11d7 100644 --- a/clang/test/OpenMP/distribute_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_simd_firstprivate_codegen.cpp @@ -595,7 +595,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -898,7 +898,7 @@ int main() { // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1274,7 +1274,7 @@ int main() { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1575,7 +1575,7 @@ int main() { // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/distribute_simd_lastprivate_codegen.cpp index 5720c3aaaaff..92b73b220bcc 100644 --- a/clang/test/OpenMP/distribute_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/distribute_simd_lastprivate_codegen.cpp @@ -582,7 +582,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -903,7 +903,7 @@ int main() { // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1298,7 +1298,7 @@ int main() { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1617,7 +1617,7 @@ int main() { // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_simd_private_codegen.cpp b/clang/test/OpenMP/distribute_simd_private_codegen.cpp index eac5bce7d5da..93b2bd8b12a8 100644 --- a/clang/test/OpenMP/distribute_simd_private_codegen.cpp +++ b/clang/test/OpenMP/distribute_simd_private_codegen.cpp @@ -396,7 +396,7 @@ int main() { // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -440,7 +440,7 @@ int main() { // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP22]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 2 @@ -742,7 +742,7 @@ int main() { // CHECK9-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK9-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1042,7 +1042,7 @@ int main() { // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1086,7 +1086,7 @@ int main() { // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP22]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS3]], i32 0, i32 2 @@ -1386,7 +1386,7 @@ int main() { // CHECK11-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK11-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/distribute_simd_reduction_codegen.cpp b/clang/test/OpenMP/distribute_simd_reduction_codegen.cpp index 31d276e984ee..b6cc1adfc76b 100644 --- a/clang/test/OpenMP/distribute_simd_reduction_codegen.cpp +++ b/clang/test/OpenMP/distribute_simd_reduction_codegen.cpp @@ -105,7 +105,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -255,7 +255,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -402,7 +402,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -552,7 +552,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/map_struct_ordering.cpp b/clang/test/OpenMP/map_struct_ordering.cpp index dd0bb8e9d6e7..e422010f3dcd 100644 --- a/clang/test/OpenMP/map_struct_ordering.cpp +++ b/clang/test/OpenMP/map_struct_ordering.cpp @@ -97,7 +97,7 @@ int map_struct() { // CHECK-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS4]], i32 0, i32 0 // CHECK-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS5]], i32 0, i32 0 // CHECK-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP24]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP25]], align 4 // CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/nvptx_lambda_capturing.cpp b/clang/test/OpenMP/nvptx_lambda_capturing.cpp index 5d7da793e732..86035e17ef3b 100644 --- a/clang/test/OpenMP/nvptx_lambda_capturing.cpp +++ b/clang/test/OpenMP/nvptx_lambda_capturing.cpp @@ -191,7 +191,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds [11 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds [11 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP66]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP66]], align 4 // CHECK1-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 11, ptr [[TMP67]], align 4 // CHECK1-NEXT: [[TMP68:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -317,7 +317,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP136:%.*]] = getelementptr inbounds [11 x ptr], ptr [[DOTOFFLOAD_BASEPTRS7]], i32 0, i32 0 // CHECK1-NEXT: [[TMP137:%.*]] = getelementptr inbounds [11 x ptr], ptr [[DOTOFFLOAD_PTRS8]], i32 0, i32 0 // CHECK1-NEXT: [[TMP138:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP138]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP138]], align 4 // CHECK1-NEXT: [[TMP139:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 1 // CHECK1-NEXT: store i32 11, ptr [[TMP139]], align 4 // CHECK1-NEXT: [[TMP140:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 2 @@ -541,7 +541,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -599,7 +599,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP46]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP47]], align 4 // CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -744,7 +744,7 @@ int main(int argc, char **argv) { // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP12]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP12]], align 4 // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP13]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/reduction_implicit_map.cpp b/clang/test/OpenMP/reduction_implicit_map.cpp index 7305c56289e0..0f67cdc56ddc 100644 --- a/clang/test/OpenMP/reduction_implicit_map.cpp +++ b/clang/test/OpenMP/reduction_implicit_map.cpp @@ -318,7 +318,7 @@ int main() // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -359,7 +359,7 @@ int main() // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 2 @@ -890,7 +890,7 @@ int main() // CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP26]], 1 // CHECK2-NEXT: [[TMP27:%.*]] = zext i32 [[ADD]] to i64 // CHECK2-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK2-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK2-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -971,7 +971,7 @@ int main() // CHECK2-NEXT: [[ADD17:%.*]] = add nsw i32 [[TMP69]], 1 // CHECK2-NEXT: [[TMP70:%.*]] = zext i32 [[ADD17]] to i64 // CHECK2-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP71]], align 4 // CHECK2-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 1 // CHECK2-NEXT: store i32 3, ptr [[TMP72]], align 4 // CHECK2-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 2 @@ -1022,7 +1022,7 @@ int main() // CHECK2-NEXT: [[TMP94:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS23]], i32 0, i32 0 // CHECK2-NEXT: [[TMP95:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS24]], i32 0, i32 0 // CHECK2-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP96]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP96]], align 4 // CHECK2-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 1 // CHECK2-NEXT: store i32 2, ptr [[TMP97]], align 4 // CHECK2-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 2 @@ -1073,7 +1073,7 @@ int main() // CHECK2-NEXT: [[TMP119:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS31]], i32 0, i32 0 // CHECK2-NEXT: [[TMP120:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS32]], i32 0, i32 0 // CHECK2-NEXT: [[TMP121:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS34]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP121]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP121]], align 4 // CHECK2-NEXT: [[TMP122:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS34]], i32 0, i32 1 // CHECK2-NEXT: store i32 2, ptr [[TMP122]], align 4 // CHECK2-NEXT: [[TMP123:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS34]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_codegen_global_capture.cpp b/clang/test/OpenMP/target_codegen_global_capture.cpp index 0fb52c3fa6c5..d2c800a56a10 100644 --- a/clang/test/OpenMP/target_codegen_global_capture.cpp +++ b/clang/test/OpenMP/target_codegen_global_capture.cpp @@ -288,7 +288,7 @@ int tbar2(short a, short b, short c, short d){ // CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK1-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 9, ptr [[TMP51]], align 4 // CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -615,7 +615,7 @@ int tbar2(short a, short b, short c, short d){ // CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP53:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP54]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP54]], align 4 // CHECK1-NEXT: [[TMP55:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 9, ptr [[TMP55]], align 4 // CHECK1-NEXT: [[TMP56:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -938,7 +938,7 @@ int tbar2(short a, short b, short c, short d){ // CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP53:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP54]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP54]], align 4 // CHECK1-NEXT: [[TMP55:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 9, ptr [[TMP55]], align 4 // CHECK1-NEXT: [[TMP56:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1184,7 +1184,7 @@ int tbar2(short a, short b, short c, short d){ // CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP44]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP44]], align 4 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 9, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1511,7 +1511,7 @@ int tbar2(short a, short b, short c, short d){ // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP48]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP48]], align 4 // CHECK3-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 9, ptr [[TMP49]], align 4 // CHECK3-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1834,7 +1834,7 @@ int tbar2(short a, short b, short c, short d){ // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP48]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP48]], align 4 // CHECK3-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 9, ptr [[TMP49]], align 4 // CHECK3-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_firstprivate_codegen.cpp b/clang/test/OpenMP/target_firstprivate_codegen.cpp index 631494073047..02de48e6aa39 100644 --- a/clang/test/OpenMP/target_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/target_firstprivate_codegen.cpp @@ -6159,7 +6159,7 @@ int bar(int n, double *ptr) { // CHECK0-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK0-NEXT: [[TMP23:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK0-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK0-NEXT: store i32 2, ptr [[TMP24]], align 4 +// CHECK0-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK0-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK0-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK0-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6260,7 +6260,7 @@ int bar(int n, double *ptr) { // CHECK0-NEXT: [[TMP74:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK0-NEXT: [[TMP75:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK0-NEXT: [[TMP76:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK0-NEXT: store i32 2, ptr [[TMP76]], align 4 +// CHECK0-NEXT: store i32 3, ptr [[TMP76]], align 4 // CHECK0-NEXT: [[TMP77:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK0-NEXT: store i32 9, ptr [[TMP77]], align 4 // CHECK0-NEXT: [[TMP78:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -6308,7 +6308,7 @@ int bar(int n, double *ptr) { // CHECK0-NEXT: [[TMP98:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK0-NEXT: [[TMP99:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK0-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 0 -// CHECK0-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK0-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK0-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 1 // CHECK0-NEXT: store i32 2, ptr [[TMP101]], align 4 // CHECK0-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 2 @@ -6564,7 +6564,7 @@ int bar(int n, double *ptr) { // CHECK0-NEXT: [[TMP26:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK0-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK0-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK0-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK0-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK0-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK0-NEXT: store i32 5, ptr [[TMP29]], align 4 // CHECK0-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6651,7 +6651,7 @@ int bar(int n, double *ptr) { // CHECK0-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK0-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK0-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK0-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK0-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK0-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK0-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK0-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6718,7 +6718,7 @@ int bar(int n, double *ptr) { // CHECK0-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK0-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK0-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK0-NEXT: store i32 2, ptr [[TMP10]], align 4 +// CHECK0-NEXT: store i32 3, ptr [[TMP10]], align 4 // CHECK0-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK0-NEXT: store i32 2, ptr [[TMP11]], align 4 // CHECK0-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6930,7 +6930,7 @@ int bar(int n, double *ptr) { // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP24]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7031,7 +7031,7 @@ int bar(int n, double *ptr) { // CHECK1-NEXT: [[TMP74:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP75:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP76:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP76]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP76]], align 4 // CHECK1-NEXT: [[TMP77:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK1-NEXT: store i32 9, ptr [[TMP77]], align 4 // CHECK1-NEXT: [[TMP78:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -7079,7 +7079,7 @@ int bar(int n, double *ptr) { // CHECK1-NEXT: [[TMP98:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK1-NEXT: [[TMP99:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK1-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK1-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP101]], align 4 // CHECK1-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 2 @@ -7335,7 +7335,7 @@ int bar(int n, double *ptr) { // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7422,7 +7422,7 @@ int bar(int n, double *ptr) { // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7489,7 +7489,7 @@ int bar(int n, double *ptr) { // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP10]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP10]], align 4 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP11]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7699,7 +7699,7 @@ int bar(int n, double *ptr) { // CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK2-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK2-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP22]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK2-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK2-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7802,7 +7802,7 @@ int bar(int n, double *ptr) { // CHECK2-NEXT: [[TMP74:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK2-NEXT: [[TMP75:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK2-NEXT: [[TMP76:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP76]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP76]], align 4 // CHECK2-NEXT: [[TMP77:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK2-NEXT: store i32 9, ptr [[TMP77]], align 4 // CHECK2-NEXT: [[TMP78:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -7850,7 +7850,7 @@ int bar(int n, double *ptr) { // CHECK2-NEXT: [[TMP98:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK2-NEXT: [[TMP99:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK2-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK2-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 1 // CHECK2-NEXT: store i32 2, ptr [[TMP101]], align 4 // CHECK2-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 2 @@ -8106,7 +8106,7 @@ int bar(int n, double *ptr) { // CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK2-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK2-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK2-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK2-NEXT: store i32 5, ptr [[TMP29]], align 4 // CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -8193,7 +8193,7 @@ int bar(int n, double *ptr) { // CHECK2-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK2-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK2-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK2-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK2-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -8260,7 +8260,7 @@ int bar(int n, double *ptr) { // CHECK2-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK2-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP10]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP10]], align 4 // CHECK2-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK2-NEXT: store i32 2, ptr [[TMP11]], align 4 // CHECK2-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -8470,7 +8470,7 @@ int bar(int n, double *ptr) { // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP22]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -8573,7 +8573,7 @@ int bar(int n, double *ptr) { // CHECK3-NEXT: [[TMP74:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP75:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP76:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP76]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP76]], align 4 // CHECK3-NEXT: [[TMP77:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK3-NEXT: store i32 9, ptr [[TMP77]], align 4 // CHECK3-NEXT: [[TMP78:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -8621,7 +8621,7 @@ int bar(int n, double *ptr) { // CHECK3-NEXT: [[TMP98:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK3-NEXT: [[TMP99:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK3-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK3-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP101]], align 4 // CHECK3-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS11]], i32 0, i32 2 @@ -8877,7 +8877,7 @@ int bar(int n, double *ptr) { // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -8964,7 +8964,7 @@ int bar(int n, double *ptr) { // CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -9031,7 +9031,7 @@ int bar(int n, double *ptr) { // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP10]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP10]], align 4 // CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP11]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_has_device_addr_codegen.cpp b/clang/test/OpenMP/target_has_device_addr_codegen.cpp index e6a0e7bb38d6..ba1b618ed8bd 100644 --- a/clang/test/OpenMP/target_has_device_addr_codegen.cpp +++ b/clang/test/OpenMP/target_has_device_addr_codegen.cpp @@ -328,7 +328,7 @@ void use_template() { // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP6]], align 4 // CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP7]], align 4 // CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -372,7 +372,7 @@ void use_template() { // CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP29]], align 4 // CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 2 @@ -413,7 +413,7 @@ void use_template() { // CHECK-NEXT: [[TMP46:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS7]], i32 0, i32 0 // CHECK-NEXT: [[TMP47:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS8]], i32 0, i32 0 // CHECK-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP48]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP48]], align 4 // CHECK-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP49]], align 4 // CHECK-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 2 @@ -457,7 +457,7 @@ void use_template() { // CHECK-NEXT: [[TMP68:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS14]], i32 0, i32 0 // CHECK-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS15]], i32 0, i32 0 // CHECK-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP70]], align 4 // CHECK-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP71]], align 4 // CHECK-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 2 @@ -498,7 +498,7 @@ void use_template() { // CHECK-NEXT: [[TMP88:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS20]], i32 0, i32 0 // CHECK-NEXT: [[TMP89:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS21]], i32 0, i32 0 // CHECK-NEXT: [[TMP90:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP90]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP90]], align 4 // CHECK-NEXT: [[TMP91:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP91]], align 4 // CHECK-NEXT: [[TMP92:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -539,7 +539,7 @@ void use_template() { // CHECK-NEXT: [[TMP108:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS26]], i32 0, i32 0 // CHECK-NEXT: [[TMP109:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS27]], i32 0, i32 0 // CHECK-NEXT: [[TMP110:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS29]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP110]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP110]], align 4 // CHECK-NEXT: [[TMP111:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS29]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP111]], align 4 // CHECK-NEXT: [[TMP112:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS29]], i32 0, i32 2 @@ -705,7 +705,7 @@ void use_template() { // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP6]], align 4 // CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP7]], align 4 // CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -749,7 +749,7 @@ void use_template() { // CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP29]], align 4 // CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 2 @@ -790,7 +790,7 @@ void use_template() { // CHECK-NEXT: [[TMP46:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS7]], i32 0, i32 0 // CHECK-NEXT: [[TMP47:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS8]], i32 0, i32 0 // CHECK-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP48]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP48]], align 4 // CHECK-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP49]], align 4 // CHECK-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 2 @@ -831,7 +831,7 @@ void use_template() { // CHECK-NEXT: [[TMP66:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS13]], i32 0, i32 0 // CHECK-NEXT: [[TMP67:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS14]], i32 0, i32 0 // CHECK-NEXT: [[TMP68:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP68]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP68]], align 4 // CHECK-NEXT: [[TMP69:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP69]], align 4 // CHECK-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 2 @@ -911,7 +911,7 @@ void use_template() { // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP6]], align 4 // CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP7]], align 4 // CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -955,7 +955,7 @@ void use_template() { // CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP29]], align 4 // CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 2 @@ -996,7 +996,7 @@ void use_template() { // CHECK-NEXT: [[TMP46:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS7]], i32 0, i32 0 // CHECK-NEXT: [[TMP47:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS8]], i32 0, i32 0 // CHECK-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP48]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP48]], align 4 // CHECK-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP49]], align 4 // CHECK-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 2 @@ -1037,7 +1037,7 @@ void use_template() { // CHECK-NEXT: [[TMP66:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS13]], i32 0, i32 0 // CHECK-NEXT: [[TMP67:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS14]], i32 0, i32 0 // CHECK-NEXT: [[TMP68:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP68]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP68]], align 4 // CHECK-NEXT: [[TMP69:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP69]], align 4 // CHECK-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 2 @@ -1239,7 +1239,7 @@ void use_template() { // CHECK-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK-NEXT: [[TMP20:%.*]] = sext i32 [[TMP19]] to i64 // CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_has_device_addr_codegen_01.cpp b/clang/test/OpenMP/target_has_device_addr_codegen_01.cpp index efd0a1ee88fe..6bbabdf51f6e 100644 --- a/clang/test/OpenMP/target_has_device_addr_codegen_01.cpp +++ b/clang/test/OpenMP/target_has_device_addr_codegen_01.cpp @@ -102,7 +102,7 @@ int main() { // CHECK-NEXT: [[TMP24:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP25:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP26]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP26]], align 4 // CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 6, ptr [[TMP27]], align 4 // CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -211,7 +211,7 @@ int main() { // CHECK-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_is_device_ptr_codegen.cpp b/clang/test/OpenMP/target_is_device_ptr_codegen.cpp index 162f18529a48..190032023aed 100644 --- a/clang/test/OpenMP/target_is_device_ptr_codegen.cpp +++ b/clang/test/OpenMP/target_is_device_ptr_codegen.cpp @@ -1827,7 +1827,7 @@ void bar() { // CK10-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK10-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK10-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK10-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CK10-NEXT: store i32 3, ptr [[TMP6]], align 4 // CK10-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK10-NEXT: store i32 1, ptr [[TMP7]], align 4 // CK10-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1869,7 +1869,7 @@ void bar() { // CK10-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CK10-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CK10-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 0 -// CK10-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CK10-NEXT: store i32 3, ptr [[TMP27]], align 4 // CK10-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 1 // CK10-NEXT: store i32 1, ptr [[TMP28]], align 4 // CK10-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 2 @@ -1911,7 +1911,7 @@ void bar() { // CK10-NEXT: [[TMP46:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS7]], i32 0, i32 0 // CK10-NEXT: [[TMP47:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS8]], i32 0, i32 0 // CK10-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 0 -// CK10-NEXT: store i32 2, ptr [[TMP48]], align 4 +// CK10-NEXT: store i32 3, ptr [[TMP48]], align 4 // CK10-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 1 // CK10-NEXT: store i32 1, ptr [[TMP49]], align 4 // CK10-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 2 @@ -1956,7 +1956,7 @@ void bar() { // CK10-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS13]], i32 0, i32 0 // CK10-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS14]], i32 0, i32 0 // CK10-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 0 -// CK10-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CK10-NEXT: store i32 3, ptr [[TMP71]], align 4 // CK10-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 1 // CK10-NEXT: store i32 1, ptr [[TMP72]], align 4 // CK10-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 2 @@ -2001,7 +2001,7 @@ void bar() { // CK10-NEXT: [[TMP92:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS20]], i32 0, i32 0 // CK10-NEXT: [[TMP93:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS21]], i32 0, i32 0 // CK10-NEXT: [[TMP94:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CK10-NEXT: store i32 2, ptr [[TMP94]], align 4 +// CK10-NEXT: store i32 3, ptr [[TMP94]], align 4 // CK10-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CK10-NEXT: store i32 1, ptr [[TMP95]], align 4 // CK10-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -2046,7 +2046,7 @@ void bar() { // CK10-NEXT: [[TMP115:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CK10-NEXT: [[TMP116:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CK10-NEXT: [[TMP117:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CK10-NEXT: store i32 2, ptr [[TMP117]], align 4 +// CK10-NEXT: store i32 3, ptr [[TMP117]], align 4 // CK10-NEXT: [[TMP118:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CK10-NEXT: store i32 1, ptr [[TMP118]], align 4 // CK10-NEXT: [[TMP119:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -2101,7 +2101,7 @@ void bar() { // CK10-NEXT: [[TMP144:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS35]], i32 0, i32 0 // CK10-NEXT: [[TMP145:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS36]], i32 0, i32 0 // CK10-NEXT: [[TMP146:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 0 -// CK10-NEXT: store i32 2, ptr [[TMP146]], align 4 +// CK10-NEXT: store i32 3, ptr [[TMP146]], align 4 // CK10-NEXT: [[TMP147:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 1 // CK10-NEXT: store i32 2, ptr [[TMP147]], align 4 // CK10-NEXT: [[TMP148:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 2 @@ -2298,7 +2298,7 @@ void bar() { // CK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK11-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CK11-NEXT: store i32 3, ptr [[TMP6]], align 4 // CK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK11-NEXT: store i32 1, ptr [[TMP7]], align 4 // CK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2340,7 +2340,7 @@ void bar() { // CK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 0 -// CK11-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CK11-NEXT: store i32 3, ptr [[TMP27]], align 4 // CK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 1 // CK11-NEXT: store i32 1, ptr [[TMP28]], align 4 // CK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 2 @@ -2382,7 +2382,7 @@ void bar() { // CK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS7]], i32 0, i32 0 // CK11-NEXT: [[TMP47:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS8]], i32 0, i32 0 // CK11-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 0 -// CK11-NEXT: store i32 2, ptr [[TMP48]], align 4 +// CK11-NEXT: store i32 3, ptr [[TMP48]], align 4 // CK11-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 1 // CK11-NEXT: store i32 1, ptr [[TMP49]], align 4 // CK11-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 2 @@ -2427,7 +2427,7 @@ void bar() { // CK11-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS13]], i32 0, i32 0 // CK11-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS14]], i32 0, i32 0 // CK11-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 0 -// CK11-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CK11-NEXT: store i32 3, ptr [[TMP71]], align 4 // CK11-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 1 // CK11-NEXT: store i32 1, ptr [[TMP72]], align 4 // CK11-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 2 @@ -2472,7 +2472,7 @@ void bar() { // CK11-NEXT: [[TMP92:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS20]], i32 0, i32 0 // CK11-NEXT: [[TMP93:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS21]], i32 0, i32 0 // CK11-NEXT: [[TMP94:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CK11-NEXT: store i32 2, ptr [[TMP94]], align 4 +// CK11-NEXT: store i32 3, ptr [[TMP94]], align 4 // CK11-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CK11-NEXT: store i32 1, ptr [[TMP95]], align 4 // CK11-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -2517,7 +2517,7 @@ void bar() { // CK11-NEXT: [[TMP115:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CK11-NEXT: [[TMP116:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CK11-NEXT: [[TMP117:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CK11-NEXT: store i32 2, ptr [[TMP117]], align 4 +// CK11-NEXT: store i32 3, ptr [[TMP117]], align 4 // CK11-NEXT: [[TMP118:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CK11-NEXT: store i32 1, ptr [[TMP118]], align 4 // CK11-NEXT: [[TMP119:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -2572,7 +2572,7 @@ void bar() { // CK11-NEXT: [[TMP144:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS35]], i32 0, i32 0 // CK11-NEXT: [[TMP145:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS36]], i32 0, i32 0 // CK11-NEXT: [[TMP146:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 0 -// CK11-NEXT: store i32 2, ptr [[TMP146]], align 4 +// CK11-NEXT: store i32 3, ptr [[TMP146]], align 4 // CK11-NEXT: [[TMP147:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 1 // CK11-NEXT: store i32 2, ptr [[TMP147]], align 4 // CK11-NEXT: [[TMP148:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 2 @@ -2769,7 +2769,7 @@ void bar() { // CK12-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK12-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK12-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK12-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CK12-NEXT: store i32 3, ptr [[TMP6]], align 4 // CK12-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK12-NEXT: store i32 1, ptr [[TMP7]], align 4 // CK12-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2811,7 +2811,7 @@ void bar() { // CK12-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CK12-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CK12-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 0 -// CK12-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CK12-NEXT: store i32 3, ptr [[TMP27]], align 4 // CK12-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 1 // CK12-NEXT: store i32 1, ptr [[TMP28]], align 4 // CK12-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 2 @@ -2853,7 +2853,7 @@ void bar() { // CK12-NEXT: [[TMP46:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS7]], i32 0, i32 0 // CK12-NEXT: [[TMP47:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS8]], i32 0, i32 0 // CK12-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 0 -// CK12-NEXT: store i32 2, ptr [[TMP48]], align 4 +// CK12-NEXT: store i32 3, ptr [[TMP48]], align 4 // CK12-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 1 // CK12-NEXT: store i32 1, ptr [[TMP49]], align 4 // CK12-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 2 @@ -2898,7 +2898,7 @@ void bar() { // CK12-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS13]], i32 0, i32 0 // CK12-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS14]], i32 0, i32 0 // CK12-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 0 -// CK12-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CK12-NEXT: store i32 3, ptr [[TMP71]], align 4 // CK12-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 1 // CK12-NEXT: store i32 1, ptr [[TMP72]], align 4 // CK12-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 2 @@ -2943,7 +2943,7 @@ void bar() { // CK12-NEXT: [[TMP92:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS20]], i32 0, i32 0 // CK12-NEXT: [[TMP93:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS21]], i32 0, i32 0 // CK12-NEXT: [[TMP94:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CK12-NEXT: store i32 2, ptr [[TMP94]], align 4 +// CK12-NEXT: store i32 3, ptr [[TMP94]], align 4 // CK12-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CK12-NEXT: store i32 1, ptr [[TMP95]], align 4 // CK12-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -2988,7 +2988,7 @@ void bar() { // CK12-NEXT: [[TMP115:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CK12-NEXT: [[TMP116:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CK12-NEXT: [[TMP117:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CK12-NEXT: store i32 2, ptr [[TMP117]], align 4 +// CK12-NEXT: store i32 3, ptr [[TMP117]], align 4 // CK12-NEXT: [[TMP118:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CK12-NEXT: store i32 1, ptr [[TMP118]], align 4 // CK12-NEXT: [[TMP119:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -3043,7 +3043,7 @@ void bar() { // CK12-NEXT: [[TMP144:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS35]], i32 0, i32 0 // CK12-NEXT: [[TMP145:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS36]], i32 0, i32 0 // CK12-NEXT: [[TMP146:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 0 -// CK12-NEXT: store i32 2, ptr [[TMP146]], align 4 +// CK12-NEXT: store i32 3, ptr [[TMP146]], align 4 // CK12-NEXT: [[TMP147:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 1 // CK12-NEXT: store i32 2, ptr [[TMP147]], align 4 // CK12-NEXT: [[TMP148:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 2 @@ -3240,7 +3240,7 @@ void bar() { // CK13-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK13-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK13-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK13-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CK13-NEXT: store i32 3, ptr [[TMP6]], align 4 // CK13-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK13-NEXT: store i32 1, ptr [[TMP7]], align 4 // CK13-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3282,7 +3282,7 @@ void bar() { // CK13-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CK13-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CK13-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 0 -// CK13-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CK13-NEXT: store i32 3, ptr [[TMP27]], align 4 // CK13-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 1 // CK13-NEXT: store i32 1, ptr [[TMP28]], align 4 // CK13-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 2 @@ -3324,7 +3324,7 @@ void bar() { // CK13-NEXT: [[TMP46:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS7]], i32 0, i32 0 // CK13-NEXT: [[TMP47:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS8]], i32 0, i32 0 // CK13-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 0 -// CK13-NEXT: store i32 2, ptr [[TMP48]], align 4 +// CK13-NEXT: store i32 3, ptr [[TMP48]], align 4 // CK13-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 1 // CK13-NEXT: store i32 1, ptr [[TMP49]], align 4 // CK13-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS10]], i32 0, i32 2 @@ -3369,7 +3369,7 @@ void bar() { // CK13-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS13]], i32 0, i32 0 // CK13-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS14]], i32 0, i32 0 // CK13-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 0 -// CK13-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CK13-NEXT: store i32 3, ptr [[TMP71]], align 4 // CK13-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 1 // CK13-NEXT: store i32 1, ptr [[TMP72]], align 4 // CK13-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 2 @@ -3414,7 +3414,7 @@ void bar() { // CK13-NEXT: [[TMP92:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS20]], i32 0, i32 0 // CK13-NEXT: [[TMP93:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS21]], i32 0, i32 0 // CK13-NEXT: [[TMP94:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CK13-NEXT: store i32 2, ptr [[TMP94]], align 4 +// CK13-NEXT: store i32 3, ptr [[TMP94]], align 4 // CK13-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CK13-NEXT: store i32 1, ptr [[TMP95]], align 4 // CK13-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -3459,7 +3459,7 @@ void bar() { // CK13-NEXT: [[TMP115:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CK13-NEXT: [[TMP116:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CK13-NEXT: [[TMP117:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CK13-NEXT: store i32 2, ptr [[TMP117]], align 4 +// CK13-NEXT: store i32 3, ptr [[TMP117]], align 4 // CK13-NEXT: [[TMP118:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CK13-NEXT: store i32 1, ptr [[TMP118]], align 4 // CK13-NEXT: [[TMP119:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -3514,7 +3514,7 @@ void bar() { // CK13-NEXT: [[TMP144:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS35]], i32 0, i32 0 // CK13-NEXT: [[TMP145:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS36]], i32 0, i32 0 // CK13-NEXT: [[TMP146:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 0 -// CK13-NEXT: store i32 2, ptr [[TMP146]], align 4 +// CK13-NEXT: store i32 3, ptr [[TMP146]], align 4 // CK13-NEXT: [[TMP147:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 1 // CK13-NEXT: store i32 2, ptr [[TMP147]], align 4 // CK13-NEXT: [[TMP148:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 2 @@ -4003,7 +4003,7 @@ void bar() { // CK20-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK20-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK20-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK20-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CK20-NEXT: store i32 3, ptr [[TMP5]], align 4 // CK20-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK20-NEXT: store i32 1, ptr [[TMP6]], align 4 // CK20-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4061,7 +4061,7 @@ void bar() { // CK20-NEXT: [[TMP34:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CK20-NEXT: [[TMP35:%.*]] = getelementptr inbounds [2 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CK20-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CK20-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CK20-NEXT: store i32 3, ptr [[TMP36]], align 4 // CK20-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CK20-NEXT: store i32 2, ptr [[TMP37]], align 4 // CK20-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -4126,7 +4126,7 @@ void bar() { // CK20-NEXT: [[TMP68:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CK20-NEXT: [[TMP69:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES13]], i32 0, i32 0 // CK20-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CK20-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CK20-NEXT: store i32 3, ptr [[TMP70]], align 4 // CK20-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CK20-NEXT: store i32 3, ptr [[TMP71]], align 4 // CK20-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -4283,7 +4283,7 @@ void bar() { // CK21-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK21-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK21-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK21-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CK21-NEXT: store i32 3, ptr [[TMP5]], align 4 // CK21-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK21-NEXT: store i32 1, ptr [[TMP6]], align 4 // CK21-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4341,7 +4341,7 @@ void bar() { // CK21-NEXT: [[TMP34:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CK21-NEXT: [[TMP35:%.*]] = getelementptr inbounds [2 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CK21-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CK21-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CK21-NEXT: store i32 3, ptr [[TMP36]], align 4 // CK21-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CK21-NEXT: store i32 2, ptr [[TMP37]], align 4 // CK21-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -4406,7 +4406,7 @@ void bar() { // CK21-NEXT: [[TMP68:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CK21-NEXT: [[TMP69:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES13]], i32 0, i32 0 // CK21-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CK21-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CK21-NEXT: store i32 3, ptr [[TMP70]], align 4 // CK21-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CK21-NEXT: store i32 3, ptr [[TMP71]], align 4 // CK21-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -4563,7 +4563,7 @@ void bar() { // CK22-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK22-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK22-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK22-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CK22-NEXT: store i32 3, ptr [[TMP5]], align 4 // CK22-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK22-NEXT: store i32 1, ptr [[TMP6]], align 4 // CK22-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4621,7 +4621,7 @@ void bar() { // CK22-NEXT: [[TMP34:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CK22-NEXT: [[TMP35:%.*]] = getelementptr inbounds [2 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CK22-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CK22-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CK22-NEXT: store i32 3, ptr [[TMP36]], align 4 // CK22-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CK22-NEXT: store i32 2, ptr [[TMP37]], align 4 // CK22-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -4686,7 +4686,7 @@ void bar() { // CK22-NEXT: [[TMP68:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CK22-NEXT: [[TMP69:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES13]], i32 0, i32 0 // CK22-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CK22-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CK22-NEXT: store i32 3, ptr [[TMP70]], align 4 // CK22-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CK22-NEXT: store i32 3, ptr [[TMP71]], align 4 // CK22-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -4843,7 +4843,7 @@ void bar() { // CK23-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK23-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK23-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK23-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CK23-NEXT: store i32 3, ptr [[TMP5]], align 4 // CK23-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK23-NEXT: store i32 1, ptr [[TMP6]], align 4 // CK23-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4901,7 +4901,7 @@ void bar() { // CK23-NEXT: [[TMP34:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CK23-NEXT: [[TMP35:%.*]] = getelementptr inbounds [2 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CK23-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CK23-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CK23-NEXT: store i32 3, ptr [[TMP36]], align 4 // CK23-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CK23-NEXT: store i32 2, ptr [[TMP37]], align 4 // CK23-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -4966,7 +4966,7 @@ void bar() { // CK23-NEXT: [[TMP68:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CK23-NEXT: [[TMP69:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES13]], i32 0, i32 0 // CK23-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CK23-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CK23-NEXT: store i32 3, ptr [[TMP70]], align 4 // CK23-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CK23-NEXT: store i32 3, ptr [[TMP71]], align 4 // CK23-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -5376,7 +5376,7 @@ void bar() { // CK30-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK30-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK30-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK30-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CK30-NEXT: store i32 3, ptr [[TMP6]], align 4 // CK30-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK30-NEXT: store i32 1, ptr [[TMP7]], align 4 // CK30-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5439,7 +5439,7 @@ void bar() { // CK31-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK31-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK31-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK31-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CK31-NEXT: store i32 3, ptr [[TMP6]], align 4 // CK31-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK31-NEXT: store i32 1, ptr [[TMP7]], align 4 // CK31-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5502,7 +5502,7 @@ void bar() { // CK32-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK32-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK32-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK32-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CK32-NEXT: store i32 3, ptr [[TMP6]], align 4 // CK32-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK32-NEXT: store i32 1, ptr [[TMP7]], align 4 // CK32-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5565,7 +5565,7 @@ void bar() { // CK33-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CK33-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CK33-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CK33-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CK33-NEXT: store i32 3, ptr [[TMP6]], align 4 // CK33-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CK33-NEXT: store i32 1, ptr [[TMP7]], align 4 // CK33-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_map_codegen_03.cpp b/clang/test/OpenMP/target_map_codegen_03.cpp index cd28e7bf848e..959018647906 100644 --- a/clang/test/OpenMP/target_map_codegen_03.cpp +++ b/clang/test/OpenMP/target_map_codegen_03.cpp @@ -96,7 +96,7 @@ void implicit_maps_nested_integer (int a){ // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP8]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP9]], align 4 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -195,7 +195,7 @@ void implicit_maps_nested_integer (int a){ // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP8]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP9]], align 4 // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_map_codegen_hold.cpp b/clang/test/OpenMP/target_map_codegen_hold.cpp index 81306ccb4cf5..c6ee673d9598 100644 --- a/clang/test/OpenMP/target_map_codegen_hold.cpp +++ b/clang/test/OpenMP/target_map_codegen_hold.cpp @@ -245,7 +245,7 @@ void ST::test_present_members() { // CHECK-USE-PPC64LE-NEXT: [[TMP35:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-USE-PPC64LE-NEXT: [[TMP36:%.*]] = getelementptr inbounds [7 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK-USE-PPC64LE-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-USE-PPC64LE-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK-USE-PPC64LE-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK-USE-PPC64LE-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-USE-PPC64LE-NEXT: store i32 7, ptr [[TMP38]], align 4 // CHECK-USE-PPC64LE-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -286,7 +286,7 @@ void ST::test_present_members() { // CHECK-USE-PPC64LE-NEXT: [[TMP55:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK-USE-PPC64LE-NEXT: [[TMP56:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK-USE-PPC64LE-NEXT: [[TMP57:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK-USE-PPC64LE-NEXT: store i32 2, ptr [[TMP57]], align 4 +// CHECK-USE-PPC64LE-NEXT: store i32 3, ptr [[TMP57]], align 4 // CHECK-USE-PPC64LE-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK-USE-PPC64LE-NEXT: store i32 1, ptr [[TMP58]], align 4 // CHECK-USE-PPC64LE-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -410,7 +410,7 @@ void ST::test_present_members() { // CHECK-USE-PPC64LE-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-USE-PPC64LE-NEXT: [[TMP17:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK-USE-PPC64LE-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-USE-PPC64LE-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK-USE-PPC64LE-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK-USE-PPC64LE-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-USE-PPC64LE-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK-USE-PPC64LE-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -546,7 +546,7 @@ void ST::test_present_members() { // CHECK-USE-I386-NEXT: [[TMP35:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-USE-I386-NEXT: [[TMP36:%.*]] = getelementptr inbounds [7 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK-USE-I386-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-USE-I386-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK-USE-I386-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK-USE-I386-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-USE-I386-NEXT: store i32 7, ptr [[TMP38]], align 4 // CHECK-USE-I386-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -587,7 +587,7 @@ void ST::test_present_members() { // CHECK-USE-I386-NEXT: [[TMP55:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK-USE-I386-NEXT: [[TMP56:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK-USE-I386-NEXT: [[TMP57:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK-USE-I386-NEXT: store i32 2, ptr [[TMP57]], align 4 +// CHECK-USE-I386-NEXT: store i32 3, ptr [[TMP57]], align 4 // CHECK-USE-I386-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK-USE-I386-NEXT: store i32 1, ptr [[TMP58]], align 4 // CHECK-USE-I386-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -711,7 +711,7 @@ void ST::test_present_members() { // CHECK-USE-I386-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-USE-I386-NEXT: [[TMP17:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK-USE-I386-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-USE-I386-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK-USE-I386-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK-USE-I386-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-USE-I386-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK-USE-I386-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -847,7 +847,7 @@ void ST::test_present_members() { // CHECK-NOUSE-PPC64LE-NEXT: [[TMP35:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP36:%.*]] = getelementptr inbounds [7 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NOUSE-PPC64LE-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK-NOUSE-PPC64LE-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NOUSE-PPC64LE-NEXT: store i32 7, ptr [[TMP38]], align 4 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -888,7 +888,7 @@ void ST::test_present_members() { // CHECK-NOUSE-PPC64LE-NEXT: [[TMP55:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP56:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP57:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK-NOUSE-PPC64LE-NEXT: store i32 2, ptr [[TMP57]], align 4 +// CHECK-NOUSE-PPC64LE-NEXT: store i32 3, ptr [[TMP57]], align 4 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK-NOUSE-PPC64LE-NEXT: store i32 1, ptr [[TMP58]], align 4 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -978,7 +978,7 @@ void ST::test_present_members() { // CHECK-NOUSE-PPC64LE-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP17:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NOUSE-PPC64LE-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK-NOUSE-PPC64LE-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NOUSE-PPC64LE-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK-NOUSE-PPC64LE-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1103,7 +1103,7 @@ void ST::test_present_members() { // CHECK-NOUSE-I386-NEXT: [[TMP35:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NOUSE-I386-NEXT: [[TMP36:%.*]] = getelementptr inbounds [7 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK-NOUSE-I386-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NOUSE-I386-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK-NOUSE-I386-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK-NOUSE-I386-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NOUSE-I386-NEXT: store i32 7, ptr [[TMP38]], align 4 // CHECK-NOUSE-I386-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1144,7 +1144,7 @@ void ST::test_present_members() { // CHECK-NOUSE-I386-NEXT: [[TMP55:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK-NOUSE-I386-NEXT: [[TMP56:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK-NOUSE-I386-NEXT: [[TMP57:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK-NOUSE-I386-NEXT: store i32 2, ptr [[TMP57]], align 4 +// CHECK-NOUSE-I386-NEXT: store i32 3, ptr [[TMP57]], align 4 // CHECK-NOUSE-I386-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK-NOUSE-I386-NEXT: store i32 1, ptr [[TMP58]], align 4 // CHECK-NOUSE-I386-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -1234,7 +1234,7 @@ void ST::test_present_members() { // CHECK-NOUSE-I386-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NOUSE-I386-NEXT: [[TMP17:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK-NOUSE-I386-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NOUSE-I386-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK-NOUSE-I386-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK-NOUSE-I386-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NOUSE-I386-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK-NOUSE-I386-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_map_deref_array_codegen.cpp b/clang/test/OpenMP/target_map_deref_array_codegen.cpp index da4176f20109..b85433300229 100644 --- a/clang/test/OpenMP/target_map_deref_array_codegen.cpp +++ b/clang/test/OpenMP/target_map_deref_array_codegen.cpp @@ -91,7 +91,7 @@ void foo(int **t1d) // CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 2, ptr [[TMP20]], align 4 // CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -143,7 +143,7 @@ void foo(int **t1d) // CHECK-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 // CHECK-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP47]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP47]], align 4 // CHECK-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK-NEXT: store i32 2, ptr [[TMP48]], align 4 // CHECK-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -224,7 +224,7 @@ void foo(int **t1d) // CHECK-NEXT: [[TMP86:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS12]], i32 0, i32 0 // CHECK-NEXT: [[TMP87:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS13]], i32 0, i32 0 // CHECK-NEXT: [[TMP88:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP88]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP88]], align 4 // CHECK-NEXT: [[TMP89:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK-NEXT: store i32 4, ptr [[TMP89]], align 4 // CHECK-NEXT: [[TMP90:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_map_member_expr_codegen.cpp b/clang/test/OpenMP/target_map_member_expr_codegen.cpp index 84844cff09b9..9979f381a706 100644 --- a/clang/test/OpenMP/target_map_member_expr_codegen.cpp +++ b/clang/test/OpenMP/target_map_member_expr_codegen.cpp @@ -138,7 +138,7 @@ void foo() { // CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP14]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP14]], align 4 // CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 4, ptr [[TMP15]], align 4 // CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -295,7 +295,7 @@ void foo() { // CHECK-NEXT: [[TMP53:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS9]], i32 0, i32 0 // CHECK-NEXT: [[TMP54:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS10]], i32 0, i32 0 // CHECK-NEXT: [[TMP55:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP55]], align 4 // CHECK-NEXT: [[TMP56:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 2, ptr [[TMP56]], align 4 // CHECK-NEXT: [[TMP57:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -379,7 +379,7 @@ void foo() { // CHECK-NEXT: [[TMP100:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS19]], i32 0, i32 0 // CHECK-NEXT: [[TMP101:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES21]], i32 0, i32 0 // CHECK-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS22]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP102]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP102]], align 4 // CHECK-NEXT: [[TMP103:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS22]], i32 0, i32 1 // CHECK-NEXT: store i32 3, ptr [[TMP103]], align 4 // CHECK-NEXT: [[TMP104:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS22]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_offload_mandatory_codegen.cpp b/clang/test/OpenMP/target_offload_mandatory_codegen.cpp index 04360f1ea03b..3bf15277aa1c 100644 --- a/clang/test/OpenMP/target_offload_mandatory_codegen.cpp +++ b/clang/test/OpenMP/target_offload_mandatory_codegen.cpp @@ -33,7 +33,7 @@ void host_dev(int device) { // MANDATORY-NEXT: entry: // MANDATORY-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // MANDATORY-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// MANDATORY-NEXT: store i32 2, ptr [[TMP0]], align 4 +// MANDATORY-NEXT: store i32 3, ptr [[TMP0]], align 4 // MANDATORY-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // MANDATORY-NEXT: store i32 0, ptr [[TMP1]], align 4 // MANDATORY-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -79,7 +79,7 @@ void host_dev(int device) { // MANDATORY-NEXT: br i1 [[TOBOOL]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] // MANDATORY: omp_if.then: // MANDATORY-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// MANDATORY-NEXT: store i32 2, ptr [[TMP1]], align 4 +// MANDATORY-NEXT: store i32 3, ptr [[TMP1]], align 4 // MANDATORY-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // MANDATORY-NEXT: store i32 0, ptr [[TMP2]], align 4 // MANDATORY-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -129,7 +129,7 @@ void host_dev(int device) { // MANDATORY-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // MANDATORY-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 // MANDATORY-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// MANDATORY-NEXT: store i32 2, ptr [[TMP3]], align 4 +// MANDATORY-NEXT: store i32 3, ptr [[TMP3]], align 4 // MANDATORY-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // MANDATORY-NEXT: store i32 0, ptr [[TMP4]], align 4 // MANDATORY-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_ompx_dyn_cgroup_mem_codegen.cpp b/clang/test/OpenMP/target_ompx_dyn_cgroup_mem_codegen.cpp index e8b074a9d5f8..10c4ac38e6a8 100644 --- a/clang/test/OpenMP/target_ompx_dyn_cgroup_mem_codegen.cpp +++ b/clang/test/OpenMP/target_ompx_dyn_cgroup_mem_codegen.cpp @@ -256,7 +256,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -298,7 +298,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP38]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP38]], align 4 // CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP39]], align 4 // CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -408,7 +408,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP20]], 0 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -493,7 +493,7 @@ int bar(int n){ // CHECK1-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4 // CHECK1-NEXT: store i32 0, ptr [[A]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -561,7 +561,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP34:%.*]] = sext i16 [[TMP33]] to i32 // CHECK1-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP34]], 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 2 @@ -958,7 +958,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias [[META27]] // CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias [[META27]] // CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP9]], align 4 -// CHECK1-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META27]] +// CHECK1-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META27]] // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP16]], align 4, !noalias [[META27]] // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -1138,7 +1138,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1180,7 +1180,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP38]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP38]], align 4 // CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP39]], align 4 // CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -1290,7 +1290,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP25:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP20]], 0 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1375,7 +1375,7 @@ int bar(int n){ // CHECK3-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4 // CHECK3-NEXT: store i32 0, ptr [[A]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1443,7 +1443,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP34:%.*]] = sext i16 [[TMP33]] to i32 // CHECK3-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP34]], 0 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 2 @@ -1836,7 +1836,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP13:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias [[META28]] // CHECK3-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias [[META28]] // CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP9]], align 4 -// CHECK3-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META28]] +// CHECK3-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META28]] // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP16]], align 4, !noalias [[META28]] // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_parallel_codegen.cpp b/clang/test/OpenMP/target_parallel_codegen.cpp index 84b7f1ae4ec0..ad5a9d53bcf6 100644 --- a/clang/test/OpenMP/target_parallel_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_codegen.cpp @@ -356,7 +356,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP20]], align 4 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -413,7 +413,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS5]], i32 0, i32 0 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP47]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP47]], align 4 // CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP48]], align 4 // CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -523,7 +523,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP98:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS14]], i32 0, i32 0 // CHECK1-NEXT: [[TMP99:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK1-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 1 // CHECK1-NEXT: store i32 9, ptr [[TMP101]], align 4 // CHECK1-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 2 @@ -614,7 +614,7 @@ int bar(int n){ // CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, !noalias [[META21]] // CHECK1-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META21]] // CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META21]] -// CHECK1-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META21]] +// CHECK1-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META21]] // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP9]], align 4, !noalias [[META21]] // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -972,7 +972,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1080,7 +1080,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1168,7 +1168,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1450,7 +1450,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP17]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1507,7 +1507,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS5]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -1619,7 +1619,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP98:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS14]], i32 0, i32 0 // CHECK3-NEXT: [[TMP99:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK3-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 1 // CHECK3-NEXT: store i32 9, ptr [[TMP101]], align 4 // CHECK3-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 2 @@ -1710,7 +1710,7 @@ int bar(int n){ // CHECK3-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 4, !noalias [[META22]] // CHECK3-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 4, !noalias [[META22]] // CHECK3-NEXT: [[TMP8:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 4, !noalias [[META22]] -// CHECK3-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META22]] +// CHECK3-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META22]] // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP9]], align 4, !noalias [[META22]] // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -2068,7 +2068,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2176,7 +2176,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2264,7 +2264,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_parallel_for_codegen.cpp b/clang/test/OpenMP/target_parallel_for_codegen.cpp index 31f6d0b8ad9a..73504cf7a802 100644 --- a/clang/test/OpenMP/target_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_for_codegen.cpp @@ -366,7 +366,7 @@ int bar(int n){ // CHECK1-NEXT: [[VLA1:%.*]] = alloca double, i64 [[TMP6]], align 8 // CHECK1-NEXT: store i64 [[TMP5]], ptr [[__VLA_EXPR1]], align 8 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -487,7 +487,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP71:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK1-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP73]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP73]], align 4 // CHECK1-NEXT: [[TMP74:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP74]], align 4 // CHECK1-NEXT: [[TMP75:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 @@ -608,7 +608,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP130:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS15]], i32 0, i32 0 // CHECK1-NEXT: [[TMP131:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP132:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP132]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP132]], align 4 // CHECK1-NEXT: [[TMP133:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 1 // CHECK1-NEXT: store i32 10, ptr [[TMP133]], align 4 // CHECK1-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 2 @@ -1047,7 +1047,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias [[META24]] // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[TMP9]], i32 0, i32 1 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 -// CHECK1-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META24]] +// CHECK1-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META24]] // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4, !noalias [[META24]] // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -1475,7 +1475,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1583,7 +1583,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1671,7 +1671,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2032,7 +2032,7 @@ int bar(int n){ // CHECK3-NEXT: [[VLA1:%.*]] = alloca double, i32 [[TMP4]], align 8 // CHECK3-NEXT: store i32 [[TMP3]], ptr [[__VLA_EXPR1]], align 4 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2150,7 +2150,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP67:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK3-NEXT: [[TMP68:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK3-NEXT: [[TMP69:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP69]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP69]], align 4 // CHECK3-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP70]], align 4 // CHECK3-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 @@ -2273,7 +2273,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP128:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS15]], i32 0, i32 0 // CHECK3-NEXT: [[TMP129:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP130:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP130]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP130]], align 4 // CHECK3-NEXT: [[TMP131:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 1 // CHECK3-NEXT: store i32 10, ptr [[TMP131]], align 4 // CHECK3-NEXT: [[TMP132:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 2 @@ -2710,7 +2710,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias [[META25]] // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[TMP9]], i32 0, i32 1 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 -// CHECK3-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META25]] +// CHECK3-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META25]] // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4, !noalias [[META25]] // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -3138,7 +3138,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3246,7 +3246,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3334,7 +3334,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5256,7 +5256,7 @@ int bar(int n){ // CHECK17-NEXT: [[VLA1:%.*]] = alloca double, i64 [[TMP6]], align 8 // CHECK17-NEXT: store i64 [[TMP5]], ptr [[__VLA_EXPR1]], align 8 // CHECK17-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK17-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 0, ptr [[TMP8]], align 4 // CHECK17-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5377,7 +5377,7 @@ int bar(int n){ // CHECK17-NEXT: [[TMP71:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK17-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK17-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP73]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP73]], align 4 // CHECK17-NEXT: [[TMP74:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP74]], align 4 // CHECK17-NEXT: [[TMP75:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 @@ -5498,7 +5498,7 @@ int bar(int n){ // CHECK17-NEXT: [[TMP130:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS15]], i32 0, i32 0 // CHECK17-NEXT: [[TMP131:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK17-NEXT: [[TMP132:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP132]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP132]], align 4 // CHECK17-NEXT: [[TMP133:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 1 // CHECK17-NEXT: store i32 10, ptr [[TMP133]], align 4 // CHECK17-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 2 @@ -5937,7 +5937,7 @@ int bar(int n){ // CHECK17-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias [[META24]] // CHECK17-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[TMP9]], i32 0, i32 1 // CHECK17-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 -// CHECK17-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META24]] +// CHECK17-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META24]] // CHECK17-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP18]], align 4, !noalias [[META24]] // CHECK17-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -6365,7 +6365,7 @@ int bar(int n){ // CHECK17-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK17-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK17-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK17-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6473,7 +6473,7 @@ int bar(int n){ // CHECK17-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK17-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6561,7 +6561,7 @@ int bar(int n){ // CHECK17-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK17-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK17-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6922,7 +6922,7 @@ int bar(int n){ // CHECK19-NEXT: [[VLA1:%.*]] = alloca double, i32 [[TMP4]], align 8 // CHECK19-NEXT: store i32 [[TMP3]], ptr [[__VLA_EXPR1]], align 4 // CHECK19-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK19-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 0, ptr [[TMP6]], align 4 // CHECK19-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7040,7 +7040,7 @@ int bar(int n){ // CHECK19-NEXT: [[TMP67:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK19-NEXT: [[TMP68:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK19-NEXT: [[TMP69:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP69]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP69]], align 4 // CHECK19-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP70]], align 4 // CHECK19-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 @@ -7163,7 +7163,7 @@ int bar(int n){ // CHECK19-NEXT: [[TMP128:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS15]], i32 0, i32 0 // CHECK19-NEXT: [[TMP129:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK19-NEXT: [[TMP130:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP130]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP130]], align 4 // CHECK19-NEXT: [[TMP131:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 1 // CHECK19-NEXT: store i32 10, ptr [[TMP131]], align 4 // CHECK19-NEXT: [[TMP132:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 2 @@ -7600,7 +7600,7 @@ int bar(int n){ // CHECK19-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias [[META25]] // CHECK19-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[TMP9]], i32 0, i32 1 // CHECK19-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 -// CHECK19-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META25]] +// CHECK19-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META25]] // CHECK19-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP18]], align 4, !noalias [[META25]] // CHECK19-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -8028,7 +8028,7 @@ int bar(int n){ // CHECK19-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK19-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK19-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK19-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -8136,7 +8136,7 @@ int bar(int n){ // CHECK19-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK19-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -8224,7 +8224,7 @@ int bar(int n){ // CHECK19-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK19-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK19-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_parallel_for_simd_codegen.cpp b/clang/test/OpenMP/target_parallel_for_simd_codegen.cpp index 7751ae93d59f..8009e06666c8 100644 --- a/clang/test/OpenMP/target_parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_codegen.cpp @@ -395,7 +395,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP31]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP31]], align 4 // CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP32]], align 4 // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -452,7 +452,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP57:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP60]], align 4 // CHECK1-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 @@ -573,7 +573,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP116:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS15]], i32 0, i32 0 // CHECK1-NEXT: [[TMP117:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP118:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP118]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP118]], align 4 // CHECK1-NEXT: [[TMP119:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 1 // CHECK1-NEXT: store i32 10, ptr [[TMP119]], align 4 // CHECK1-NEXT: [[TMP120:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 2 @@ -721,7 +721,7 @@ int bar(int n){ // CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, !noalias [[META25]] // CHECK1-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META25]] // CHECK1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META25]] -// CHECK1-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META25]] +// CHECK1-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META25]] // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP9]], align 4, !noalias [[META25]] // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -1403,7 +1403,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1511,7 +1511,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1599,7 +1599,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2013,7 +2013,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2070,7 +2070,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP53:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK3-NEXT: [[TMP54:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK3-NEXT: [[TMP55:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP55]], align 4 // CHECK3-NEXT: [[TMP56:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP56]], align 4 // CHECK3-NEXT: [[TMP57:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 @@ -2193,7 +2193,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP114:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS15]], i32 0, i32 0 // CHECK3-NEXT: [[TMP115:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP116:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP116]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP116]], align 4 // CHECK3-NEXT: [[TMP117:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 1 // CHECK3-NEXT: store i32 10, ptr [[TMP117]], align 4 // CHECK3-NEXT: [[TMP118:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 2 @@ -2341,7 +2341,7 @@ int bar(int n){ // CHECK3-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 4, !noalias [[META26]] // CHECK3-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP8:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 4, !noalias [[META26]] -// CHECK3-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP9]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -3021,7 +3021,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3129,7 +3129,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3217,7 +3217,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3637,7 +3637,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP31]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP31]], align 4 // CHECK5-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 3, ptr [[TMP32]], align 4 // CHECK5-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3694,7 +3694,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP57:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK5-NEXT: [[TMP58:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK5-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK5-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK5-NEXT: store i32 2, ptr [[TMP60]], align 4 // CHECK5-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 @@ -3815,7 +3815,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP116:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS15]], i32 0, i32 0 // CHECK5-NEXT: [[TMP117:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK5-NEXT: [[TMP118:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP118]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP118]], align 4 // CHECK5-NEXT: [[TMP119:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 1 // CHECK5-NEXT: store i32 10, ptr [[TMP119]], align 4 // CHECK5-NEXT: [[TMP120:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 2 @@ -3963,7 +3963,7 @@ int bar(int n){ // CHECK5-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, !noalias [[META25]] // CHECK5-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META25]] // CHECK5-NEXT: [[TMP8:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, !noalias [[META25]] -// CHECK5-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META25]] +// CHECK5-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META25]] // CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP9]], align 4, !noalias [[META25]] // CHECK5-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -4666,7 +4666,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP36:%.*]] = select i1 [[TOBOOL4]], i32 0, i32 1 // CHECK5-NEXT: [[TMP37:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP36]], 0 // CHECK5-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP38]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP38]], align 4 // CHECK5-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 6, ptr [[TMP39]], align 4 // CHECK5-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4774,7 +4774,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK5-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4862,7 +4862,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5362,7 +5362,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP25:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP26:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK7-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK7-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5419,7 +5419,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP53:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK7-NEXT: [[TMP54:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK7-NEXT: [[TMP55:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP55]], align 4 // CHECK7-NEXT: [[TMP56:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK7-NEXT: store i32 2, ptr [[TMP56]], align 4 // CHECK7-NEXT: [[TMP57:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 @@ -5542,7 +5542,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP114:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS15]], i32 0, i32 0 // CHECK7-NEXT: [[TMP115:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK7-NEXT: [[TMP116:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP116]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP116]], align 4 // CHECK7-NEXT: [[TMP117:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 1 // CHECK7-NEXT: store i32 10, ptr [[TMP117]], align 4 // CHECK7-NEXT: [[TMP118:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS17]], i32 0, i32 2 @@ -5690,7 +5690,7 @@ int bar(int n){ // CHECK7-NEXT: store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 4, !noalias [[META26]] // CHECK7-NEXT: store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 4, !noalias [[META26]] // CHECK7-NEXT: [[TMP8:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 4, !noalias [[META26]] -// CHECK7-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META26]] +// CHECK7-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META26]] // CHECK7-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK7-NEXT: store i32 0, ptr [[TMP9]], align 4, !noalias [[META26]] // CHECK7-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -6391,7 +6391,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP36:%.*]] = select i1 [[TOBOOL4]], i32 0, i32 1 // CHECK7-NEXT: [[TMP37:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP36]], 0 // CHECK7-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP38]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP38]], align 4 // CHECK7-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 6, ptr [[TMP39]], align 4 // CHECK7-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6499,7 +6499,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK7-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK7-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6587,7 +6587,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK7-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK7-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_parallel_generic_loop_codegen-1.cpp b/clang/test/OpenMP/target_parallel_generic_loop_codegen-1.cpp index fa3d182b62ad..bbefab195b9a 100644 --- a/clang/test/OpenMP/target_parallel_generic_loop_codegen-1.cpp +++ b/clang/test/OpenMP/target_parallel_generic_loop_codegen-1.cpp @@ -4185,7 +4185,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP9]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP10]], align 4 // OMP-DEfAULT-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4394,7 +4394,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP9]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP10]], align 4 // OMP-DEfAULT-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4565,7 +4565,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP9]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP10]], align 4 // OMP-DEfAULT-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4708,7 +4708,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP9]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP10]], align 4 // OMP-DEfAULT-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4879,7 +4879,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP9]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP10]], align 4 // OMP-DEfAULT-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5022,7 +5022,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP9]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP10]], align 4 // OMP-DEfAULT-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5193,7 +5193,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP9]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP10]], align 4 // OMP-DEfAULT-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5336,7 +5336,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP9]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP10]], align 4 // OMP-DEfAULT-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5486,7 +5486,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP8]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP8]], align 4 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5571,7 +5571,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP9]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP10]], align 4 // OMP-DEfAULT-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5695,7 +5695,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP9]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP10]], align 4 // OMP-DEfAULT-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5760,7 +5760,7 @@ int bar(int a){ // OMP-DEfAULT-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // OMP-DEfAULT-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// OMP-DEfAULT-NEXT: store i32 2, ptr [[TMP9]], align 4 +// OMP-DEfAULT-NEXT: store i32 3, ptr [[TMP9]], align 4 // OMP-DEfAULT-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // OMP-DEfAULT-NEXT: store i32 1, ptr [[TMP10]], align 4 // OMP-DEfAULT-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_parallel_generic_loop_codegen-2.cpp b/clang/test/OpenMP/target_parallel_generic_loop_codegen-2.cpp index a7b7278dff8d..a92f052085c7 100644 --- a/clang/test/OpenMP/target_parallel_generic_loop_codegen-2.cpp +++ b/clang/test/OpenMP/target_parallel_generic_loop_codegen-2.cpp @@ -88,7 +88,7 @@ int nested(int a){ // CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -306,7 +306,7 @@ int nested(int a){ // CHECK-X86-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-X86-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-X86-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-X86-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK-X86-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK-X86-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-X86-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK-X86-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_parallel_generic_loop_uses_allocators_codegen.cpp b/clang/test/OpenMP/target_parallel_generic_loop_uses_allocators_codegen.cpp index 472811c5c566..0171d97e2f54 100644 --- a/clang/test/OpenMP/target_parallel_generic_loop_uses_allocators_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_generic_loop_uses_allocators_codegen.cpp @@ -90,7 +90,7 @@ void foo() { // CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_parallel_if_codegen.cpp b/clang/test/OpenMP/target_parallel_if_codegen.cpp index 841c49e31ccb..6447a76dd467 100644 --- a/clang/test/OpenMP/target_parallel_if_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_if_codegen.cpp @@ -270,7 +270,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP17:%.*]] = select i1 [[TOBOOL3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP17]], 0 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -335,7 +335,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP47:%.*]] = select i1 [[TOBOOL15]], i32 0, i32 1 // CHECK1-NEXT: [[TMP48:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP47]], 0 // CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP49]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP49]], align 4 // CHECK1-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP50]], align 4 // CHECK1-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 2 @@ -416,7 +416,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP10:%.*]] = select i1 [[TOBOOL3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP11:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP10]], 0 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP12]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP12]], align 4 // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP13]], align 4 // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -459,7 +459,7 @@ int bar(int n){ // CHECK1-NEXT: br i1 [[CMP4]], label [[OMP_IF_THEN5:%.*]], label [[OMP_IF_ELSE9:%.*]] // CHECK1: omp_if.then5: // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -532,7 +532,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -586,7 +586,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP34]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP34]], align 4 // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP35]], align 4 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -932,7 +932,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP17:%.*]] = select i1 [[TOBOOL3]], i32 0, i32 1 // CHECK3-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP17]], 0 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -997,7 +997,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP47:%.*]] = select i1 [[TOBOOL15]], i32 0, i32 1 // CHECK3-NEXT: [[TMP48:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP47]], 0 // CHECK3-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP49]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP49]], align 4 // CHECK3-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP50]], align 4 // CHECK3-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS16]], i32 0, i32 2 @@ -1078,7 +1078,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP10:%.*]] = select i1 [[TOBOOL3]], i32 0, i32 1 // CHECK3-NEXT: [[TMP11:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP10]], 0 // CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP12]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP12]], align 4 // CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP13]], align 4 // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1121,7 +1121,7 @@ int bar(int n){ // CHECK3-NEXT: br i1 [[CMP4]], label [[OMP_IF_THEN5:%.*]], label [[OMP_IF_ELSE9:%.*]] // CHECK3: omp_if.then5: // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -1194,7 +1194,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1248,7 +1248,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 // CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP34]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP34]], align 4 // CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP35]], align 4 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_parallel_num_threads_codegen.cpp b/clang/test/OpenMP/target_parallel_num_threads_codegen.cpp index 0778bca8c3f4..a14518286dc9 100644 --- a/clang/test/OpenMP/target_parallel_num_threads_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_num_threads_codegen.cpp @@ -271,7 +271,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP17]], 0 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -313,7 +313,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP39]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP39]], align 4 // CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP40]], align 4 // CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -384,7 +384,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP8]], 0 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP10]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP10]], align 4 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP11]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -433,7 +433,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP33:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK1-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP36]], align 4 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -488,7 +488,7 @@ int bar(int n){ // CHECK1-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4 // CHECK1-NEXT: store i32 0, ptr [[A]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -556,7 +556,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP34:%.*]] = zext i16 [[TMP33]] to i32 // CHECK1-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP34]], 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 2 @@ -849,7 +849,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP17]], 0 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -891,7 +891,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP39]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP39]], align 4 // CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP40]], align 4 // CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -962,7 +962,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP8]], 0 // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP10]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP10]], align 4 // CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP11]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1011,7 +1011,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP33:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 // CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP36]], align 4 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -1066,7 +1066,7 @@ int bar(int n){ // CHECK3-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4 // CHECK3-NEXT: store i32 0, ptr [[A]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1134,7 +1134,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP34:%.*]] = zext i16 [[TMP33]] to i32 // CHECK3-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP34]], 0 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_task_affinity_codegen.cpp b/clang/test/OpenMP/target_task_affinity_codegen.cpp index 472c50235bf9..2ef6e5a2f7a3 100644 --- a/clang/test/OpenMP/target_task_affinity_codegen.cpp +++ b/clang/test/OpenMP/target_task_affinity_codegen.cpp @@ -118,7 +118,7 @@ int main() { // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP28]], align 4 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -341,7 +341,7 @@ int main() { // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP28]], align 4 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_codegen.cpp b/clang/test/OpenMP/target_teams_codegen.cpp index e22fcbbcd277..24dc2fd2e49f 100644 --- a/clang/test/OpenMP/target_teams_codegen.cpp +++ b/clang/test/OpenMP/target_teams_codegen.cpp @@ -453,7 +453,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP50:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK1-NEXT: [[TMP51:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP52]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP52]], align 4 // CHECK1-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP53]], align 4 // CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -510,7 +510,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS10]], i32 0, i32 0 // CHECK1-NEXT: [[TMP79:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP80:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS13]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP80]], align 4 // CHECK1-NEXT: [[TMP81:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS13]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP81]], align 4 // CHECK1-NEXT: [[TMP82:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS13]], i32 0, i32 2 @@ -568,7 +568,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP105:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS18]], i32 0, i32 0 // CHECK1-NEXT: [[TMP106:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS19]], i32 0, i32 0 // CHECK1-NEXT: [[TMP107:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP107]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP107]], align 4 // CHECK1-NEXT: [[TMP108:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP108]], align 4 // CHECK1-NEXT: [[TMP109:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 2 @@ -673,7 +673,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP158:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK1-NEXT: [[TMP159:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP160:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP160]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP160]], align 4 // CHECK1-NEXT: [[TMP161:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK1-NEXT: store i32 9, ptr [[TMP161]], align 4 // CHECK1-NEXT: [[TMP162:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -723,7 +723,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP180:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS35]], i32 0, i32 0 // CHECK1-NEXT: [[TMP181:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS36]], i32 0, i32 0 // CHECK1-NEXT: [[TMP182:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP182]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP182]], align 4 // CHECK1-NEXT: [[TMP183:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP183]], align 4 // CHECK1-NEXT: [[TMP184:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 2 @@ -767,7 +767,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP202:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS42]], i32 0, i32 0 // CHECK1-NEXT: [[TMP203:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS43]], i32 0, i32 0 // CHECK1-NEXT: [[TMP204:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP204]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP204]], align 4 // CHECK1-NEXT: [[TMP205:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP205]], align 4 // CHECK1-NEXT: [[TMP206:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 2 @@ -919,7 +919,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 // CHECK1-NEXT: [[TMP21:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP19]], 0 -// CHECK1-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META25]] +// CHECK1-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META25]] // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP22]], align 4, !noalias [[META25]] // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -1317,7 +1317,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1482,7 +1482,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1590,7 +1590,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1678,7 +1678,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2040,7 +2040,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP48:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK3-NEXT: [[TMP49:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK3-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK3-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP51]], align 4 // CHECK3-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2097,7 +2097,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS10]], i32 0, i32 0 // CHECK3-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP78:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS13]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP78]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP78]], align 4 // CHECK3-NEXT: [[TMP79:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS13]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP79]], align 4 // CHECK3-NEXT: [[TMP80:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS13]], i32 0, i32 2 @@ -2155,7 +2155,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP103:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS18]], i32 0, i32 0 // CHECK3-NEXT: [[TMP104:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS19]], i32 0, i32 0 // CHECK3-NEXT: [[TMP105:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP105]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP105]], align 4 // CHECK3-NEXT: [[TMP106:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP106]], align 4 // CHECK3-NEXT: [[TMP107:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS21]], i32 0, i32 2 @@ -2262,7 +2262,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP158:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK3-NEXT: [[TMP159:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP160:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP160]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP160]], align 4 // CHECK3-NEXT: [[TMP161:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK3-NEXT: store i32 9, ptr [[TMP161]], align 4 // CHECK3-NEXT: [[TMP162:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -2312,7 +2312,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP180:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS35]], i32 0, i32 0 // CHECK3-NEXT: [[TMP181:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS36]], i32 0, i32 0 // CHECK3-NEXT: [[TMP182:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP182]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP182]], align 4 // CHECK3-NEXT: [[TMP183:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP183]], align 4 // CHECK3-NEXT: [[TMP184:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS38]], i32 0, i32 2 @@ -2356,7 +2356,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP202:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS42]], i32 0, i32 0 // CHECK3-NEXT: [[TMP203:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS43]], i32 0, i32 0 // CHECK3-NEXT: [[TMP204:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP204]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP204]], align 4 // CHECK3-NEXT: [[TMP205:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP205]], align 4 // CHECK3-NEXT: [[TMP206:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 2 @@ -2508,7 +2508,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[TMP17]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 // CHECK3-NEXT: [[TMP21:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP19]], 0 -// CHECK3-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META26]] +// CHECK3-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP22]], align 4, !noalias [[META26]] // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -2905,7 +2905,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3070,7 +3070,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3178,7 +3178,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3266,7 +3266,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_codegen.cpp index 1ad3d8333ba6..bd33e52ca3ef 100644 --- a/clang/test/OpenMP/target_teams_distribute_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_codegen.cpp @@ -427,7 +427,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP50:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK1-NEXT: [[TMP51:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP52]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP52]], align 4 // CHECK1-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP53]], align 4 // CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -484,7 +484,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS10]], i32 0, i32 0 // CHECK1-NEXT: [[TMP79:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP80:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP80]], align 4 // CHECK1-NEXT: [[TMP81:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP81]], align 4 // CHECK1-NEXT: [[TMP82:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -605,7 +605,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP137:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS23]], i32 0, i32 0 // CHECK1-NEXT: [[TMP138:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP139:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP139]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP139]], align 4 // CHECK1-NEXT: [[TMP140:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 1 // CHECK1-NEXT: store i32 10, ptr [[TMP140]], align 4 // CHECK1-NEXT: [[TMP141:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 2 @@ -812,7 +812,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 // CHECK1-NEXT: [[TMP21:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP19]], 0 -// CHECK1-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META21]] +// CHECK1-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META21]] // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP22]], align 4, !noalias [[META21]] // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -1397,7 +1397,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1534,7 +1534,7 @@ int bar(int n){ // CHECK1-NEXT: [[ADD5:%.*]] = add i32 [[TMP30]], 1 // CHECK1-NEXT: [[TMP31:%.*]] = zext i32 [[ADD5]] to i64 // CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP32]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP32]], align 4 // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP33]], align 4 // CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1623,7 +1623,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2163,7 +2163,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP48:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK3-NEXT: [[TMP49:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK3-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK3-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP51]], align 4 // CHECK3-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2220,7 +2220,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS10]], i32 0, i32 0 // CHECK3-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP78:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP78]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP78]], align 4 // CHECK3-NEXT: [[TMP79:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP79]], align 4 // CHECK3-NEXT: [[TMP80:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -2343,7 +2343,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP137:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS23]], i32 0, i32 0 // CHECK3-NEXT: [[TMP138:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP139:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP139]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP139]], align 4 // CHECK3-NEXT: [[TMP140:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 1 // CHECK3-NEXT: store i32 10, ptr [[TMP140]], align 4 // CHECK3-NEXT: [[TMP141:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 2 @@ -2550,7 +2550,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[TMP17]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 // CHECK3-NEXT: [[TMP21:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP19]], 0 -// CHECK3-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META22]] +// CHECK3-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META22]] // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP22]], align 4, !noalias [[META22]] // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -3135,7 +3135,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3272,7 +3272,7 @@ int bar(int n){ // CHECK3-NEXT: [[ADD5:%.*]] = add i32 [[TMP30]], 1 // CHECK3-NEXT: [[TMP31:%.*]] = zext i32 [[ADD5]] to i64 // CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP32]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP32]], align 4 // CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP33]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3361,7 +3361,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_collapse_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_collapse_codegen.cpp index 2d886109b95b..52b40ede902c 100644 --- a/clang/test/OpenMP/target_teams_distribute_collapse_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_collapse_codegen.cpp @@ -124,7 +124,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -285,7 +285,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -514,7 +514,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK9-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP35]], 1 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -750,7 +750,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -975,7 +975,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK11-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP34]], 1 // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP36]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1209,7 +1209,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_dist_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_dist_schedule_codegen.cpp index 714ed708e71a..e898f6cff7e7 100644 --- a/clang/test/OpenMP/target_teams_distribute_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_dist_schedule_codegen.cpp @@ -161,7 +161,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -203,7 +203,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -245,7 +245,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -573,7 +573,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -615,7 +615,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -657,7 +657,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1030,7 +1030,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1101,7 +1101,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK9-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1183,7 +1183,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP97]], 1 // CHECK9-NEXT: [[TMP98:%.*]] = zext i32 [[ADD30]] to i64 // CHECK9-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP99]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP99]], align 4 // CHECK9-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP100]], align 4 // CHECK9-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -1619,7 +1619,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1660,7 +1660,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -1701,7 +1701,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK9-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -2071,7 +2071,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2143,7 +2143,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK11-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -2226,7 +2226,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP99]], 1 // CHECK11-NEXT: [[TMP100:%.*]] = zext i32 [[ADD30]] to i64 // CHECK11-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP101]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP101]], align 4 // CHECK11-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP102]], align 4 // CHECK11-NEXT: [[TMP103:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -2659,7 +2659,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2700,7 +2700,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -2741,7 +2741,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK11-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp index 1d6f69079df9..da69e19a890e 100644 --- a/clang/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_firstprivate_codegen.cpp @@ -303,7 +303,7 @@ int main() { // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -584,7 +584,7 @@ int main() { // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1105,7 +1105,7 @@ int main() { // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1384,7 +1384,7 @@ int main() { // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp index ffba1c2221c2..e23435d13e9a 100644 --- a/clang/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_lastprivate_codegen.cpp @@ -522,7 +522,7 @@ int main() { // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -837,7 +837,7 @@ int main() { // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1223,7 +1223,7 @@ int main() { // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1536,7 +1536,7 @@ int main() { // CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp index 7e06d8c16169..0d0d99674721 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp @@ -653,7 +653,7 @@ int target_teams_fun(int *g){ // CHECK2-NEXT: [[TMP29:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP23]], 0 // CHECK2-NEXT: [[TMP30:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP24]], 0 // CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP31]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP31]], align 4 // CHECK2-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK2-NEXT: store i32 4, ptr [[TMP32]], align 4 // CHECK2-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -720,7 +720,7 @@ int target_teams_fun(int *g){ // CHECK2-NEXT: [[ADD17:%.*]] = add nsw i32 [[TMP62]], 1 // CHECK2-NEXT: [[TMP63:%.*]] = zext i32 [[ADD17]] to i64 // CHECK2-NEXT: [[TMP64:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP64]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP64]], align 4 // CHECK2-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 1 // CHECK2-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK2-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 2 @@ -1295,7 +1295,7 @@ int target_teams_fun(int *g){ // CHECK4-NEXT: [[TMP29:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP23]], 0 // CHECK4-NEXT: [[TMP30:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP24]], 0 // CHECK4-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK4-NEXT: store i32 2, ptr [[TMP31]], align 4 +// CHECK4-NEXT: store i32 3, ptr [[TMP31]], align 4 // CHECK4-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK4-NEXT: store i32 4, ptr [[TMP32]], align 4 // CHECK4-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1362,7 +1362,7 @@ int target_teams_fun(int *g){ // CHECK4-NEXT: [[ADD17:%.*]] = add nsw i32 [[TMP62]], 1 // CHECK4-NEXT: [[TMP63:%.*]] = zext i32 [[ADD17]] to i64 // CHECK4-NEXT: [[TMP64:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 0 -// CHECK4-NEXT: store i32 2, ptr [[TMP64]], align 4 +// CHECK4-NEXT: store i32 3, ptr [[TMP64]], align 4 // CHECK4-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 1 // CHECK4-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK4-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_collapse_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_collapse_codegen.cpp index b812011ea4ca..da85b23de2e2 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_collapse_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_collapse_codegen.cpp @@ -129,7 +129,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -365,7 +365,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -665,7 +665,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK9-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP35]], 1 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1027,7 +1027,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1327,7 +1327,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK11-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP34]], 1 // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP36]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1691,7 +1691,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_codegen.cpp index 0aa75952a3c2..e0b722bd8046 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_dist_schedule_codegen.cpp @@ -173,7 +173,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -215,7 +215,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -257,7 +257,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -807,7 +807,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -849,7 +849,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -891,7 +891,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1476,7 +1476,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1547,7 +1547,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK9-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1629,7 +1629,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP97]], 1 // CHECK9-NEXT: [[TMP98:%.*]] = zext i32 [[ADD30]] to i64 // CHECK9-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP99]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP99]], align 4 // CHECK9-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP100]], align 4 // CHECK9-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -2394,7 +2394,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2435,7 +2435,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -2487,7 +2487,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK9-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK9-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK9-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK9-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK9-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -3096,7 +3096,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3168,7 +3168,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK11-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -3251,7 +3251,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP99]], 1 // CHECK11-NEXT: [[TMP100:%.*]] = zext i32 [[ADD30]] to i64 // CHECK11-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP101]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP101]], align 4 // CHECK11-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP102]], align 4 // CHECK11-NEXT: [[TMP103:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -4001,7 +4001,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4042,7 +4042,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -4094,7 +4094,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK11-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK11-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK11-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK11-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK11-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_codegen.cpp index 375279d96360..bf1fc1d7cbae 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_codegen.cpp @@ -364,7 +364,7 @@ int main() { // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -775,7 +775,7 @@ int main() { // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1426,7 +1426,7 @@ int main() { // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1831,7 +1831,7 @@ int main() { // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp index 9baf13385bef..9be3ca8fd758 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp @@ -113,7 +113,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -146,7 +146,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -476,7 +476,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -535,7 +535,7 @@ int main() { // CHECK1-NEXT: [[TMP25:%.*]] = select i1 [[TOBOOL4]], i32 0, i32 1 // CHECK1-NEXT: [[TMP26:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP25]], 0 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP28]], align 4 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -1035,7 +1035,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1090,7 +1090,7 @@ int main() { // CHECK1-NEXT: [[TMP24:%.*]] = select i1 [[TOBOOL3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP25:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP24]], 0 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP26]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP27]], align 4 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_codegen.cpp index e54c230eea7e..ae900d2dc53b 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_codegen.cpp @@ -783,7 +783,7 @@ int main() { // CHECK5-NEXT: [[TMP21:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP22:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK5-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 5, ptr [[TMP24]], align 4 // CHECK5-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1252,7 +1252,7 @@ int main() { // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK5-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1783,7 +1783,7 @@ int main() { // CHECK7-NEXT: [[TMP21:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP22:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK7-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 5, ptr [[TMP24]], align 4 // CHECK7-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2246,7 +2246,7 @@ int main() { // CHECK7-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK7-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK7-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp index feab9cdc948b..a64110f581df 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_order_codegen.cpp @@ -27,7 +27,7 @@ void gtid_test() { // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_private_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_private_codegen.cpp index 066d926e5abc..49e4681c0515 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_private_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_private_codegen.cpp @@ -301,7 +301,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -571,7 +571,7 @@ int main() { // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1034,7 +1034,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1298,7 +1298,7 @@ int main() { // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_proc_bind_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_proc_bind_codegen.cpp index 9f3e50fe20a6..caac6edfc51d 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_proc_bind_codegen.cpp @@ -58,7 +58,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -91,7 +91,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -409,7 +409,7 @@ int main() { // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_codegen.cpp index 1036ffd195de..d5f1b0b9e59d 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_codegen.cpp @@ -109,7 +109,7 @@ int main() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -400,7 +400,7 @@ int main() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -688,7 +688,7 @@ int main() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -975,7 +975,7 @@ int main() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp index 3d031e09aa07..fb0b2893d952 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp @@ -243,7 +243,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -285,7 +285,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -327,7 +327,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -369,7 +369,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK1-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -411,7 +411,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK1-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK1-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK1-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK1-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -1270,7 +1270,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1312,7 +1312,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -1354,7 +1354,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1396,7 +1396,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK3-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -1438,7 +1438,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK3-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK3-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK3-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK3-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -2270,7 +2270,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK5-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2312,7 +2312,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK5-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK5-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK5-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK5-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -2354,7 +2354,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK5-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK5-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK5-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK5-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -2396,7 +2396,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK5-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK5-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK5-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK5-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -2438,7 +2438,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK5-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK5-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK5-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK5-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -3297,7 +3297,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK7-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK7-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3339,7 +3339,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK7-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK7-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK7-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK7-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -3381,7 +3381,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK7-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK7-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK7-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK7-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -3423,7 +3423,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK7-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK7-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK7-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK7-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -3465,7 +3465,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK7-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK7-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK7-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK7-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -4357,7 +4357,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK13-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK13-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK13-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK13-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4428,7 +4428,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK13-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK13-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK13-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK13-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -4510,7 +4510,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP97]], 1 // CHECK13-NEXT: [[TMP98:%.*]] = zext i32 [[ADD30]] to i64 // CHECK13-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP99]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP99]], align 4 // CHECK13-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK13-NEXT: store i32 4, ptr [[TMP100]], align 4 // CHECK13-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -4581,7 +4581,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP132]], 1 // CHECK13-NEXT: [[TMP133:%.*]] = zext i32 [[ADD45]] to i64 // CHECK13-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP134]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP134]], align 4 // CHECK13-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP135]], align 4 // CHECK13-NEXT: [[TMP136:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 2 @@ -4663,7 +4663,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD62:%.*]] = add nsw i32 [[TMP173]], 1 // CHECK13-NEXT: [[TMP174:%.*]] = zext i32 [[ADD62]] to i64 // CHECK13-NEXT: [[TMP175:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP175]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP175]], align 4 // CHECK13-NEXT: [[TMP176:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 1 // CHECK13-NEXT: store i32 4, ptr [[TMP176]], align 4 // CHECK13-NEXT: [[TMP177:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 2 @@ -5881,7 +5881,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK13-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK13-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5922,7 +5922,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK13-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK13-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK13-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK13-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -5974,7 +5974,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK13-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK13-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK13-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK13-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK13-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -6015,7 +6015,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK13-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK13-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP71]], align 4 // CHECK13-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP72]], align 4 // CHECK13-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -6067,7 +6067,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP95:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS24]], i32 0, i32 0 // CHECK13-NEXT: [[TMP96:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS25]], i32 0, i32 0 // CHECK13-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP97]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP97]], align 4 // CHECK13-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK13-NEXT: store i32 2, ptr [[TMP98]], align 4 // CHECK13-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -7008,7 +7008,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK15-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK15-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK15-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK15-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK15-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7080,7 +7080,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK15-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK15-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK15-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK15-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK15-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -7163,7 +7163,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP99]], 1 // CHECK15-NEXT: [[TMP100:%.*]] = zext i32 [[ADD30]] to i64 // CHECK15-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP101]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP101]], align 4 // CHECK15-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK15-NEXT: store i32 4, ptr [[TMP102]], align 4 // CHECK15-NEXT: [[TMP103:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -7235,7 +7235,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP135]], 1 // CHECK15-NEXT: [[TMP136:%.*]] = zext i32 [[ADD45]] to i64 // CHECK15-NEXT: [[TMP137:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP137]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP137]], align 4 // CHECK15-NEXT: [[TMP138:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 1 // CHECK15-NEXT: store i32 3, ptr [[TMP138]], align 4 // CHECK15-NEXT: [[TMP139:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 2 @@ -7318,7 +7318,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD62:%.*]] = add nsw i32 [[TMP177]], 1 // CHECK15-NEXT: [[TMP178:%.*]] = zext i32 [[ADD62]] to i64 // CHECK15-NEXT: [[TMP179:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP179]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP179]], align 4 // CHECK15-NEXT: [[TMP180:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 1 // CHECK15-NEXT: store i32 4, ptr [[TMP180]], align 4 // CHECK15-NEXT: [[TMP181:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 2 @@ -8511,7 +8511,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK15-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK15-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK15-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK15-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK15-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -8552,7 +8552,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK15-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK15-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK15-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK15-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK15-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -8604,7 +8604,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK15-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK15-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK15-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK15-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK15-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -8645,7 +8645,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK15-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK15-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP71]], align 4 // CHECK15-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK15-NEXT: store i32 1, ptr [[TMP72]], align 4 // CHECK15-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -8697,7 +8697,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP95:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS24]], i32 0, i32 0 // CHECK15-NEXT: [[TMP96:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS25]], i32 0, i32 0 // CHECK15-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP97]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP97]], align 4 // CHECK15-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK15-NEXT: store i32 2, ptr [[TMP98]], align 4 // CHECK15-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -9611,7 +9611,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK17-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK17-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK17-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -9682,7 +9682,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK17-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK17-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK17-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK17-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -9764,7 +9764,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP97]], 1 // CHECK17-NEXT: [[TMP98:%.*]] = zext i32 [[ADD30]] to i64 // CHECK17-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP99]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP99]], align 4 // CHECK17-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK17-NEXT: store i32 4, ptr [[TMP100]], align 4 // CHECK17-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -9835,7 +9835,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP132]], 1 // CHECK17-NEXT: [[TMP133:%.*]] = zext i32 [[ADD45]] to i64 // CHECK17-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP134]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP134]], align 4 // CHECK17-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP135]], align 4 // CHECK17-NEXT: [[TMP136:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 2 @@ -9917,7 +9917,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD62:%.*]] = add nsw i32 [[TMP173]], 1 // CHECK17-NEXT: [[TMP174:%.*]] = zext i32 [[ADD62]] to i64 // CHECK17-NEXT: [[TMP175:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP175]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP175]], align 4 // CHECK17-NEXT: [[TMP176:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 1 // CHECK17-NEXT: store i32 4, ptr [[TMP176]], align 4 // CHECK17-NEXT: [[TMP177:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 2 @@ -11135,7 +11135,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK17-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK17-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -11176,7 +11176,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK17-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK17-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK17-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK17-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -11228,7 +11228,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK17-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK17-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK17-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK17-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -11269,7 +11269,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK17-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK17-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP71]], align 4 // CHECK17-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP72]], align 4 // CHECK17-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -11321,7 +11321,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP95:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS24]], i32 0, i32 0 // CHECK17-NEXT: [[TMP96:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS25]], i32 0, i32 0 // CHECK17-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP97]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP97]], align 4 // CHECK17-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP98]], align 4 // CHECK17-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -12262,7 +12262,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK19-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK19-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK19-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -12334,7 +12334,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK19-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK19-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK19-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK19-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -12417,7 +12417,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP99]], 1 // CHECK19-NEXT: [[TMP100:%.*]] = zext i32 [[ADD30]] to i64 // CHECK19-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP101]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP101]], align 4 // CHECK19-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK19-NEXT: store i32 4, ptr [[TMP102]], align 4 // CHECK19-NEXT: [[TMP103:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -12489,7 +12489,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP135]], 1 // CHECK19-NEXT: [[TMP136:%.*]] = zext i32 [[ADD45]] to i64 // CHECK19-NEXT: [[TMP137:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP137]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP137]], align 4 // CHECK19-NEXT: [[TMP138:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP138]], align 4 // CHECK19-NEXT: [[TMP139:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 2 @@ -12572,7 +12572,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD62:%.*]] = add nsw i32 [[TMP177]], 1 // CHECK19-NEXT: [[TMP178:%.*]] = zext i32 [[ADD62]] to i64 // CHECK19-NEXT: [[TMP179:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP179]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP179]], align 4 // CHECK19-NEXT: [[TMP180:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 1 // CHECK19-NEXT: store i32 4, ptr [[TMP180]], align 4 // CHECK19-NEXT: [[TMP181:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 2 @@ -13765,7 +13765,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK19-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK19-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -13806,7 +13806,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK19-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK19-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK19-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK19-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -13858,7 +13858,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK19-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK19-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK19-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK19-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -13899,7 +13899,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK19-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK19-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP71]], align 4 // CHECK19-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP72]], align 4 // CHECK19-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -13951,7 +13951,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP95:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS24]], i32 0, i32 0 // CHECK19-NEXT: [[TMP96:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS25]], i32 0, i32 0 // CHECK19-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP97]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP97]], align 4 // CHECK19-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP98]], align 4 // CHECK19-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp index 109063c623a1..a4119a07f61f 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp @@ -181,7 +181,7 @@ void test_target_teams_atomic() { // CHECK1-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP28]], 0 // CHECK1-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP29]], 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -248,7 +248,7 @@ void test_target_teams_atomic() { // CHECK1-NEXT: [[ADD17:%.*]] = add nsw i32 [[TMP67]], 1 // CHECK1-NEXT: [[TMP68:%.*]] = zext i32 [[ADD17]] to i64 // CHECK1-NEXT: [[TMP69:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP69]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP69]], align 4 // CHECK1-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP70]], align 4 // CHECK1-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 2 @@ -821,7 +821,7 @@ void test_target_teams_atomic() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1116,7 +1116,7 @@ void test_target_teams_atomic() { // CHECK3-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP28]], 0 // CHECK3-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP29]], 0 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1183,7 +1183,7 @@ void test_target_teams_atomic() { // CHECK3-NEXT: [[ADD17:%.*]] = add nsw i32 [[TMP67]], 1 // CHECK3-NEXT: [[TMP68:%.*]] = zext i32 [[ADD17]] to i64 // CHECK3-NEXT: [[TMP69:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP69]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP69]], align 4 // CHECK3-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP70]], align 4 // CHECK3-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 2 @@ -1746,7 +1746,7 @@ void test_target_teams_atomic() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_codegen.cpp index 306ec1db2ab2..53a13e129d3b 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_codegen.cpp @@ -129,7 +129,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -381,7 +381,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -837,7 +837,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK9-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP35]], 1 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1235,7 +1235,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1551,7 +1551,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK11-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP34]], 1 // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP36]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1951,7 +1951,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp index c265c1c616b1..d449406927e7 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp @@ -173,7 +173,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -215,7 +215,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -257,7 +257,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -849,7 +849,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -891,7 +891,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -933,7 +933,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1807,7 +1807,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1878,7 +1878,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK9-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1960,7 +1960,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP97]], 1 // CHECK9-NEXT: [[TMP98:%.*]] = zext i32 [[ADD30]] to i64 // CHECK9-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP99]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP99]], align 4 // CHECK9-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP100]], align 4 // CHECK9-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -2797,7 +2797,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2838,7 +2838,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -2890,7 +2890,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK9-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK9-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK9-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK9-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK9-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -3541,7 +3541,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3613,7 +3613,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK11-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -3696,7 +3696,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP99]], 1 // CHECK11-NEXT: [[TMP100:%.*]] = zext i32 [[ADD30]] to i64 // CHECK11-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP101]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP101]], align 4 // CHECK11-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP102]], align 4 // CHECK11-NEXT: [[TMP103:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -4518,7 +4518,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4559,7 +4559,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -4611,7 +4611,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK11-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK11-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK11-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK11-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK11-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_codegen.cpp index 37c1f428ef9a..ea05aecebf37 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_codegen.cpp @@ -362,7 +362,7 @@ int main() { // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -787,7 +787,7 @@ int main() { // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1452,7 +1452,7 @@ int main() { // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1871,7 +1871,7 @@ int main() { // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp index df5dd7ba6805..71f4506fb634 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp @@ -130,7 +130,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -163,7 +163,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP22]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP23]], align 4 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -536,7 +536,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -595,7 +595,7 @@ int main() { // CHECK1-NEXT: [[TMP25:%.*]] = select i1 [[TOBOOL4]], i32 0, i32 1 // CHECK1-NEXT: [[TMP26:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP25]], 0 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP28]], align 4 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -1137,7 +1137,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1192,7 +1192,7 @@ int main() { // CHECK1-NEXT: [[TMP24:%.*]] = select i1 [[TOBOOL3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP25:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP24]], 0 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP26]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP27]], align 4 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -1735,7 +1735,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1768,7 +1768,7 @@ int main() { // CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK3: omp_offload.cont: // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP22]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP23]], align 4 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -2141,7 +2141,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2200,7 +2200,7 @@ int main() { // CHECK3-NEXT: [[TMP25:%.*]] = select i1 [[TOBOOL4]], i32 0, i32 1 // CHECK3-NEXT: [[TMP26:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP25]], 0 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP28]], align 4 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -2972,7 +2972,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK3-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3027,7 +3027,7 @@ int main() { // CHECK3-NEXT: [[TMP24:%.*]] = select i1 [[TOBOOL3]], i32 0, i32 1 // CHECK3-NEXT: [[TMP25:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP24]], 0 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP26]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP27]], align 4 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -4163,7 +4163,7 @@ int main() { // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4196,7 +4196,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP22]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -4569,7 +4569,7 @@ int main() { // CHECK9-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4628,7 +4628,7 @@ int main() { // CHECK9-NEXT: [[TMP25:%.*]] = select i1 [[TOBOOL4]], i32 0, i32 1 // CHECK9-NEXT: [[TMP26:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP25]], 0 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP28]], align 4 // CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -5170,7 +5170,7 @@ int main() { // CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5225,7 +5225,7 @@ int main() { // CHECK9-NEXT: [[TMP24:%.*]] = select i1 [[TOBOOL3]], i32 0, i32 1 // CHECK9-NEXT: [[TMP25:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP24]], 0 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP26]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP27]], align 4 // CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -5768,7 +5768,7 @@ int main() { // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5801,7 +5801,7 @@ int main() { // CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK11: omp_offload.cont: // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP22]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -6174,7 +6174,7 @@ int main() { // CHECK11-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK11-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6233,7 +6233,7 @@ int main() { // CHECK11-NEXT: [[TMP25:%.*]] = select i1 [[TOBOOL4]], i32 0, i32 1 // CHECK11-NEXT: [[TMP26:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP25]], 0 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP28]], align 4 // CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -7005,7 +7005,7 @@ int main() { // CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK11-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7060,7 +7060,7 @@ int main() { // CHECK11-NEXT: [[TMP24:%.*]] = select i1 [[TOBOOL3]], i32 0, i32 1 // CHECK11-NEXT: [[TMP25:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP24]], 0 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP26]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP27]], align 4 // CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_codegen.cpp index 3fdc0c482541..b2b9e2082fa3 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_codegen.cpp @@ -811,7 +811,7 @@ int main() { // CHECK5-NEXT: [[TMP21:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP22:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK5-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 5, ptr [[TMP24]], align 4 // CHECK5-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1294,7 +1294,7 @@ int main() { // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK5-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1839,7 +1839,7 @@ int main() { // CHECK7-NEXT: [[TMP21:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP22:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK7-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 5, ptr [[TMP24]], align 4 // CHECK7-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2316,7 +2316,7 @@ int main() { // CHECK7-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK7-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK7-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_private_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_private_codegen.cpp index bba97a750adc..0cc07c86aaea 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_private_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_private_codegen.cpp @@ -301,7 +301,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -585,7 +585,7 @@ int main() { // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1062,7 +1062,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1340,7 +1340,7 @@ int main() { // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_proc_bind_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_proc_bind_codegen.cpp index c347743bd4fd..7619bf7502e7 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_proc_bind_codegen.cpp @@ -58,7 +58,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -91,7 +91,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -437,7 +437,7 @@ int main() { // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_codegen.cpp index 52430d51cde1..3bff9904850f 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_codegen.cpp @@ -109,7 +109,7 @@ int main() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -414,7 +414,7 @@ int main() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -716,7 +716,7 @@ int main() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1017,7 +1017,7 @@ int main() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp index f7c0666d58b6..b92dd14de108 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp @@ -243,7 +243,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -285,7 +285,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -327,7 +327,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -369,7 +369,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK1-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -411,7 +411,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK1-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK1-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK1-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK1-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -1340,7 +1340,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1382,7 +1382,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -1424,7 +1424,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1466,7 +1466,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK3-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -1508,7 +1508,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK3-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK3-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK3-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK3-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -2410,7 +2410,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK5-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2452,7 +2452,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK5-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK5-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK5-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK5-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -2494,7 +2494,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK5-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK5-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK5-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK5-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -2536,7 +2536,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK5-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK5-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK5-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK5-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -2578,7 +2578,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK5-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK5-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK5-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK5-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -3507,7 +3507,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK7-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK7-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3549,7 +3549,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK7-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK7-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK7-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK7-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -3591,7 +3591,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK7-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK7-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK7-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK7-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -3633,7 +3633,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK7-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK7-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK7-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK7-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -3675,7 +3675,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK7-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK7-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK7-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK7-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -5022,7 +5022,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK13-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK13-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK13-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK13-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5093,7 +5093,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK13-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK13-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK13-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK13-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -5175,7 +5175,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP97]], 1 // CHECK13-NEXT: [[TMP98:%.*]] = zext i32 [[ADD30]] to i64 // CHECK13-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP99]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP99]], align 4 // CHECK13-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK13-NEXT: store i32 4, ptr [[TMP100]], align 4 // CHECK13-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -5246,7 +5246,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP132]], 1 // CHECK13-NEXT: [[TMP133:%.*]] = zext i32 [[ADD45]] to i64 // CHECK13-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP134]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP134]], align 4 // CHECK13-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP135]], align 4 // CHECK13-NEXT: [[TMP136:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 2 @@ -5328,7 +5328,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD62:%.*]] = add nsw i32 [[TMP173]], 1 // CHECK13-NEXT: [[TMP174:%.*]] = zext i32 [[ADD62]] to i64 // CHECK13-NEXT: [[TMP175:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP175]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP175]], align 4 // CHECK13-NEXT: [[TMP176:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 1 // CHECK13-NEXT: store i32 4, ptr [[TMP176]], align 4 // CHECK13-NEXT: [[TMP177:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 2 @@ -6666,7 +6666,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK13-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK13-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6707,7 +6707,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK13-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK13-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK13-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK13-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -6759,7 +6759,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK13-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK13-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK13-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK13-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK13-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -6800,7 +6800,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK13-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK13-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP71]], align 4 // CHECK13-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP72]], align 4 // CHECK13-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -6852,7 +6852,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP95:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS24]], i32 0, i32 0 // CHECK13-NEXT: [[TMP96:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS25]], i32 0, i32 0 // CHECK13-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP97]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP97]], align 4 // CHECK13-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK13-NEXT: store i32 2, ptr [[TMP98]], align 4 // CHECK13-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -7863,7 +7863,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK15-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK15-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK15-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK15-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK15-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7935,7 +7935,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK15-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK15-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK15-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK15-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK15-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -8018,7 +8018,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP99]], 1 // CHECK15-NEXT: [[TMP100:%.*]] = zext i32 [[ADD30]] to i64 // CHECK15-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP101]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP101]], align 4 // CHECK15-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK15-NEXT: store i32 4, ptr [[TMP102]], align 4 // CHECK15-NEXT: [[TMP103:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -8090,7 +8090,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP135]], 1 // CHECK15-NEXT: [[TMP136:%.*]] = zext i32 [[ADD45]] to i64 // CHECK15-NEXT: [[TMP137:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP137]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP137]], align 4 // CHECK15-NEXT: [[TMP138:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 1 // CHECK15-NEXT: store i32 3, ptr [[TMP138]], align 4 // CHECK15-NEXT: [[TMP139:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 2 @@ -8173,7 +8173,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD62:%.*]] = add nsw i32 [[TMP177]], 1 // CHECK15-NEXT: [[TMP178:%.*]] = zext i32 [[ADD62]] to i64 // CHECK15-NEXT: [[TMP179:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP179]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP179]], align 4 // CHECK15-NEXT: [[TMP180:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 1 // CHECK15-NEXT: store i32 4, ptr [[TMP180]], align 4 // CHECK15-NEXT: [[TMP181:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 2 @@ -9486,7 +9486,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK15-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK15-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK15-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK15-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK15-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -9527,7 +9527,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK15-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK15-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK15-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK15-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK15-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -9579,7 +9579,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK15-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK15-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK15-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK15-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK15-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -9620,7 +9620,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK15-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK15-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP71]], align 4 // CHECK15-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK15-NEXT: store i32 1, ptr [[TMP72]], align 4 // CHECK15-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -9672,7 +9672,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP95:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS24]], i32 0, i32 0 // CHECK15-NEXT: [[TMP96:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS25]], i32 0, i32 0 // CHECK15-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP97]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP97]], align 4 // CHECK15-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK15-NEXT: store i32 2, ptr [[TMP98]], align 4 // CHECK15-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -10656,7 +10656,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK17-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK17-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK17-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -10727,7 +10727,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK17-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK17-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK17-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK17-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -10809,7 +10809,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP97]], 1 // CHECK17-NEXT: [[TMP98:%.*]] = zext i32 [[ADD30]] to i64 // CHECK17-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP99]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP99]], align 4 // CHECK17-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK17-NEXT: store i32 4, ptr [[TMP100]], align 4 // CHECK17-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -10880,7 +10880,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP132]], 1 // CHECK17-NEXT: [[TMP133:%.*]] = zext i32 [[ADD45]] to i64 // CHECK17-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP134]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP134]], align 4 // CHECK17-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP135]], align 4 // CHECK17-NEXT: [[TMP136:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 2 @@ -10962,7 +10962,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD62:%.*]] = add nsw i32 [[TMP173]], 1 // CHECK17-NEXT: [[TMP174:%.*]] = zext i32 [[ADD62]] to i64 // CHECK17-NEXT: [[TMP175:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP175]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP175]], align 4 // CHECK17-NEXT: [[TMP176:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 1 // CHECK17-NEXT: store i32 4, ptr [[TMP176]], align 4 // CHECK17-NEXT: [[TMP177:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 2 @@ -12300,7 +12300,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK17-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK17-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -12341,7 +12341,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK17-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK17-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK17-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK17-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -12393,7 +12393,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK17-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK17-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK17-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK17-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -12434,7 +12434,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK17-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK17-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP71]], align 4 // CHECK17-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP72]], align 4 // CHECK17-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -12486,7 +12486,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP95:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS24]], i32 0, i32 0 // CHECK17-NEXT: [[TMP96:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS25]], i32 0, i32 0 // CHECK17-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP97]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP97]], align 4 // CHECK17-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP98]], align 4 // CHECK17-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -13497,7 +13497,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK19-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK19-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK19-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -13569,7 +13569,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK19-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK19-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK19-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK19-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -13652,7 +13652,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP99]], 1 // CHECK19-NEXT: [[TMP100:%.*]] = zext i32 [[ADD30]] to i64 // CHECK19-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP101]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP101]], align 4 // CHECK19-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK19-NEXT: store i32 4, ptr [[TMP102]], align 4 // CHECK19-NEXT: [[TMP103:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -13724,7 +13724,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP135]], 1 // CHECK19-NEXT: [[TMP136:%.*]] = zext i32 [[ADD45]] to i64 // CHECK19-NEXT: [[TMP137:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP137]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP137]], align 4 // CHECK19-NEXT: [[TMP138:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP138]], align 4 // CHECK19-NEXT: [[TMP139:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS46]], i32 0, i32 2 @@ -13807,7 +13807,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD62:%.*]] = add nsw i32 [[TMP177]], 1 // CHECK19-NEXT: [[TMP178:%.*]] = zext i32 [[ADD62]] to i64 // CHECK19-NEXT: [[TMP179:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP179]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP179]], align 4 // CHECK19-NEXT: [[TMP180:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 1 // CHECK19-NEXT: store i32 4, ptr [[TMP180]], align 4 // CHECK19-NEXT: [[TMP181:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS63]], i32 0, i32 2 @@ -15120,7 +15120,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK19-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK19-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -15161,7 +15161,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK19-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK19-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK19-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK19-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -15213,7 +15213,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK19-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK19-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK19-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK19-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -15254,7 +15254,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK19-NEXT: [[TMP70:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK19-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP71]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP71]], align 4 // CHECK19-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP72]], align 4 // CHECK19-NEXT: [[TMP73:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -15306,7 +15306,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP95:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS24]], i32 0, i32 0 // CHECK19-NEXT: [[TMP96:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS25]], i32 0, i32 0 // CHECK19-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP97]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP97]], align 4 // CHECK19-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP98]], align 4 // CHECK19-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_private_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_private_codegen.cpp index 5bc78062c830..3cb2d2c2f9b4 100644 --- a/clang/test/OpenMP/target_teams_distribute_private_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_private_codegen.cpp @@ -240,7 +240,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -409,7 +409,7 @@ int main() { // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -768,7 +768,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -935,7 +935,7 @@ int main() { // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_reduction_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_reduction_codegen.cpp index 9e9306a5e749..47251b00c7a1 100644 --- a/clang/test/OpenMP/target_teams_distribute_reduction_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_reduction_codegen.cpp @@ -335,7 +335,7 @@ int main() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -376,7 +376,7 @@ int main() { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -418,7 +418,7 @@ int main() { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -460,7 +460,7 @@ int main() { // CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK1-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -502,7 +502,7 @@ int main() { // CHECK1-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS22]], i32 0, i32 0 // CHECK1-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS23]], i32 0, i32 0 // CHECK1-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK1-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK1-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 2 @@ -544,7 +544,7 @@ int main() { // CHECK1-NEXT: [[TMP103:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS29]], i32 0, i32 0 // CHECK1-NEXT: [[TMP104:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS30]], i32 0, i32 0 // CHECK1-NEXT: [[TMP105:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP105]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP105]], align 4 // CHECK1-NEXT: [[TMP106:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP106]], align 4 // CHECK1-NEXT: [[TMP107:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 2 @@ -585,7 +585,7 @@ int main() { // CHECK1-NEXT: [[TMP123:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS36]], i32 0, i32 0 // CHECK1-NEXT: [[TMP124:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS37]], i32 0, i32 0 // CHECK1-NEXT: [[TMP125:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP125]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP125]], align 4 // CHECK1-NEXT: [[TMP126:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP126]], align 4 // CHECK1-NEXT: [[TMP127:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 2 @@ -626,7 +626,7 @@ int main() { // CHECK1-NEXT: [[TMP143:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS43]], i32 0, i32 0 // CHECK1-NEXT: [[TMP144:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS44]], i32 0, i32 0 // CHECK1-NEXT: [[TMP145:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP145]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP145]], align 4 // CHECK1-NEXT: [[TMP146:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP146]], align 4 // CHECK1-NEXT: [[TMP147:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 2 @@ -668,7 +668,7 @@ int main() { // CHECK1-NEXT: [[TMP163:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS50]], i32 0, i32 0 // CHECK1-NEXT: [[TMP164:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS51]], i32 0, i32 0 // CHECK1-NEXT: [[TMP165:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP165]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP165]], align 4 // CHECK1-NEXT: [[TMP166:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP166]], align 4 // CHECK1-NEXT: [[TMP167:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 2 @@ -710,7 +710,7 @@ int main() { // CHECK1-NEXT: [[TMP183:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS57]], i32 0, i32 0 // CHECK1-NEXT: [[TMP184:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS58]], i32 0, i32 0 // CHECK1-NEXT: [[TMP185:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP185]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP185]], align 4 // CHECK1-NEXT: [[TMP186:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP186]], align 4 // CHECK1-NEXT: [[TMP187:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 @@ -2179,7 +2179,7 @@ int main() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2226,7 +2226,7 @@ int main() { // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -2274,7 +2274,7 @@ int main() { // CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK1-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK1-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK1-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -2322,7 +2322,7 @@ int main() { // CHECK1-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK1-NEXT: [[TMP73:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK1-NEXT: [[TMP74:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP74]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP74]], align 4 // CHECK1-NEXT: [[TMP75:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP75]], align 4 // CHECK1-NEXT: [[TMP76:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -2370,7 +2370,7 @@ int main() { // CHECK1-NEXT: [[TMP95:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS22]], i32 0, i32 0 // CHECK1-NEXT: [[TMP96:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS23]], i32 0, i32 0 // CHECK1-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP97]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP97]], align 4 // CHECK1-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP98]], align 4 // CHECK1-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 2 @@ -2418,7 +2418,7 @@ int main() { // CHECK1-NEXT: [[TMP118:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS29]], i32 0, i32 0 // CHECK1-NEXT: [[TMP119:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS30]], i32 0, i32 0 // CHECK1-NEXT: [[TMP120:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP120]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP120]], align 4 // CHECK1-NEXT: [[TMP121:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP121]], align 4 // CHECK1-NEXT: [[TMP122:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 2 @@ -2465,7 +2465,7 @@ int main() { // CHECK1-NEXT: [[TMP141:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS36]], i32 0, i32 0 // CHECK1-NEXT: [[TMP142:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS37]], i32 0, i32 0 // CHECK1-NEXT: [[TMP143:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP143]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP143]], align 4 // CHECK1-NEXT: [[TMP144:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP144]], align 4 // CHECK1-NEXT: [[TMP145:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 2 @@ -2512,7 +2512,7 @@ int main() { // CHECK1-NEXT: [[TMP164:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS43]], i32 0, i32 0 // CHECK1-NEXT: [[TMP165:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS44]], i32 0, i32 0 // CHECK1-NEXT: [[TMP166:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP166]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP166]], align 4 // CHECK1-NEXT: [[TMP167:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP167]], align 4 // CHECK1-NEXT: [[TMP168:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 2 @@ -2560,7 +2560,7 @@ int main() { // CHECK1-NEXT: [[TMP187:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS50]], i32 0, i32 0 // CHECK1-NEXT: [[TMP188:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS51]], i32 0, i32 0 // CHECK1-NEXT: [[TMP189:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP189]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP189]], align 4 // CHECK1-NEXT: [[TMP190:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP190]], align 4 // CHECK1-NEXT: [[TMP191:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 2 @@ -2608,7 +2608,7 @@ int main() { // CHECK1-NEXT: [[TMP210:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS57]], i32 0, i32 0 // CHECK1-NEXT: [[TMP211:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS58]], i32 0, i32 0 // CHECK1-NEXT: [[TMP212:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP212]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP212]], align 4 // CHECK1-NEXT: [[TMP213:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP213]], align 4 // CHECK1-NEXT: [[TMP214:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 @@ -4163,7 +4163,7 @@ int main() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4204,7 +4204,7 @@ int main() { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -4246,7 +4246,7 @@ int main() { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -4288,7 +4288,7 @@ int main() { // CHECK3-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK3-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -4330,7 +4330,7 @@ int main() { // CHECK3-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS22]], i32 0, i32 0 // CHECK3-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS23]], i32 0, i32 0 // CHECK3-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK3-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK3-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 2 @@ -4372,7 +4372,7 @@ int main() { // CHECK3-NEXT: [[TMP103:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS29]], i32 0, i32 0 // CHECK3-NEXT: [[TMP104:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS30]], i32 0, i32 0 // CHECK3-NEXT: [[TMP105:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP105]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP105]], align 4 // CHECK3-NEXT: [[TMP106:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP106]], align 4 // CHECK3-NEXT: [[TMP107:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 2 @@ -4413,7 +4413,7 @@ int main() { // CHECK3-NEXT: [[TMP123:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS36]], i32 0, i32 0 // CHECK3-NEXT: [[TMP124:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS37]], i32 0, i32 0 // CHECK3-NEXT: [[TMP125:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP125]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP125]], align 4 // CHECK3-NEXT: [[TMP126:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP126]], align 4 // CHECK3-NEXT: [[TMP127:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 2 @@ -4454,7 +4454,7 @@ int main() { // CHECK3-NEXT: [[TMP143:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS43]], i32 0, i32 0 // CHECK3-NEXT: [[TMP144:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS44]], i32 0, i32 0 // CHECK3-NEXT: [[TMP145:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP145]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP145]], align 4 // CHECK3-NEXT: [[TMP146:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP146]], align 4 // CHECK3-NEXT: [[TMP147:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 2 @@ -4496,7 +4496,7 @@ int main() { // CHECK3-NEXT: [[TMP163:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS50]], i32 0, i32 0 // CHECK3-NEXT: [[TMP164:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS51]], i32 0, i32 0 // CHECK3-NEXT: [[TMP165:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP165]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP165]], align 4 // CHECK3-NEXT: [[TMP166:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP166]], align 4 // CHECK3-NEXT: [[TMP167:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 2 @@ -4538,7 +4538,7 @@ int main() { // CHECK3-NEXT: [[TMP183:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS57]], i32 0, i32 0 // CHECK3-NEXT: [[TMP184:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS58]], i32 0, i32 0 // CHECK3-NEXT: [[TMP185:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP185]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP185]], align 4 // CHECK3-NEXT: [[TMP186:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP186]], align 4 // CHECK3-NEXT: [[TMP187:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 @@ -6007,7 +6007,7 @@ int main() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6054,7 +6054,7 @@ int main() { // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -6102,7 +6102,7 @@ int main() { // CHECK3-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK3-NEXT: [[TMP50:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK3-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP51]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP51]], align 4 // CHECK3-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP52]], align 4 // CHECK3-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -6150,7 +6150,7 @@ int main() { // CHECK3-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK3-NEXT: [[TMP73:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK3-NEXT: [[TMP74:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP74]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP74]], align 4 // CHECK3-NEXT: [[TMP75:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP75]], align 4 // CHECK3-NEXT: [[TMP76:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -6198,7 +6198,7 @@ int main() { // CHECK3-NEXT: [[TMP95:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS22]], i32 0, i32 0 // CHECK3-NEXT: [[TMP96:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS23]], i32 0, i32 0 // CHECK3-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP97]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP97]], align 4 // CHECK3-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP98]], align 4 // CHECK3-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS26]], i32 0, i32 2 @@ -6246,7 +6246,7 @@ int main() { // CHECK3-NEXT: [[TMP118:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS29]], i32 0, i32 0 // CHECK3-NEXT: [[TMP119:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS30]], i32 0, i32 0 // CHECK3-NEXT: [[TMP120:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP120]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP120]], align 4 // CHECK3-NEXT: [[TMP121:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP121]], align 4 // CHECK3-NEXT: [[TMP122:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS33]], i32 0, i32 2 @@ -6293,7 +6293,7 @@ int main() { // CHECK3-NEXT: [[TMP141:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS36]], i32 0, i32 0 // CHECK3-NEXT: [[TMP142:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS37]], i32 0, i32 0 // CHECK3-NEXT: [[TMP143:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP143]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP143]], align 4 // CHECK3-NEXT: [[TMP144:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP144]], align 4 // CHECK3-NEXT: [[TMP145:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS40]], i32 0, i32 2 @@ -6340,7 +6340,7 @@ int main() { // CHECK3-NEXT: [[TMP164:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS43]], i32 0, i32 0 // CHECK3-NEXT: [[TMP165:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS44]], i32 0, i32 0 // CHECK3-NEXT: [[TMP166:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP166]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP166]], align 4 // CHECK3-NEXT: [[TMP167:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP167]], align 4 // CHECK3-NEXT: [[TMP168:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS47]], i32 0, i32 2 @@ -6388,7 +6388,7 @@ int main() { // CHECK3-NEXT: [[TMP187:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS50]], i32 0, i32 0 // CHECK3-NEXT: [[TMP188:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS51]], i32 0, i32 0 // CHECK3-NEXT: [[TMP189:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP189]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP189]], align 4 // CHECK3-NEXT: [[TMP190:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP190]], align 4 // CHECK3-NEXT: [[TMP191:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS54]], i32 0, i32 2 @@ -6436,7 +6436,7 @@ int main() { // CHECK3-NEXT: [[TMP210:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS57]], i32 0, i32 0 // CHECK3-NEXT: [[TMP211:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS58]], i32 0, i32 0 // CHECK3-NEXT: [[TMP212:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP212]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP212]], align 4 // CHECK3-NEXT: [[TMP213:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP213]], align 4 // CHECK3-NEXT: [[TMP214:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp index 5091d41eec4f..d2a5d1f62a8b 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp @@ -424,7 +424,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP50:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK1-NEXT: [[TMP51:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP52]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP52]], align 4 // CHECK1-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP53]], align 4 // CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -481,7 +481,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS10]], i32 0, i32 0 // CHECK1-NEXT: [[TMP79:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP80:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP80]], align 4 // CHECK1-NEXT: [[TMP81:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP81]], align 4 // CHECK1-NEXT: [[TMP82:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -591,7 +591,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP131:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS21]], i32 0, i32 0 // CHECK1-NEXT: [[TMP132:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP133:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP133]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP133]], align 4 // CHECK1-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 1 // CHECK1-NEXT: store i32 9, ptr [[TMP134]], align 4 // CHECK1-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 2 @@ -803,7 +803,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 -// CHECK1-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META26]] +// CHECK1-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META26]] // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP20]], align 4, !noalias [[META26]] // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -1392,7 +1392,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1529,7 +1529,7 @@ int bar(int n){ // CHECK1-NEXT: [[ADD5:%.*]] = add i32 [[TMP30]], 1 // CHECK1-NEXT: [[TMP31:%.*]] = zext i32 [[ADD5]] to i64 // CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP32]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP32]], align 4 // CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP33]], align 4 // CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1618,7 +1618,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2186,7 +2186,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP48:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK3-NEXT: [[TMP49:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK3-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK3-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP51]], align 4 // CHECK3-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2243,7 +2243,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS10]], i32 0, i32 0 // CHECK3-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP78:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP78]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP78]], align 4 // CHECK3-NEXT: [[TMP79:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP79]], align 4 // CHECK3-NEXT: [[TMP80:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -2355,7 +2355,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP131:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS21]], i32 0, i32 0 // CHECK3-NEXT: [[TMP132:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP133:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP133]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP133]], align 4 // CHECK3-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 1 // CHECK3-NEXT: store i32 9, ptr [[TMP134]], align 4 // CHECK3-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 2 @@ -2567,7 +2567,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 -// CHECK3-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META27]] +// CHECK3-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META27]] // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP20]], align 4, !noalias [[META27]] // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -3156,7 +3156,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [5 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP30]], align 4 // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3293,7 +3293,7 @@ int bar(int n){ // CHECK3-NEXT: [[ADD5:%.*]] = add i32 [[TMP30]], 1 // CHECK3-NEXT: [[TMP31:%.*]] = zext i32 [[ADD5]] to i64 // CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP32]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP32]], align 4 // CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP33]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3382,7 +3382,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3952,7 +3952,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP50:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK5-NEXT: [[TMP51:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK5-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP52]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP52]], align 4 // CHECK5-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP53]], align 4 // CHECK5-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4009,7 +4009,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS10]], i32 0, i32 0 // CHECK5-NEXT: [[TMP79:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CHECK5-NEXT: [[TMP80:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP80]], align 4 // CHECK5-NEXT: [[TMP81:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK5-NEXT: store i32 2, ptr [[TMP81]], align 4 // CHECK5-NEXT: [[TMP82:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -4119,7 +4119,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP131:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS21]], i32 0, i32 0 // CHECK5-NEXT: [[TMP132:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK5-NEXT: [[TMP133:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP133]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP133]], align 4 // CHECK5-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 1 // CHECK5-NEXT: store i32 9, ptr [[TMP134]], align 4 // CHECK5-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 2 @@ -4331,7 +4331,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK5-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP16]], align 4 // CHECK5-NEXT: [[TMP19:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 -// CHECK5-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META26]] +// CHECK5-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META26]] // CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK5-NEXT: store i32 3, ptr [[TMP20]], align 4, !noalias [[META26]] // CHECK5-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -4937,7 +4937,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP33:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP34:%.*]] = getelementptr inbounds [6 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK5-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK5-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 6, ptr [[TMP36]], align 4 // CHECK5-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5074,7 +5074,7 @@ int bar(int n){ // CHECK5-NEXT: [[ADD5:%.*]] = add i32 [[TMP30]], 1 // CHECK5-NEXT: [[TMP31:%.*]] = zext i32 [[ADD5]] to i64 // CHECK5-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP32]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP32]], align 4 // CHECK5-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 5, ptr [[TMP33]], align 4 // CHECK5-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5163,7 +5163,7 @@ int bar(int n){ // CHECK5-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5783,7 +5783,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP48:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS5]], i32 0, i32 0 // CHECK7-NEXT: [[TMP49:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS6]], i32 0, i32 0 // CHECK7-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK7-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP51]], align 4 // CHECK7-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5840,7 +5840,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS10]], i32 0, i32 0 // CHECK7-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS11]], i32 0, i32 0 // CHECK7-NEXT: [[TMP78:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP78]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP78]], align 4 // CHECK7-NEXT: [[TMP79:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 1 // CHECK7-NEXT: store i32 2, ptr [[TMP79]], align 4 // CHECK7-NEXT: [[TMP80:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS14]], i32 0, i32 2 @@ -5952,7 +5952,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP131:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS21]], i32 0, i32 0 // CHECK7-NEXT: [[TMP132:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK7-NEXT: [[TMP133:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP133]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP133]], align 4 // CHECK7-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 1 // CHECK7-NEXT: store i32 9, ptr [[TMP134]], align 4 // CHECK7-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS24]], i32 0, i32 2 @@ -6164,7 +6164,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[TMP9]], i32 0, i32 2 // CHECK7-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP16]], align 4 // CHECK7-NEXT: [[TMP19:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 -// CHECK7-NEXT: store i32 2, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META27]] +// CHECK7-NEXT: store i32 3, ptr [[KERNEL_ARGS_I]], align 4, !noalias [[META27]] // CHECK7-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 1 // CHECK7-NEXT: store i32 3, ptr [[TMP20]], align 4, !noalias [[META27]] // CHECK7-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS_I]], i32 0, i32 2 @@ -6770,7 +6770,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP33:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP34:%.*]] = getelementptr inbounds [6 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK7-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK7-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 6, ptr [[TMP36]], align 4 // CHECK7-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6907,7 +6907,7 @@ int bar(int n){ // CHECK7-NEXT: [[ADD5:%.*]] = add i32 [[TMP30]], 1 // CHECK7-NEXT: [[TMP31:%.*]] = zext i32 [[ADD5]] to i64 // CHECK7-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP32]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP32]], align 4 // CHECK7-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 5, ptr [[TMP33]], align 4 // CHECK7-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6996,7 +6996,7 @@ int bar(int n){ // CHECK7-NEXT: [[TMP14:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK7-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 3, ptr [[TMP17]], align 4 // CHECK7-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_simd_collapse_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_collapse_codegen.cpp index ac7fc7c1acf9..b052a2200479 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_collapse_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_collapse_codegen.cpp @@ -124,7 +124,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -293,7 +293,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -670,7 +670,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK9-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP35]], 1 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -924,7 +924,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1157,7 +1157,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK11-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP34]], 1 // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP36]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1409,7 +1409,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_codegen.cpp index 867ec8942140..7f7e83c4dee3 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_dist_schedule_codegen.cpp @@ -161,7 +161,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -203,7 +203,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -245,7 +245,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -594,7 +594,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -636,7 +636,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -678,7 +678,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1319,7 +1319,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1390,7 +1390,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK9-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1472,7 +1472,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP97]], 1 // CHECK9-NEXT: [[TMP98:%.*]] = zext i32 [[ADD30]] to i64 // CHECK9-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP99]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP99]], align 4 // CHECK9-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP100]], align 4 // CHECK9-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -1944,7 +1944,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1985,7 +1985,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -2026,7 +2026,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK9-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -2417,7 +2417,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2489,7 +2489,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK11-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -2572,7 +2572,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP99]], 1 // CHECK11-NEXT: [[TMP100:%.*]] = zext i32 [[ADD30]] to i64 // CHECK11-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP101]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP101]], align 4 // CHECK11-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP102]], align 4 // CHECK11-NEXT: [[TMP103:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -3041,7 +3041,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3082,7 +3082,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -3123,7 +3123,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK11-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp index 425bcaf6c3f3..d22aeee120d5 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp @@ -303,7 +303,7 @@ int main() { // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -591,7 +591,7 @@ int main() { // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1119,7 +1119,7 @@ int main() { // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1405,7 +1405,7 @@ int main() { // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp index 4c9e83afb3bb..93c570ac0604 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_codegen.cpp @@ -572,7 +572,7 @@ int main() { // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -894,7 +894,7 @@ int main() { // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1287,7 +1287,7 @@ int main() { // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1607,7 +1607,7 @@ int main() { // CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP19]], align 4 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp index 6cfec0010d00..4e9b4e1027e6 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp @@ -240,7 +240,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -416,7 +416,7 @@ int main() { // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -782,7 +782,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -956,7 +956,7 @@ int main() { // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp index 1481b4fe85fd..667450c32f1d 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp @@ -97,7 +97,7 @@ int main() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -281,7 +281,7 @@ int main() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -462,7 +462,7 @@ int main() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -646,7 +646,7 @@ int main() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_generic_loop_codegen-1.cpp b/clang/test/OpenMP/target_teams_generic_loop_codegen-1.cpp index 190ea17e9607..ec806081a3e4 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_codegen-1.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_codegen-1.cpp @@ -635,7 +635,7 @@ int target_teams_fun(int *g){ // CHECK2-NEXT: [[TMP27:%.*]] = zext i32 [[ADD]] to i64 // CHECK2-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP23]], 0 // CHECK2-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK2-NEXT: store i32 4, ptr [[TMP30]], align 4 // CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -702,7 +702,7 @@ int target_teams_fun(int *g){ // CHECK2-NEXT: [[ADD17:%.*]] = add nsw i32 [[TMP60]], 1 // CHECK2-NEXT: [[TMP61:%.*]] = zext i32 [[ADD17]] to i64 // CHECK2-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP62]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP62]], align 4 // CHECK2-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 1 // CHECK2-NEXT: store i32 3, ptr [[TMP63]], align 4 // CHECK2-NEXT: [[TMP64:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 2 @@ -1260,7 +1260,7 @@ int target_teams_fun(int *g){ // CHECK4-NEXT: [[TMP27:%.*]] = zext i32 [[ADD]] to i64 // CHECK4-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP23]], 0 // CHECK4-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK4-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK4-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK4-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK4-NEXT: store i32 4, ptr [[TMP30]], align 4 // CHECK4-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1327,7 +1327,7 @@ int target_teams_fun(int *g){ // CHECK4-NEXT: [[ADD17:%.*]] = add nsw i32 [[TMP60]], 1 // CHECK4-NEXT: [[TMP61:%.*]] = zext i32 [[ADD17]] to i64 // CHECK4-NEXT: [[TMP62:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 0 -// CHECK4-NEXT: store i32 2, ptr [[TMP62]], align 4 +// CHECK4-NEXT: store i32 3, ptr [[TMP62]], align 4 // CHECK4-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 1 // CHECK4-NEXT: store i32 3, ptr [[TMP63]], align 4 // CHECK4-NEXT: [[TMP64:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS18]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_generic_loop_collapse_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_collapse_codegen.cpp index 82ad43373327..f4aea067ba22 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_collapse_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_collapse_codegen.cpp @@ -129,7 +129,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -365,7 +365,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -665,7 +665,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK9-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP35]], 1 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1027,7 +1027,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1327,7 +1327,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK11-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP34]], 1 // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP36]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1691,7 +1691,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_generic_loop_if_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_if_codegen.cpp index b2ff4c20db7a..1edcbfe2d777 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_if_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_if_codegen.cpp @@ -111,7 +111,7 @@ int main() { // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -437,7 +437,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS6:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -496,7 +496,7 @@ int main() { // CHECK1-NEXT: [[TMP25:%.*]] = select i1 [[TOBOOL4]], i32 0, i32 1 // CHECK1-NEXT: [[TMP26:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP25]], 0 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP27]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP27]], align 4 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP28]], align 4 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -991,7 +991,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1029,7 +1029,7 @@ int main() { // CHECK1-NEXT: br i1 [[TOBOOL]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] // CHECK1: omp_if.then: // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_generic_loop_order_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_order_codegen.cpp index 85f6a85a11bd..fbf7b004d5ef 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_order_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_order_codegen.cpp @@ -27,7 +27,7 @@ void gtid_test() { // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_generic_loop_private_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_private_codegen.cpp index 7503b69b92aa..99416f76e409 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_private_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_private_codegen.cpp @@ -301,7 +301,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -571,7 +571,7 @@ int main() { // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1034,7 +1034,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1298,7 +1298,7 @@ int main() { // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_generic_loop_reduction_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_reduction_codegen.cpp index 1036ffd195de..d5f1b0b9e59d 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_reduction_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_reduction_codegen.cpp @@ -109,7 +109,7 @@ int main() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -400,7 +400,7 @@ int main() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -688,7 +688,7 @@ int main() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -975,7 +975,7 @@ int main() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_generic_loop_uses_allocators_codegen.cpp b/clang/test/OpenMP/target_teams_generic_loop_uses_allocators_codegen.cpp index 0dc2c95641e2..5001f9cc8915 100644 --- a/clang/test/OpenMP/target_teams_generic_loop_uses_allocators_codegen.cpp +++ b/clang/test/OpenMP/target_teams_generic_loop_uses_allocators_codegen.cpp @@ -291,7 +291,7 @@ void foo() { // CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_map_codegen.cpp b/clang/test/OpenMP/target_teams_map_codegen.cpp index 9ccf74514691..974ba36e6bb0 100644 --- a/clang/test/OpenMP/target_teams_map_codegen.cpp +++ b/clang/test/OpenMP/target_teams_map_codegen.cpp @@ -100,7 +100,7 @@ void mapInt128() { // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP8]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP9]], align 4 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -178,7 +178,7 @@ void mapInt128() { // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP8]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP9]], align 4 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -272,7 +272,7 @@ void mapInt128() { // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP8]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP9]], align 4 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -416,7 +416,7 @@ void mapInt128() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -494,7 +494,7 @@ void mapInt128() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -572,7 +572,7 @@ void mapInt128() { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -668,7 +668,7 @@ void mapInt128() { // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP11]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP12]], align 4 // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -721,7 +721,7 @@ void mapInt128() { // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP38]], align 4 // CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 2 @@ -1031,7 +1031,7 @@ void mapInt128() { // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP11]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP12]], align 4 // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1084,7 +1084,7 @@ void mapInt128() { // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP38]], align 4 // CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 2 @@ -1327,7 +1327,7 @@ void mapInt128() { // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP8]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP9]], align 4 // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1405,7 +1405,7 @@ void mapInt128() { // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP8]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP9]], align 4 // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1499,7 +1499,7 @@ void mapInt128() { // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP8]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP9]], align 4 // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1643,7 +1643,7 @@ void mapInt128() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1721,7 +1721,7 @@ void mapInt128() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1799,7 +1799,7 @@ void mapInt128() { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1895,7 +1895,7 @@ void mapInt128() { // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP11]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP12]], align 4 // CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1948,7 +1948,7 @@ void mapInt128() { // CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP37]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP38]], align 4 // CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS4]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_num_teams_codegen.cpp b/clang/test/OpenMP/target_teams_num_teams_codegen.cpp index e5618aefaf3c..ba01a411670c 100644 --- a/clang/test/OpenMP/target_teams_num_teams_codegen.cpp +++ b/clang/test/OpenMP/target_teams_num_teams_codegen.cpp @@ -256,7 +256,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP17]], 0 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -298,7 +298,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP39]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP39]], align 4 // CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP40]], align 4 // CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -369,7 +369,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP8]], 0 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP10]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP10]], align 4 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP11]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -418,7 +418,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP33:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK1-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 // CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP36]], align 4 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -473,7 +473,7 @@ int bar(int n){ // CHECK1-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4 // CHECK1-NEXT: store i32 0, ptr [[A]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -541,7 +541,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP34:%.*]] = sext i16 [[TMP33]] to i32 // CHECK1-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP34]], 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 2 @@ -834,7 +834,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP17]], 0 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -876,7 +876,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP39]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP39]], align 4 // CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP40]], align 4 // CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -947,7 +947,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP8]], 0 // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP10]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP10]], align 4 // CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP11]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -996,7 +996,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP33:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 // CHECK3-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 // CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP36]], align 4 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -1051,7 +1051,7 @@ int bar(int n){ // CHECK3-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4 // CHECK3-NEXT: store i32 0, ptr [[A]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1119,7 +1119,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP34:%.*]] = sext i16 [[TMP33]] to i32 // CHECK3-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP34]], 0 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 2 diff --git a/clang/test/OpenMP/target_teams_thread_limit_codegen.cpp b/clang/test/OpenMP/target_teams_thread_limit_codegen.cpp index b6593b7e5368..c081f6e52d7a 100644 --- a/clang/test/OpenMP/target_teams_thread_limit_codegen.cpp +++ b/clang/test/OpenMP/target_teams_thread_limit_codegen.cpp @@ -256,7 +256,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK1-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP17]], 0 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -298,7 +298,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP39]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP39]], align 4 // CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP40]], align 4 // CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -385,7 +385,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP16:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP14]], 0 // CHECK1-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -434,7 +434,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP41:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_3]], align 4 // CHECK1-NEXT: [[TMP42:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP41]], 0 // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP43]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP43]], align 4 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP44]], align 4 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 @@ -489,7 +489,7 @@ int bar(int n){ // CHECK1-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4 // CHECK1-NEXT: store i32 0, ptr [[A]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -557,7 +557,7 @@ int bar(int n){ // CHECK1-NEXT: [[TMP34:%.*]] = sext i16 [[TMP33]] to i32 // CHECK1-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP34]], 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 2 @@ -853,7 +853,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 // CHECK3-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP17]], 0 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -895,7 +895,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP39]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP39]], align 4 // CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP40]], align 4 // CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS6]], i32 0, i32 2 @@ -982,7 +982,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP16:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP14]], 0 // CHECK3-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP19]], align 4 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1031,7 +1031,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP41:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_3]], align 4 // CHECK3-NEXT: [[TMP42:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP41]], 0 // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP43]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP43]], align 4 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP44]], align 4 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 @@ -1086,7 +1086,7 @@ int bar(int n){ // CHECK3-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4 // CHECK3-NEXT: store i32 0, ptr [[A]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1154,7 +1154,7 @@ int bar(int n){ // CHECK3-NEXT: [[TMP34:%.*]] = sext i16 [[TMP33]] to i32 // CHECK3-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP34]], 0 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP37]], align 4 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS1]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_codegen.cpp b/clang/test/OpenMP/teams_codegen.cpp index 4aab9dae2d6a..91702fb47af7 100644 --- a/clang/test/OpenMP/teams_codegen.cpp +++ b/clang/test/OpenMP/teams_codegen.cpp @@ -361,7 +361,7 @@ void foo() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -405,7 +405,7 @@ void foo() { // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 // CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -460,7 +460,7 @@ void foo() { // CHECK1-NEXT: [[TMP56:%.*]] = load i32, ptr [[LA]], align 4 // CHECK1-NEXT: [[TMP57:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP56]], 0 // CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP59]], align 4 // CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -515,7 +515,7 @@ void foo() { // CHECK1-NEXT: [[TMP85:%.*]] = load i32, ptr [[LA]], align 4 // CHECK1-NEXT: [[TMP86:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP85]], 0 // CHECK1-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP87]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP87]], align 4 // CHECK1-NEXT: [[TMP88:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP88]], align 4 // CHECK1-NEXT: [[TMP89:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 @@ -605,7 +605,7 @@ void foo() { // CHECK1-NEXT: [[TMP134:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[ADD]], 0 // CHECK1-NEXT: [[TMP135:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP133]], 0 // CHECK1-NEXT: [[TMP136:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP136]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP136]], align 4 // CHECK1-NEXT: [[TMP137:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP137]], align 4 // CHECK1-NEXT: [[TMP138:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -670,7 +670,7 @@ void foo() { // CHECK1-NEXT: [[TMP168:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[ADD36]], 0 // CHECK1-NEXT: [[TMP169:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[ADD38]], 0 // CHECK1-NEXT: [[TMP170:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS39]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP170]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP170]], align 4 // CHECK1-NEXT: [[TMP171:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS39]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP171]], align 4 // CHECK1-NEXT: [[TMP172:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS39]], i32 0, i32 2 @@ -963,7 +963,7 @@ void foo() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1007,7 +1007,7 @@ void foo() { // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 // CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP30]], align 4 // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -1062,7 +1062,7 @@ void foo() { // CHECK3-NEXT: [[TMP56:%.*]] = load i32, ptr [[LA]], align 4 // CHECK3-NEXT: [[TMP57:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP56]], 0 // CHECK3-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP59]], align 4 // CHECK3-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -1117,7 +1117,7 @@ void foo() { // CHECK3-NEXT: [[TMP85:%.*]] = load i32, ptr [[LA]], align 4 // CHECK3-NEXT: [[TMP86:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP85]], 0 // CHECK3-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP87]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP87]], align 4 // CHECK3-NEXT: [[TMP88:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP88]], align 4 // CHECK3-NEXT: [[TMP89:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 @@ -1204,7 +1204,7 @@ void foo() { // CHECK3-NEXT: [[TMP132:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[ADD]], 0 // CHECK3-NEXT: [[TMP133:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP131]], 0 // CHECK3-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP134]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP134]], align 4 // CHECK3-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP135]], align 4 // CHECK3-NEXT: [[TMP136:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS28]], i32 0, i32 2 @@ -1269,7 +1269,7 @@ void foo() { // CHECK3-NEXT: [[TMP166:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[ADD36]], 0 // CHECK3-NEXT: [[TMP167:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[ADD38]], 0 // CHECK3-NEXT: [[TMP168:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS39]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP168]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP168]], align 4 // CHECK3-NEXT: [[TMP169:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS39]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP169]], align 4 // CHECK3-NEXT: [[TMP170:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS39]], i32 0, i32 2 @@ -1552,7 +1552,7 @@ void foo() { // CHECK9-NEXT: [[TMP16:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP13]], 0 // CHECK9-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1616,7 +1616,7 @@ void foo() { // CHECK9-NEXT: [[TMP50:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP47]], 0 // CHECK9-NEXT: [[TMP51:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP49]], 0 // CHECK9-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP52]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP52]], align 4 // CHECK9-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP53]], align 4 // CHECK9-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -1779,7 +1779,7 @@ void foo() { // CHECK11-NEXT: [[TMP16:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP13]], 0 // CHECK11-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1843,7 +1843,7 @@ void foo() { // CHECK11-NEXT: [[TMP50:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP47]], 0 // CHECK11-NEXT: [[TMP51:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP49]], 0 // CHECK11-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP52]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP52]], align 4 // CHECK11-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP53]], align 4 // CHECK11-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -2006,7 +2006,7 @@ void foo() { // CHECK17-NEXT: [[TMP10:%.*]] = load i32, ptr [[A2]], align 4 // CHECK17-NEXT: [[TMP11:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP10]], 0 // CHECK17-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP12]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP12]], align 4 // CHECK17-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP13]], align 4 // CHECK17-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2062,7 +2062,7 @@ void foo() { // CHECK17-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], 123 // CHECK17-NEXT: [[TMP38:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[ADD]], 0 // CHECK17-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP39]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP39]], align 4 // CHECK17-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP40]], align 4 // CHECK17-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 @@ -2212,7 +2212,7 @@ void foo() { // CHECK19-NEXT: [[TMP10:%.*]] = load i32, ptr [[A2]], align 4 // CHECK19-NEXT: [[TMP11:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP10]], 0 // CHECK19-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP12]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP12]], align 4 // CHECK19-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP13]], align 4 // CHECK19-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2268,7 +2268,7 @@ void foo() { // CHECK19-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], 123 // CHECK19-NEXT: [[TMP38:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[ADD]], 0 // CHECK19-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP39]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP39]], align 4 // CHECK19-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP40]], align 4 // CHECK19-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_codegen.cpp b/clang/test/OpenMP/teams_distribute_codegen.cpp index 0bfadcf70d9b..11b5c9a21298 100644 --- a/clang/test/OpenMP/teams_distribute_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_codegen.cpp @@ -254,7 +254,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP27:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP21]], 0 // CHECK1-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP22]], 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -314,7 +314,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK1-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP59]], align 4 // CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -645,7 +645,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP27:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP21]], 0 // CHECK3-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP22]], 0 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP30]], align 4 // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -705,7 +705,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK3-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK3-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP59]], align 4 // CHECK3-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1016,7 +1016,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1226,7 +1226,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1403,7 +1403,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK17-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK17-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1548,7 +1548,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK19-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK19-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1730,7 +1730,7 @@ int main (int argc, char **argv) { // CHECK25-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK25-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK25-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK25-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK25-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK25-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK25-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK25-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1929,7 +1929,7 @@ int main (int argc, char **argv) { // CHECK25-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK25-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK25-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK25-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK25-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK25-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK25-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK25-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2116,7 +2116,7 @@ int main (int argc, char **argv) { // CHECK27-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK27-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK27-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK27-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK27-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK27-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK27-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK27-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2314,7 +2314,7 @@ int main (int argc, char **argv) { // CHECK27-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK27-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK27-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK27-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK27-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK27-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK27-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK27-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_collapse_codegen.cpp b/clang/test/OpenMP/teams_distribute_collapse_codegen.cpp index 178af730a8d4..42b355f39e6b 100644 --- a/clang/test/OpenMP/teams_distribute_collapse_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_collapse_codegen.cpp @@ -127,7 +127,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -288,7 +288,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -517,7 +517,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK9-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP35]], 1 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -747,7 +747,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -972,7 +972,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK11-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP34]], 1 // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP36]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1200,7 +1200,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_dist_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_dist_schedule_codegen.cpp index f21c7e9be920..39c260996fcb 100644 --- a/clang/test/OpenMP/teams_distribute_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_dist_schedule_codegen.cpp @@ -170,7 +170,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -212,7 +212,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -254,7 +254,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -582,7 +582,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -624,7 +624,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -666,7 +666,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1037,7 +1037,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1108,7 +1108,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK9-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1179,7 +1179,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP91]], 1 // CHECK9-NEXT: [[TMP92:%.*]] = zext i32 [[ADD29]] to i64 // CHECK9-NEXT: [[TMP93:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP93]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP93]], align 4 // CHECK9-NEXT: [[TMP94:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP94]], align 4 // CHECK9-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -1607,7 +1607,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1648,7 +1648,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -1689,7 +1689,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK9-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -2057,7 +2057,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2129,7 +2129,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK11-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -2201,7 +2201,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP93]], 1 // CHECK11-NEXT: [[TMP94:%.*]] = zext i32 [[ADD29]] to i64 // CHECK11-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP95]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP95]], align 4 // CHECK11-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP96]], align 4 // CHECK11-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -2626,7 +2626,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2667,7 +2667,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -2708,7 +2708,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK11-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_firstprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_firstprivate_codegen.cpp index 57175e72b79f..8b3e657428ec 100644 --- a/clang/test/OpenMP/teams_distribute_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_firstprivate_codegen.cpp @@ -306,7 +306,7 @@ int main() { // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -589,7 +589,7 @@ int main() { // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1110,7 +1110,7 @@ int main() { // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1391,7 +1391,7 @@ int main() { // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_lastprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_lastprivate_codegen.cpp index 5ee4a5ce9e29..66c952f3281f 100644 --- a/clang/test/OpenMP/teams_distribute_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_lastprivate_codegen.cpp @@ -518,7 +518,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -829,7 +829,7 @@ int main() { // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1214,7 +1214,7 @@ int main() { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1523,7 +1523,7 @@ int main() { // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp index a13b565cb38d..85b20e9b21cf 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_codegen.cpp @@ -254,7 +254,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP27:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP21]], 0 // CHECK1-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP22]], 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -314,7 +314,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK1-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP59]], align 4 // CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -856,7 +856,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP27:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP21]], 0 // CHECK3-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP22]], 0 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP30]], align 4 // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -916,7 +916,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK3-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK3-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP59]], align 4 // CHECK3-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1430,7 +1430,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1741,7 +1741,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2015,7 +2015,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK17-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK17-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2233,7 +2233,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK19-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK19-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2484,7 +2484,7 @@ int main (int argc, char **argv) { // CHECK25-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK25-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK25-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK25-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK25-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK25-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK25-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK25-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2784,7 +2784,7 @@ int main (int argc, char **argv) { // CHECK25-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK25-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK25-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK25-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK25-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK25-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK25-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK25-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3044,7 +3044,7 @@ int main (int argc, char **argv) { // CHECK27-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK27-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK27-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK27-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK27-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK27-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK27-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK27-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3339,7 +3339,7 @@ int main (int argc, char **argv) { // CHECK27-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK27-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK27-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK27-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK27-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK27-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK27-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK27-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp index 64ee660b706c..f1c74bd6a0d7 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_collapse_codegen.cpp @@ -132,7 +132,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -368,7 +368,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -668,7 +668,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK9-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP35]], 1 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1018,7 +1018,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1318,7 +1318,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK11-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP34]], 1 // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP36]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1670,7 +1670,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp index 37d19f86a950..2fda35f3e000 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp @@ -123,7 +123,7 @@ int main() { // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP11]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP12]], align 4 // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -347,7 +347,7 @@ int main() { // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP11]], align 4 // CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP12]], align 4 // CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -578,7 +578,7 @@ int main() { // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP11]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP12]], align 4 // CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -797,7 +797,7 @@ int main() { // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP11]], align 4 // CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP12]], align 4 // CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp index eb3d2fc84568..070bb1ce3fed 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_dist_schedule_codegen.cpp @@ -182,7 +182,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -224,7 +224,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -266,7 +266,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -816,7 +816,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -858,7 +858,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -900,7 +900,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1484,7 +1484,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1555,7 +1555,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK9-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1635,7 +1635,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP96]], 1 // CHECK9-NEXT: [[TMP97:%.*]] = zext i32 [[ADD29]] to i64 // CHECK9-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP98]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP98]], align 4 // CHECK9-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP99]], align 4 // CHECK9-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -2384,7 +2384,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2425,7 +2425,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -2475,7 +2475,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK9-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK9-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK9-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK9-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK9-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -3086,7 +3086,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3158,7 +3158,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK11-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -3239,7 +3239,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP98]], 1 // CHECK11-NEXT: [[TMP99:%.*]] = zext i32 [[ADD29]] to i64 // CHECK11-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK11-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP101]], align 4 // CHECK11-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -3973,7 +3973,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4014,7 +4014,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -4064,7 +4064,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK11-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK11-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK11-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK11-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK11-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp index 904e6a1c1ce7..0726fb659e7d 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_firstprivate_codegen.cpp @@ -340,7 +340,7 @@ int main() { // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -753,7 +753,7 @@ int main() { // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1404,7 +1404,7 @@ int main() { // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1811,7 +1811,7 @@ int main() { // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp index 49ff6a5d08be..aed27c47fa1d 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_if_codegen.cpp @@ -121,7 +121,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -154,7 +154,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -486,7 +486,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -519,7 +519,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -571,7 +571,7 @@ int main() { // CHECK1-NEXT: [[TMP39:%.*]] = select i1 [[TOBOOL5]], i32 0, i32 1 // CHECK1-NEXT: [[TMP40:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP39]], 0 // CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP41]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP41]], align 4 // CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP42]], align 4 // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -1073,7 +1073,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1106,7 +1106,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1158,7 +1158,7 @@ int main() { // CHECK1-NEXT: [[TMP39:%.*]] = select i1 [[TOBOOL5]], i32 0, i32 1 // CHECK1-NEXT: [[TMP40:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP39]], 0 // CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP41]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP41]], align 4 // CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP42]], align 4 // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp index 7b8df7367b82..06fc87d7da4c 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_lastprivate_codegen.cpp @@ -766,7 +766,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1225,7 +1225,7 @@ int main() { // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1752,7 +1752,7 @@ int main() { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2205,7 +2205,7 @@ int main() { // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp index a7b1f6eb309e..6b200403637b 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp @@ -97,7 +97,7 @@ int main() { // CHECK1: invoke.cont: // CHECK1-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -155,7 +155,7 @@ int main() { // CHECK1-NEXT: [[TMP27:%.*]] = zext i8 [[TMP26]] to i32 // CHECK1-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP27]], 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -556,7 +556,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -589,7 +589,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -634,7 +634,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -676,7 +676,7 @@ int main() { // CHECK1-NEXT: [[TMP16:%.*]] = zext i8 [[TMP15]] to i32 // CHECK1-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1384,7 +1384,7 @@ int main() { // CHECK5: invoke.cont: // CHECK5-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1442,7 +1442,7 @@ int main() { // CHECK5-NEXT: [[TMP27:%.*]] = zext i8 [[TMP26]] to i32 // CHECK5-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP27]], 0 // CHECK5-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK5-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP30]], align 4 // CHECK5-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1843,7 +1843,7 @@ int main() { // CHECK5-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1876,7 +1876,7 @@ int main() { // CHECK5-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK5: omp_offload.cont: // CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1921,7 +1921,7 @@ int main() { // CHECK5-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1963,7 +1963,7 @@ int main() { // CHECK5-NEXT: [[TMP16:%.*]] = zext i8 [[TMP15]] to i32 // CHECK5-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK5-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP19]], align 4 // CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp index dc430fc55787..4d10d16f47ed 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_private_codegen.cpp @@ -263,7 +263,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -533,7 +533,7 @@ int main() { // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -996,7 +996,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1260,7 +1260,7 @@ int main() { // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp index 386e772b7897..5e3962d96121 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_proc_bind_codegen.cpp @@ -60,7 +60,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -93,7 +93,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -411,7 +411,7 @@ int main() { // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp index 7ac42579e91b..2e800745baf2 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_reduction_codegen.cpp @@ -116,7 +116,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -410,7 +410,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -701,7 +701,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -991,7 +991,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp index 7518179f4776..2dd2302c0f2c 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp @@ -257,7 +257,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -299,7 +299,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -341,7 +341,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -383,7 +383,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK1-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -425,7 +425,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK1-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK1-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK1-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK1-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -1284,7 +1284,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1326,7 +1326,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -1368,7 +1368,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1410,7 +1410,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK3-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -1452,7 +1452,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK3-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK3-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK3-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK3-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -2284,7 +2284,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK5-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2326,7 +2326,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK5-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK5-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK5-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK5-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -2368,7 +2368,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK5-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK5-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK5-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK5-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -2410,7 +2410,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK5-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK5-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK5-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK5-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -2452,7 +2452,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK5-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK5-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK5-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK5-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -3311,7 +3311,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK7-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK7-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK7-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3353,7 +3353,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK7-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK7-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK7-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK7-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -3395,7 +3395,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK7-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK7-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK7-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK7-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -3437,7 +3437,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK7-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK7-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK7-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK7-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -3479,7 +3479,7 @@ int main (int argc, char **argv) { // CHECK7-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK7-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK7-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK7-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK7-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK7-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK7-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK7-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -4369,7 +4369,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK13-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK13-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK13-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK13-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4440,7 +4440,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK13-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK13-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK13-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK13-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -4520,7 +4520,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP96]], 1 // CHECK13-NEXT: [[TMP97:%.*]] = zext i32 [[ADD29]] to i64 // CHECK13-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP98]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP98]], align 4 // CHECK13-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK13-NEXT: store i32 4, ptr [[TMP99]], align 4 // CHECK13-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -4591,7 +4591,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD44:%.*]] = add nsw i32 [[TMP131]], 1 // CHECK13-NEXT: [[TMP132:%.*]] = zext i32 [[ADD44]] to i64 // CHECK13-NEXT: [[TMP133:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP133]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP133]], align 4 // CHECK13-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP134]], align 4 // CHECK13-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 2 @@ -4671,7 +4671,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD60:%.*]] = add nsw i32 [[TMP171]], 1 // CHECK13-NEXT: [[TMP172:%.*]] = zext i32 [[ADD60]] to i64 // CHECK13-NEXT: [[TMP173:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP173]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP173]], align 4 // CHECK13-NEXT: [[TMP174:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK13-NEXT: store i32 4, ptr [[TMP174]], align 4 // CHECK13-NEXT: [[TMP175:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 @@ -5863,7 +5863,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK13-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK13-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5904,7 +5904,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK13-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK13-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK13-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK13-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -5954,7 +5954,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK13-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK13-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK13-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK13-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK13-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -5995,7 +5995,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP68:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK13-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK13-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP70]], align 4 // CHECK13-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP71]], align 4 // CHECK13-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -6045,7 +6045,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP93:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS23]], i32 0, i32 0 // CHECK13-NEXT: [[TMP94:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS24]], i32 0, i32 0 // CHECK13-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP95]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP95]], align 4 // CHECK13-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 1 // CHECK13-NEXT: store i32 2, ptr [[TMP96]], align 4 // CHECK13-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 2 @@ -6990,7 +6990,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK15-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK15-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK15-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK15-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK15-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7062,7 +7062,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK15-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK15-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK15-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK15-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK15-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -7143,7 +7143,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP98]], 1 // CHECK15-NEXT: [[TMP99:%.*]] = zext i32 [[ADD29]] to i64 // CHECK15-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK15-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK15-NEXT: store i32 4, ptr [[TMP101]], align 4 // CHECK15-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -7215,7 +7215,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD44:%.*]] = add nsw i32 [[TMP134]], 1 // CHECK15-NEXT: [[TMP135:%.*]] = zext i32 [[ADD44]] to i64 // CHECK15-NEXT: [[TMP136:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP136]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP136]], align 4 // CHECK15-NEXT: [[TMP137:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 1 // CHECK15-NEXT: store i32 3, ptr [[TMP137]], align 4 // CHECK15-NEXT: [[TMP138:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 2 @@ -7296,7 +7296,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[ADD60:%.*]] = add nsw i32 [[TMP175]], 1 // CHECK15-NEXT: [[TMP176:%.*]] = zext i32 [[ADD60]] to i64 // CHECK15-NEXT: [[TMP177:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP177]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP177]], align 4 // CHECK15-NEXT: [[TMP178:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK15-NEXT: store i32 4, ptr [[TMP178]], align 4 // CHECK15-NEXT: [[TMP179:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 @@ -8463,7 +8463,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK15-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK15-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK15-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK15-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK15-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -8504,7 +8504,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK15-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK15-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK15-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK15-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK15-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -8554,7 +8554,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK15-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK15-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK15-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK15-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK15-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -8595,7 +8595,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP68:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK15-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK15-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP70]], align 4 // CHECK15-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK15-NEXT: store i32 1, ptr [[TMP71]], align 4 // CHECK15-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -8645,7 +8645,7 @@ int main (int argc, char **argv) { // CHECK15-NEXT: [[TMP93:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS23]], i32 0, i32 0 // CHECK15-NEXT: [[TMP94:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS24]], i32 0, i32 0 // CHECK15-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 0 -// CHECK15-NEXT: store i32 2, ptr [[TMP95]], align 4 +// CHECK15-NEXT: store i32 3, ptr [[TMP95]], align 4 // CHECK15-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 1 // CHECK15-NEXT: store i32 2, ptr [[TMP96]], align 4 // CHECK15-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 2 @@ -9563,7 +9563,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK17-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK17-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK17-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -9634,7 +9634,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK17-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK17-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK17-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK17-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -9714,7 +9714,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP96]], 1 // CHECK17-NEXT: [[TMP97:%.*]] = zext i32 [[ADD29]] to i64 // CHECK17-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP98]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP98]], align 4 // CHECK17-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK17-NEXT: store i32 4, ptr [[TMP99]], align 4 // CHECK17-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -9785,7 +9785,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD44:%.*]] = add nsw i32 [[TMP131]], 1 // CHECK17-NEXT: [[TMP132:%.*]] = zext i32 [[ADD44]] to i64 // CHECK17-NEXT: [[TMP133:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP133]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP133]], align 4 // CHECK17-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP134]], align 4 // CHECK17-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 2 @@ -9865,7 +9865,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD60:%.*]] = add nsw i32 [[TMP171]], 1 // CHECK17-NEXT: [[TMP172:%.*]] = zext i32 [[ADD60]] to i64 // CHECK17-NEXT: [[TMP173:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP173]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP173]], align 4 // CHECK17-NEXT: [[TMP174:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK17-NEXT: store i32 4, ptr [[TMP174]], align 4 // CHECK17-NEXT: [[TMP175:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 @@ -11057,7 +11057,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK17-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK17-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -11098,7 +11098,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK17-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK17-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK17-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK17-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -11148,7 +11148,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK17-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK17-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK17-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK17-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -11189,7 +11189,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP68:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK17-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK17-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP70]], align 4 // CHECK17-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP71]], align 4 // CHECK17-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -11239,7 +11239,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP93:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS23]], i32 0, i32 0 // CHECK17-NEXT: [[TMP94:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS24]], i32 0, i32 0 // CHECK17-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP95]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP95]], align 4 // CHECK17-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP96]], align 4 // CHECK17-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 2 @@ -12184,7 +12184,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK19-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK19-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK19-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -12256,7 +12256,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK19-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK19-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK19-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK19-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -12337,7 +12337,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP98]], 1 // CHECK19-NEXT: [[TMP99:%.*]] = zext i32 [[ADD29]] to i64 // CHECK19-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK19-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK19-NEXT: store i32 4, ptr [[TMP101]], align 4 // CHECK19-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -12409,7 +12409,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD44:%.*]] = add nsw i32 [[TMP134]], 1 // CHECK19-NEXT: [[TMP135:%.*]] = zext i32 [[ADD44]] to i64 // CHECK19-NEXT: [[TMP136:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP136]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP136]], align 4 // CHECK19-NEXT: [[TMP137:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP137]], align 4 // CHECK19-NEXT: [[TMP138:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 2 @@ -12490,7 +12490,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD60:%.*]] = add nsw i32 [[TMP175]], 1 // CHECK19-NEXT: [[TMP176:%.*]] = zext i32 [[ADD60]] to i64 // CHECK19-NEXT: [[TMP177:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP177]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP177]], align 4 // CHECK19-NEXT: [[TMP178:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK19-NEXT: store i32 4, ptr [[TMP178]], align 4 // CHECK19-NEXT: [[TMP179:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 @@ -13657,7 +13657,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK19-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK19-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -13698,7 +13698,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK19-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK19-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK19-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK19-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -13748,7 +13748,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK19-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK19-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK19-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK19-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -13789,7 +13789,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP68:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK19-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK19-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP70]], align 4 // CHECK19-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP71]], align 4 // CHECK19-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -13839,7 +13839,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP93:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS23]], i32 0, i32 0 // CHECK19-NEXT: [[TMP94:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS24]], i32 0, i32 0 // CHECK19-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP95]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP95]], align 4 // CHECK19-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP96]], align 4 // CHECK19-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp index 854afe3b9bbc..0a492152e9e0 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_codegen.cpp @@ -262,7 +262,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP27:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP21]], 0 // CHECK1-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP22]], 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -331,7 +331,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP61]], 1 // CHECK1-NEXT: [[TMP62:%.*]] = zext i32 [[ADD14]] to i64 // CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP63]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP63]], align 4 // CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 3, ptr [[TMP64]], align 4 // CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -933,7 +933,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP27:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP21]], 0 // CHECK3-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP22]], 0 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP30]], align 4 // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1002,7 +1002,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP61]], 1 // CHECK3-NEXT: [[TMP62:%.*]] = zext i32 [[ADD14]] to i64 // CHECK3-NEXT: [[TMP63:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP63]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP63]], align 4 // CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 3, ptr [[TMP64]], align 4 // CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1853,7 +1853,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP26]], 1 // CHECK9-NEXT: [[TMP27:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP29]], align 4 // CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2222,7 +2222,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP26]], 1 // CHECK11-NEXT: [[TMP27:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP29]], align 4 // CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2718,7 +2718,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP10]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP10]], align 4 // CHECK17-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP11]], align 4 // CHECK17-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2986,7 +2986,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP10]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP10]], align 4 // CHECK19-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP11]], align 4 // CHECK19-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3412,7 +3412,7 @@ int main (int argc, char **argv) { // CHECK25-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP26]], 1 // CHECK25-NEXT: [[TMP27:%.*]] = zext i32 [[ADD]] to i64 // CHECK25-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK25-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK25-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK25-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK25-NEXT: store i32 4, ptr [[TMP29]], align 4 // CHECK25-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3759,7 +3759,7 @@ int main (int argc, char **argv) { // CHECK25-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK25-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK25-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK25-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK25-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK25-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK25-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK25-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4044,7 +4044,7 @@ int main (int argc, char **argv) { // CHECK27-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP26]], 1 // CHECK27-NEXT: [[TMP27:%.*]] = zext i32 [[ADD]] to i64 // CHECK27-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK27-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK27-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK27-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK27-NEXT: store i32 4, ptr [[TMP29]], align 4 // CHECK27-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4386,7 +4386,7 @@ int main (int argc, char **argv) { // CHECK27-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK27-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK27-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK27-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK27-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK27-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK27-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK27-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp index e7b9978dd43c..910805c31074 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_collapse_codegen.cpp @@ -137,7 +137,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -389,7 +389,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -845,7 +845,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK9-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP35]], 1 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1231,7 +1231,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1547,7 +1547,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK11-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP34]], 1 // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP36]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1935,7 +1935,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp index d3777e81047c..aa6d6c67c20f 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_dist_schedule_codegen.cpp @@ -185,7 +185,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -227,7 +227,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -269,7 +269,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -861,7 +861,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -903,7 +903,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -945,7 +945,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1818,7 +1818,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1889,7 +1889,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK9-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1969,7 +1969,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP96]], 1 // CHECK9-NEXT: [[TMP97:%.*]] = zext i32 [[ADD29]] to i64 // CHECK9-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP98]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP98]], align 4 // CHECK9-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP99]], align 4 // CHECK9-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -2790,7 +2790,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2831,7 +2831,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -2881,7 +2881,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK9-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK9-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK9-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK9-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK9-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -3534,7 +3534,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3606,7 +3606,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK11-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -3687,7 +3687,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP98]], 1 // CHECK11-NEXT: [[TMP99:%.*]] = zext i32 [[ADD29]] to i64 // CHECK11-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK11-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP101]], align 4 // CHECK11-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -4493,7 +4493,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4534,7 +4534,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -4584,7 +4584,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK11-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK11-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK11-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK11-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK11-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp index 4f87d40e58f6..7d9e2ab89676 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_codegen.cpp @@ -343,7 +343,7 @@ int main() { // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -770,7 +770,7 @@ int main() { // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1435,7 +1435,7 @@ int main() { // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1856,7 +1856,7 @@ int main() { // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp index 7c86b180ec67..58c1f4155abf 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_codegen.cpp @@ -118,7 +118,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -151,7 +151,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -511,7 +511,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -544,7 +544,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -596,7 +596,7 @@ int main() { // CHECK1-NEXT: [[TMP39:%.*]] = select i1 [[TOBOOL5]], i32 0, i32 1 // CHECK1-NEXT: [[TMP40:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP39]], 0 // CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP41]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP41]], align 4 // CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP42]], align 4 // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -1140,7 +1140,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1173,7 +1173,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1225,7 +1225,7 @@ int main() { // CHECK1-NEXT: [[TMP39:%.*]] = select i1 [[TOBOOL5]], i32 0, i32 1 // CHECK1-NEXT: [[TMP40:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP39]], 0 // CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP41]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP41]], align 4 // CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP42]], align 4 // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -1758,7 +1758,7 @@ int main() { // CHECK3-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1791,7 +1791,7 @@ int main() { // CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK3: omp_offload.cont: // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -2151,7 +2151,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2184,7 +2184,7 @@ int main() { // CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK3: omp_offload.cont: // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -2236,7 +2236,7 @@ int main() { // CHECK3-NEXT: [[TMP39:%.*]] = select i1 [[TOBOOL5]], i32 0, i32 1 // CHECK3-NEXT: [[TMP40:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP39]], 0 // CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP41]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP41]], align 4 // CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP42]], align 4 // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -3010,7 +3010,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK3-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3043,7 +3043,7 @@ int main() { // CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK3: omp_offload.cont: // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -3095,7 +3095,7 @@ int main() { // CHECK3-NEXT: [[TMP39:%.*]] = select i1 [[TOBOOL5]], i32 0, i32 1 // CHECK3-NEXT: [[TMP40:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP39]], 0 // CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP41]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP41]], align 4 // CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP42]], align 4 // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -4219,7 +4219,7 @@ int main() { // CHECK9-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK9-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4252,7 +4252,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -4612,7 +4612,7 @@ int main() { // CHECK9-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4645,7 +4645,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -4697,7 +4697,7 @@ int main() { // CHECK9-NEXT: [[TMP39:%.*]] = select i1 [[TOBOOL5]], i32 0, i32 1 // CHECK9-NEXT: [[TMP40:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP39]], 0 // CHECK9-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP41]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP41]], align 4 // CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP42]], align 4 // CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -5241,7 +5241,7 @@ int main() { // CHECK9-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK9-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5274,7 +5274,7 @@ int main() { // CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK9: omp_offload.cont: // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -5326,7 +5326,7 @@ int main() { // CHECK9-NEXT: [[TMP39:%.*]] = select i1 [[TOBOOL5]], i32 0, i32 1 // CHECK9-NEXT: [[TMP40:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP39]], 0 // CHECK9-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP41]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP41]], align 4 // CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP42]], align 4 // CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -5859,7 +5859,7 @@ int main() { // CHECK11-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK11-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5892,7 +5892,7 @@ int main() { // CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK11: omp_offload.cont: // CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -6252,7 +6252,7 @@ int main() { // CHECK11-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK11-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6285,7 +6285,7 @@ int main() { // CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK11: omp_offload.cont: // CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -6337,7 +6337,7 @@ int main() { // CHECK11-NEXT: [[TMP39:%.*]] = select i1 [[TOBOOL5]], i32 0, i32 1 // CHECK11-NEXT: [[TMP40:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP39]], 0 // CHECK11-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP41]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP41]], align 4 // CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP42]], align 4 // CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -7111,7 +7111,7 @@ int main() { // CHECK11-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK11-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7144,7 +7144,7 @@ int main() { // CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK11: omp_offload.cont: // CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -7196,7 +7196,7 @@ int main() { // CHECK11-NEXT: [[TMP39:%.*]] = select i1 [[TOBOOL5]], i32 0, i32 1 // CHECK11-NEXT: [[TMP40:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP39]], 0 // CHECK11-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP41]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP41]], align 4 // CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP42]], align 4 // CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp index 268298c14801..8643cb9bb84a 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_codegen.cpp @@ -839,7 +839,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1312,7 +1312,7 @@ int main() { // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1853,7 +1853,7 @@ int main() { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2320,7 +2320,7 @@ int main() { // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp index fa8bcf65b8fb..47d067256fb3 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp @@ -99,7 +99,7 @@ int main() { // CHECK1: invoke.cont: // CHECK1-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -157,7 +157,7 @@ int main() { // CHECK1-NEXT: [[TMP27:%.*]] = zext i8 [[TMP26]] to i32 // CHECK1-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP27]], 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -586,7 +586,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -619,7 +619,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -664,7 +664,7 @@ int main() { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -706,7 +706,7 @@ int main() { // CHECK1-NEXT: [[TMP16:%.*]] = zext i8 [[TMP15]] to i32 // CHECK1-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP19]], align 4 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -1819,7 +1819,7 @@ int main() { // CHECK5: invoke.cont: // CHECK5-NEXT: store i8 [[CALL]], ptr [[A]], align 1 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1877,7 +1877,7 @@ int main() { // CHECK5-NEXT: [[TMP27:%.*]] = zext i8 [[TMP26]] to i32 // CHECK5-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP27]], 0 // CHECK5-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK5-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP30]], align 4 // CHECK5-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -2306,7 +2306,7 @@ int main() { // CHECK5-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2339,7 +2339,7 @@ int main() { // CHECK5-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK5: omp_offload.cont: // CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -2384,7 +2384,7 @@ int main() { // CHECK5-NEXT: [[_TMP1:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK5-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2426,7 +2426,7 @@ int main() { // CHECK5-NEXT: [[TMP16:%.*]] = zext i8 [[TMP15]] to i32 // CHECK5-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK5-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK5-NEXT: store i32 0, ptr [[TMP19]], align 4 // CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp index 03bee1dbb63c..f40acb42f9da 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_private_codegen.cpp @@ -265,7 +265,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -549,7 +549,7 @@ int main() { // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1026,7 +1026,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1304,7 +1304,7 @@ int main() { // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp index 7d35ea305f92..c473e8532189 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_proc_bind_codegen.cpp @@ -62,7 +62,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS2:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -95,7 +95,7 @@ int main() { // CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] // CHECK1: omp_offload.cont: // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP15]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP15]], align 4 // CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP16]], align 4 // CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS2]], i32 0, i32 2 @@ -441,7 +441,7 @@ int main() { // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp index 2dd1db48f030..669ca4a6b76e 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_reduction_codegen.cpp @@ -120,7 +120,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -428,7 +428,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -733,7 +733,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1037,7 +1037,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp index ff70e71e0126..3d40ac12e5ec 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp @@ -267,7 +267,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -309,7 +309,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -351,7 +351,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -393,7 +393,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK1-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -435,7 +435,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK1-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK1-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK1-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK1-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -1364,7 +1364,7 @@ int main (int argc, char **argv) { // CHECK2-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK2-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK2-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK2-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK2-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK2-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1406,7 +1406,7 @@ int main (int argc, char **argv) { // CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK2-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK2-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK2-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -1448,7 +1448,7 @@ int main (int argc, char **argv) { // CHECK2-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK2-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK2-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK2-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK2-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK2-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1490,7 +1490,7 @@ int main (int argc, char **argv) { // CHECK2-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK2-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK2-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK2-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK2-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK2-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -1532,7 +1532,7 @@ int main (int argc, char **argv) { // CHECK2-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK2-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK2-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK2-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK2-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK2-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK2-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK2-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -2461,7 +2461,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK5-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK5-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2503,7 +2503,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK5-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK5-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK5-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK5-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -2545,7 +2545,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK5-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK5-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK5-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK5-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -2587,7 +2587,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK5-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK5-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK5-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK5-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -2629,7 +2629,7 @@ int main (int argc, char **argv) { // CHECK5-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK5-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK5-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK5-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK5-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK5-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK5-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK5-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -3531,7 +3531,7 @@ int main (int argc, char **argv) { // CHECK6-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK6-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK6-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK6-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK6-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK6-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK6-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK6-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3573,7 +3573,7 @@ int main (int argc, char **argv) { // CHECK6-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK6-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK6-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK6-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK6-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK6-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK6-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK6-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -3615,7 +3615,7 @@ int main (int argc, char **argv) { // CHECK6-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK6-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK6-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK6-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK6-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK6-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK6-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK6-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -3657,7 +3657,7 @@ int main (int argc, char **argv) { // CHECK6-NEXT: [[TMP63:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS19]], i32 0, i32 0 // CHECK6-NEXT: [[TMP64:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS20]], i32 0, i32 0 // CHECK6-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 0 -// CHECK6-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK6-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK6-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 1 // CHECK6-NEXT: store i32 1, ptr [[TMP66]], align 4 // CHECK6-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS23]], i32 0, i32 2 @@ -3699,7 +3699,7 @@ int main (int argc, char **argv) { // CHECK6-NEXT: [[TMP83:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS27]], i32 0, i32 0 // CHECK6-NEXT: [[TMP84:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS28]], i32 0, i32 0 // CHECK6-NEXT: [[TMP85:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 0 -// CHECK6-NEXT: store i32 2, ptr [[TMP85]], align 4 +// CHECK6-NEXT: store i32 3, ptr [[TMP85]], align 4 // CHECK6-NEXT: [[TMP86:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 1 // CHECK6-NEXT: store i32 1, ptr [[TMP86]], align 4 // CHECK6-NEXT: [[TMP87:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS31]], i32 0, i32 2 @@ -5044,7 +5044,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK13-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK13-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK13-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK13-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -5115,7 +5115,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK13-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK13-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK13-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK13-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -5195,7 +5195,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP96]], 1 // CHECK13-NEXT: [[TMP97:%.*]] = zext i32 [[ADD29]] to i64 // CHECK13-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP98]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP98]], align 4 // CHECK13-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK13-NEXT: store i32 4, ptr [[TMP99]], align 4 // CHECK13-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -5266,7 +5266,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD44:%.*]] = add nsw i32 [[TMP131]], 1 // CHECK13-NEXT: [[TMP132:%.*]] = zext i32 [[ADD44]] to i64 // CHECK13-NEXT: [[TMP133:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP133]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP133]], align 4 // CHECK13-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 1 // CHECK13-NEXT: store i32 3, ptr [[TMP134]], align 4 // CHECK13-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 2 @@ -5346,7 +5346,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[ADD60:%.*]] = add nsw i32 [[TMP171]], 1 // CHECK13-NEXT: [[TMP172:%.*]] = zext i32 [[ADD60]] to i64 // CHECK13-NEXT: [[TMP173:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP173]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP173]], align 4 // CHECK13-NEXT: [[TMP174:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK13-NEXT: store i32 4, ptr [[TMP174]], align 4 // CHECK13-NEXT: [[TMP175:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 @@ -6658,7 +6658,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK13-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK13-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK13-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -6699,7 +6699,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK13-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK13-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK13-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK13-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -6749,7 +6749,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK13-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK13-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK13-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK13-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK13-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -6790,7 +6790,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP68:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK13-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK13-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP70]], align 4 // CHECK13-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK13-NEXT: store i32 1, ptr [[TMP71]], align 4 // CHECK13-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -6840,7 +6840,7 @@ int main (int argc, char **argv) { // CHECK13-NEXT: [[TMP93:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS23]], i32 0, i32 0 // CHECK13-NEXT: [[TMP94:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS24]], i32 0, i32 0 // CHECK13-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 0 -// CHECK13-NEXT: store i32 2, ptr [[TMP95]], align 4 +// CHECK13-NEXT: store i32 3, ptr [[TMP95]], align 4 // CHECK13-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 1 // CHECK13-NEXT: store i32 2, ptr [[TMP96]], align 4 // CHECK13-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 2 @@ -7855,7 +7855,7 @@ int main (int argc, char **argv) { // CHECK14-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK14-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK14-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK14-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK14-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK14-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK14-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK14-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -7926,7 +7926,7 @@ int main (int argc, char **argv) { // CHECK14-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK14-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK14-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK14-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK14-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK14-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK14-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK14-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -8006,7 +8006,7 @@ int main (int argc, char **argv) { // CHECK14-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP96]], 1 // CHECK14-NEXT: [[TMP97:%.*]] = zext i32 [[ADD29]] to i64 // CHECK14-NEXT: [[TMP98:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK14-NEXT: store i32 2, ptr [[TMP98]], align 4 +// CHECK14-NEXT: store i32 3, ptr [[TMP98]], align 4 // CHECK14-NEXT: [[TMP99:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK14-NEXT: store i32 4, ptr [[TMP99]], align 4 // CHECK14-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -8077,7 +8077,7 @@ int main (int argc, char **argv) { // CHECK14-NEXT: [[ADD44:%.*]] = add nsw i32 [[TMP131]], 1 // CHECK14-NEXT: [[TMP132:%.*]] = zext i32 [[ADD44]] to i64 // CHECK14-NEXT: [[TMP133:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 0 -// CHECK14-NEXT: store i32 2, ptr [[TMP133]], align 4 +// CHECK14-NEXT: store i32 3, ptr [[TMP133]], align 4 // CHECK14-NEXT: [[TMP134:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 1 // CHECK14-NEXT: store i32 3, ptr [[TMP134]], align 4 // CHECK14-NEXT: [[TMP135:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 2 @@ -8157,7 +8157,7 @@ int main (int argc, char **argv) { // CHECK14-NEXT: [[ADD60:%.*]] = add nsw i32 [[TMP171]], 1 // CHECK14-NEXT: [[TMP172:%.*]] = zext i32 [[ADD60]] to i64 // CHECK14-NEXT: [[TMP173:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK14-NEXT: store i32 2, ptr [[TMP173]], align 4 +// CHECK14-NEXT: store i32 3, ptr [[TMP173]], align 4 // CHECK14-NEXT: [[TMP174:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK14-NEXT: store i32 4, ptr [[TMP174]], align 4 // CHECK14-NEXT: [[TMP175:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 @@ -9469,7 +9469,7 @@ int main (int argc, char **argv) { // CHECK14-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK14-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK14-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK14-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK14-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK14-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK14-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK14-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -9510,7 +9510,7 @@ int main (int argc, char **argv) { // CHECK14-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK14-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK14-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK14-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK14-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK14-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK14-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK14-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -9560,7 +9560,7 @@ int main (int argc, char **argv) { // CHECK14-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK14-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK14-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK14-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK14-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK14-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK14-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK14-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -9601,7 +9601,7 @@ int main (int argc, char **argv) { // CHECK14-NEXT: [[TMP68:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK14-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK14-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK14-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CHECK14-NEXT: store i32 3, ptr [[TMP70]], align 4 // CHECK14-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK14-NEXT: store i32 1, ptr [[TMP71]], align 4 // CHECK14-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -9651,7 +9651,7 @@ int main (int argc, char **argv) { // CHECK14-NEXT: [[TMP93:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS23]], i32 0, i32 0 // CHECK14-NEXT: [[TMP94:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS24]], i32 0, i32 0 // CHECK14-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 0 -// CHECK14-NEXT: store i32 2, ptr [[TMP95]], align 4 +// CHECK14-NEXT: store i32 3, ptr [[TMP95]], align 4 // CHECK14-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 1 // CHECK14-NEXT: store i32 2, ptr [[TMP96]], align 4 // CHECK14-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 2 @@ -10666,7 +10666,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK17-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK17-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK17-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -10738,7 +10738,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK17-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK17-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK17-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK17-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -10819,7 +10819,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP98]], 1 // CHECK17-NEXT: [[TMP99:%.*]] = zext i32 [[ADD29]] to i64 // CHECK17-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK17-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK17-NEXT: store i32 4, ptr [[TMP101]], align 4 // CHECK17-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -10891,7 +10891,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD44:%.*]] = add nsw i32 [[TMP134]], 1 // CHECK17-NEXT: [[TMP135:%.*]] = zext i32 [[ADD44]] to i64 // CHECK17-NEXT: [[TMP136:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP136]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP136]], align 4 // CHECK17-NEXT: [[TMP137:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP137]], align 4 // CHECK17-NEXT: [[TMP138:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 2 @@ -10972,7 +10972,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[ADD60:%.*]] = add nsw i32 [[TMP175]], 1 // CHECK17-NEXT: [[TMP176:%.*]] = zext i32 [[ADD60]] to i64 // CHECK17-NEXT: [[TMP177:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP177]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP177]], align 4 // CHECK17-NEXT: [[TMP178:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK17-NEXT: store i32 4, ptr [[TMP178]], align 4 // CHECK17-NEXT: [[TMP179:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 @@ -12259,7 +12259,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK17-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK17-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -12300,7 +12300,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK17-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK17-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK17-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK17-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -12350,7 +12350,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK17-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK17-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK17-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK17-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -12391,7 +12391,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP68:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK17-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK17-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP70]], align 4 // CHECK17-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP71]], align 4 // CHECK17-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -12441,7 +12441,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP93:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS23]], i32 0, i32 0 // CHECK17-NEXT: [[TMP94:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS24]], i32 0, i32 0 // CHECK17-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP95]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP95]], align 4 // CHECK17-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 1 // CHECK17-NEXT: store i32 2, ptr [[TMP96]], align 4 // CHECK17-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 2 @@ -13429,7 +13429,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK19-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK19-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK19-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -13501,7 +13501,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK19-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK19-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK19-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK19-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -13582,7 +13582,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP98]], 1 // CHECK19-NEXT: [[TMP99:%.*]] = zext i32 [[ADD29]] to i64 // CHECK19-NEXT: [[TMP100:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP100]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP100]], align 4 // CHECK19-NEXT: [[TMP101:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK19-NEXT: store i32 4, ptr [[TMP101]], align 4 // CHECK19-NEXT: [[TMP102:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -13654,7 +13654,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD44:%.*]] = add nsw i32 [[TMP134]], 1 // CHECK19-NEXT: [[TMP135:%.*]] = zext i32 [[ADD44]] to i64 // CHECK19-NEXT: [[TMP136:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP136]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP136]], align 4 // CHECK19-NEXT: [[TMP137:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP137]], align 4 // CHECK19-NEXT: [[TMP138:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS45]], i32 0, i32 2 @@ -13735,7 +13735,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[ADD60:%.*]] = add nsw i32 [[TMP175]], 1 // CHECK19-NEXT: [[TMP176:%.*]] = zext i32 [[ADD60]] to i64 // CHECK19-NEXT: [[TMP177:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP177]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP177]], align 4 // CHECK19-NEXT: [[TMP178:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 1 // CHECK19-NEXT: store i32 4, ptr [[TMP178]], align 4 // CHECK19-NEXT: [[TMP179:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS61]], i32 0, i32 2 @@ -15022,7 +15022,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK19-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK19-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -15063,7 +15063,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK19-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK19-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK19-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK19-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -15113,7 +15113,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK19-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK19-NEXT: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP50]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP50]], align 4 // CHECK19-NEXT: [[TMP51:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP51]], align 4 // CHECK19-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -15154,7 +15154,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP68:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS15]], i32 0, i32 0 // CHECK19-NEXT: [[TMP69:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS16]], i32 0, i32 0 // CHECK19-NEXT: [[TMP70:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP70]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP70]], align 4 // CHECK19-NEXT: [[TMP71:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP71]], align 4 // CHECK19-NEXT: [[TMP72:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS19]], i32 0, i32 2 @@ -15204,7 +15204,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP93:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS23]], i32 0, i32 0 // CHECK19-NEXT: [[TMP94:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS24]], i32 0, i32 0 // CHECK19-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP95]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP95]], align 4 // CHECK19-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 1 // CHECK19-NEXT: store i32 2, ptr [[TMP96]], align 4 // CHECK19-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS27]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_private_codegen.cpp b/clang/test/OpenMP/teams_distribute_private_codegen.cpp index bdc001fe5d5d..78b42e3194c7 100644 --- a/clang/test/OpenMP/teams_distribute_private_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_private_codegen.cpp @@ -243,7 +243,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -412,7 +412,7 @@ int main() { // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -771,7 +771,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -938,7 +938,7 @@ int main() { // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_reduction_codegen.cpp b/clang/test/OpenMP/teams_distribute_reduction_codegen.cpp index 309cbffcf616..ff2defa849ef 100644 --- a/clang/test/OpenMP/teams_distribute_reduction_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_reduction_codegen.cpp @@ -105,7 +105,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -285,7 +285,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -462,7 +462,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -642,7 +642,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_simd_codegen.cpp b/clang/test/OpenMP/teams_distribute_simd_codegen.cpp index ee5d5cad72fe..2fab0cff5537 100644 --- a/clang/test/OpenMP/teams_distribute_simd_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_codegen.cpp @@ -302,7 +302,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP26]], 0 // CHECK1-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP29]], 0 // CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -362,7 +362,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP63]], 1 // CHECK1-NEXT: [[TMP64:%.*]] = zext i32 [[ADD14]] to i64 // CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP66]], align 4 // CHECK1-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -737,7 +737,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP26]], 0 // CHECK3-NEXT: [[TMP35:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP29]], 0 // CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -797,7 +797,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP63]], 1 // CHECK3-NEXT: [[TMP64:%.*]] = zext i32 [[ADD14]] to i64 // CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP65]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP65]], align 4 // CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP66]], align 4 // CHECK3-NEXT: [[TMP67:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1407,7 +1407,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1629,7 +1629,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1993,7 +1993,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP17:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK17-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK17-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK17-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2171,7 +2171,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP17:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK19-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK19-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK19-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2348,7 +2348,7 @@ int main (int argc, char **argv) { // CHECK21-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK21-NEXT: [[TMP17:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK21-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK21-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK21-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK21-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK21-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK21-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2576,7 +2576,7 @@ int main (int argc, char **argv) { // CHECK23-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK23-NEXT: [[TMP17:%.*]] = getelementptr inbounds [3 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK23-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK23-NEXT: store i32 2, ptr [[TMP18]], align 4 +// CHECK23-NEXT: store i32 3, ptr [[TMP18]], align 4 // CHECK23-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK23-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK23-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3130,7 +3130,7 @@ int main (int argc, char **argv) { // CHECK33-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK33-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK33-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK33-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK33-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK33-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK33-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK33-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3343,7 +3343,7 @@ int main (int argc, char **argv) { // CHECK33-NEXT: [[TMP19:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK33-NEXT: [[TMP20:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 // CHECK33-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK33-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK33-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK33-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK33-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK33-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3537,7 +3537,7 @@ int main (int argc, char **argv) { // CHECK35-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK35-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK35-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK35-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK35-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK35-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK35-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK35-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3749,7 +3749,7 @@ int main (int argc, char **argv) { // CHECK35-NEXT: [[TMP19:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK35-NEXT: [[TMP20:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 // CHECK35-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK35-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK35-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK35-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK35-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK35-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3952,7 +3952,7 @@ int main (int argc, char **argv) { // CHECK37-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP26]], 1 // CHECK37-NEXT: [[TMP27:%.*]] = zext i32 [[ADD]] to i64 // CHECK37-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK37-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK37-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK37-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK37-NEXT: store i32 4, ptr [[TMP29]], align 4 // CHECK37-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4212,7 +4212,7 @@ int main (int argc, char **argv) { // CHECK37-NEXT: [[TMP19:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK37-NEXT: [[TMP20:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 // CHECK37-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK37-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK37-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK37-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK37-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK37-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4416,7 +4416,7 @@ int main (int argc, char **argv) { // CHECK39-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP26]], 1 // CHECK39-NEXT: [[TMP27:%.*]] = zext i32 [[ADD]] to i64 // CHECK39-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK39-NEXT: store i32 2, ptr [[TMP28]], align 4 +// CHECK39-NEXT: store i32 3, ptr [[TMP28]], align 4 // CHECK39-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK39-NEXT: store i32 4, ptr [[TMP29]], align 4 // CHECK39-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -4674,7 +4674,7 @@ int main (int argc, char **argv) { // CHECK39-NEXT: [[TMP19:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK39-NEXT: [[TMP20:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP18]], 0 // CHECK39-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK39-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK39-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK39-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK39-NEXT: store i32 3, ptr [[TMP22]], align 4 // CHECK39-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_simd_collapse_codegen.cpp b/clang/test/OpenMP/teams_distribute_simd_collapse_codegen.cpp index 292bfb2a296c..da0e7703e30c 100644 --- a/clang/test/OpenMP/teams_distribute_simd_collapse_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_collapse_codegen.cpp @@ -128,7 +128,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -297,7 +297,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -674,7 +674,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK9-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP35]], 1 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -922,7 +922,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1155,7 +1155,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK11-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP34]], 1 // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP36]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1401,7 +1401,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_simd_dist_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_simd_dist_schedule_codegen.cpp index a18b4d2feeec..1266534b890f 100644 --- a/clang/test/OpenMP/teams_distribute_simd_dist_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_dist_schedule_codegen.cpp @@ -170,7 +170,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -212,7 +212,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -254,7 +254,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -603,7 +603,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -645,7 +645,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 // CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 // CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 @@ -687,7 +687,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS11]], i32 0, i32 0 // CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS12]], i32 0, i32 0 // CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1326,7 +1326,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1397,7 +1397,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK9-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1468,7 +1468,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP91]], 1 // CHECK9-NEXT: [[TMP92:%.*]] = zext i32 [[ADD29]] to i64 // CHECK9-NEXT: [[TMP93:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP93]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP93]], align 4 // CHECK9-NEXT: [[TMP94:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP94]], align 4 // CHECK9-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -1932,7 +1932,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1973,7 +1973,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -2014,7 +2014,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK9-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 @@ -2403,7 +2403,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2475,7 +2475,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP57]], 1 // CHECK11-NEXT: [[TMP58:%.*]] = zext i32 [[ADD14]] to i64 // CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP59]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP59]], align 4 // CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP60]], align 4 // CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -2547,7 +2547,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP93]], 1 // CHECK11-NEXT: [[TMP94:%.*]] = zext i32 [[ADD29]] to i64 // CHECK11-NEXT: [[TMP95:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP95]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP95]], align 4 // CHECK11-NEXT: [[TMP96:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP96]], align 4 // CHECK11-NEXT: [[TMP97:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS30]], i32 0, i32 2 @@ -3008,7 +3008,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3049,7 +3049,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -3090,7 +3090,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 // CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 // CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP45]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP45]], align 4 // CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP46]], align 4 // CHECK11-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp index dd3daf865512..2d3fccd90c0a 100644 --- a/clang/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp @@ -306,7 +306,7 @@ int main() { // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -596,7 +596,7 @@ int main() { // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1124,7 +1124,7 @@ int main() { // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1412,7 +1412,7 @@ int main() { // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp b/clang/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp index 073960cc5a46..ec95ab55b155 100644 --- a/clang/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_lastprivate_codegen.cpp @@ -568,7 +568,7 @@ int main() { // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -886,7 +886,7 @@ int main() { // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1278,7 +1278,7 @@ int main() { // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP25]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP25]], align 4 // CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP26]], align 4 // CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1594,7 +1594,7 @@ int main() { // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP20]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP21]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_simd_private_codegen.cpp b/clang/test/OpenMP/teams_distribute_simd_private_codegen.cpp index 52b213c34591..c839268ada75 100644 --- a/clang/test/OpenMP/teams_distribute_simd_private_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_private_codegen.cpp @@ -244,7 +244,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -420,7 +420,7 @@ int main() { // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -786,7 +786,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -960,7 +960,7 @@ int main() { // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_distribute_simd_reduction_codegen.cpp b/clang/test/OpenMP/teams_distribute_simd_reduction_codegen.cpp index e660009f1cd7..27c47f50547e 100644 --- a/clang/test/OpenMP/teams_distribute_simd_reduction_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_reduction_codegen.cpp @@ -105,7 +105,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -292,7 +292,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -476,7 +476,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -663,7 +663,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_firstprivate_codegen.cpp b/clang/test/OpenMP/teams_firstprivate_codegen.cpp index c023de8cf010..649fae99b21a 100644 --- a/clang/test/OpenMP/teams_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/teams_firstprivate_codegen.cpp @@ -327,7 +327,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -371,7 +371,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK9-NEXT: [[TMP41:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 // CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP43]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP43]], align 4 // CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP44]], align 4 // CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -663,7 +663,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 4, ptr [[TMP17]], align 4 // CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -707,7 +707,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP38]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP38]], align 4 // CHECK9-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP39]], align 4 // CHECK9-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -1121,7 +1121,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP21]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP21]], align 4 // CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP22]], align 4 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1165,7 +1165,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK11-NEXT: [[TMP41:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 // CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP43]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP43]], align 4 // CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP44]], align 4 // CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -1457,7 +1457,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds [4 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP16]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP16]], align 4 // CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 4, ptr [[TMP17]], align 4 // CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1501,7 +1501,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 // CHECK11-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP38]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP38]], align 4 // CHECK11-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP39]], align 4 // CHECK11-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 @@ -1942,7 +1942,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK17-NEXT: [[TMP41:%.*]] = getelementptr inbounds [8 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP42:%.*]] = getelementptr inbounds [8 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK17-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP43]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP43]], align 4 // CHECK17-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 8, ptr [[TMP44]], align 4 // CHECK17-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2180,7 +2180,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK17-NEXT: [[TMP53:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP54:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK17-NEXT: [[TMP55:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP55]], align 4 // CHECK17-NEXT: [[TMP56:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 10, ptr [[TMP56]], align 4 // CHECK17-NEXT: [[TMP57:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2405,7 +2405,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK19-NEXT: [[TMP39:%.*]] = getelementptr inbounds [8 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP40:%.*]] = getelementptr inbounds [8 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK19-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP41]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP41]], align 4 // CHECK19-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 8, ptr [[TMP42]], align 4 // CHECK19-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2641,7 +2641,7 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) { // CHECK19-NEXT: [[TMP51:%.*]] = getelementptr inbounds [10 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP52:%.*]] = getelementptr inbounds [10 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 // CHECK19-NEXT: [[TMP53:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP53]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP53]], align 4 // CHECK19-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 10, ptr [[TMP54]], align 4 // CHECK19-NEXT: [[TMP55:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_generic_loop_codegen-1.cpp b/clang/test/OpenMP/teams_generic_loop_codegen-1.cpp index 85a4dfea91a2..d4a98f07fe24 100644 --- a/clang/test/OpenMP/teams_generic_loop_codegen-1.cpp +++ b/clang/test/OpenMP/teams_generic_loop_codegen-1.cpp @@ -253,7 +253,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP27:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP21]], 0 // CHECK1-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP22]], 0 // CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 4, ptr [[TMP30]], align 4 // CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -313,7 +313,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK1-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK1-NEXT: store i32 2, ptr [[TMP59]], align 4 // CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -840,7 +840,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP27:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP21]], 0 // CHECK3-NEXT: [[TMP28:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP22]], 0 // CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP29]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP29]], align 4 // CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 4, ptr [[TMP30]], align 4 // CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -900,7 +900,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP56]], 1 // CHECK3-NEXT: [[TMP57:%.*]] = zext i32 [[ADD14]] to i64 // CHECK3-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP58]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP58]], align 4 // CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 1 // CHECK3-NEXT: store i32 2, ptr [[TMP59]], align 4 // CHECK3-NEXT: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS15]], i32 0, i32 2 @@ -1399,7 +1399,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK9-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1710,7 +1710,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK11-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1984,7 +1984,7 @@ int main (int argc, char **argv) { // CHECK17-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK17-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK17-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK17-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK17-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK17-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK17-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2202,7 +2202,7 @@ int main (int argc, char **argv) { // CHECK19-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK19-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK19-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK19-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK19-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK19-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK19-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2453,7 +2453,7 @@ int main (int argc, char **argv) { // CHECK25-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK25-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK25-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK25-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK25-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK25-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK25-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK25-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -2753,7 +2753,7 @@ int main (int argc, char **argv) { // CHECK25-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK25-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK25-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK25-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK25-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK25-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK25-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK25-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3013,7 +3013,7 @@ int main (int argc, char **argv) { // CHECK27-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK27-NEXT: [[TMP22:%.*]] = zext i32 [[ADD]] to i64 // CHECK27-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK27-NEXT: store i32 2, ptr [[TMP23]], align 4 +// CHECK27-NEXT: store i32 3, ptr [[TMP23]], align 4 // CHECK27-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK27-NEXT: store i32 3, ptr [[TMP24]], align 4 // CHECK27-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -3308,7 +3308,7 @@ int main (int argc, char **argv) { // CHECK27-NEXT: [[TMP17:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP15]], 0 // CHECK27-NEXT: [[TMP18:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP16]], 0 // CHECK27-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK27-NEXT: store i32 2, ptr [[TMP19]], align 4 +// CHECK27-NEXT: store i32 3, ptr [[TMP19]], align 4 // CHECK27-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK27-NEXT: store i32 3, ptr [[TMP20]], align 4 // CHECK27-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_generic_loop_collapse_codegen.cpp b/clang/test/OpenMP/teams_generic_loop_collapse_codegen.cpp index 49df83c9c765..c0c04986f147 100644 --- a/clang/test/OpenMP/teams_generic_loop_collapse_codegen.cpp +++ b/clang/test/OpenMP/teams_generic_loop_collapse_codegen.cpp @@ -132,7 +132,7 @@ int main (int argc, char **argv) { // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -368,7 +368,7 @@ int main (int argc, char **argv) { // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -668,7 +668,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP35:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK9-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP35]], 1 // CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP36]], align 4 // CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 5, ptr [[TMP37]], align 4 // CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1018,7 +1018,7 @@ int main (int argc, char **argv) { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1318,7 +1318,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP34:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_3]], align 8 // CHECK11-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP34]], 1 // CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP35]], align 4 // CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 5, ptr [[TMP36]], align 4 // CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1670,7 +1670,7 @@ int main (int argc, char **argv) { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp b/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp index 5ef729f044e0..303bce8c648c 100644 --- a/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp +++ b/clang/test/OpenMP/teams_generic_loop_private_codegen.cpp @@ -263,7 +263,7 @@ int main() { // CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -533,7 +533,7 @@ int main() { // CHECK1-NEXT: store ptr [[TEST]], ptr [[VAR]], align 8 // CHECK1-NEXT: store ptr undef, ptr [[_TMP1]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -996,7 +996,7 @@ int main() { // CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 // CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1260,7 +1260,7 @@ int main() { // CHECK3-NEXT: store ptr [[TEST]], ptr [[VAR]], align 4 // CHECK3-NEXT: store ptr undef, ptr [[_TMP1]], align 4 // CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_generic_loop_reduction_codegen.cpp b/clang/test/OpenMP/teams_generic_loop_reduction_codegen.cpp index 4da49eed32ef..d80c003c0109 100644 --- a/clang/test/OpenMP/teams_generic_loop_reduction_codegen.cpp +++ b/clang/test/OpenMP/teams_generic_loop_reduction_codegen.cpp @@ -116,7 +116,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -410,7 +410,7 @@ int main() { // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -701,7 +701,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -991,7 +991,7 @@ int main() { // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP7]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP8]], align 4 // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/clang/test/OpenMP/teams_private_codegen.cpp b/clang/test/OpenMP/teams_private_codegen.cpp index 0126545c5915..1d0b2435ff00 100644 --- a/clang/test/OpenMP/teams_private_codegen.cpp +++ b/clang/test/OpenMP/teams_private_codegen.cpp @@ -219,7 +219,7 @@ int main() { // CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK1-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CHECK1-NEXT: store i32 3, ptr [[TMP6]], align 4 // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK1-NEXT: store i32 1, ptr [[TMP7]], align 4 // CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -405,7 +405,7 @@ int main() { // CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK3-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CHECK3-NEXT: store i32 3, ptr [[TMP6]], align 4 // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK3-NEXT: store i32 1, ptr [[TMP7]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -557,7 +557,7 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK9-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -724,7 +724,7 @@ int main() { // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef signext 2) // CHECK9-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef signext 3) // CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -804,7 +804,7 @@ int main() { // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP7]], align 4 // CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1037,7 +1037,7 @@ int main() { // CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK9-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK9-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1147,7 +1147,7 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00) // CHECK11-NEXT: call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00) // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1314,7 +1314,7 @@ int main() { // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) // CHECK11-NEXT: call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3) // CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP0]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP0]], align 4 // CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 0, ptr [[TMP1]], align 4 // CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1394,7 +1394,7 @@ int main() { // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP6]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP7]], align 4 // CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 @@ -1627,7 +1627,7 @@ int main() { // CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 // CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 -// CHECK11-NEXT: store i32 2, ptr [[TMP5]], align 4 +// CHECK11-NEXT: store i32 3, ptr [[TMP5]], align 4 // CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 // CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 // CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h index 1bfaf3718552..338b56226f20 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -72,7 +72,10 @@ enum class IdentFlag { #include "llvm/Frontend/OpenMP/OMPKinds.def" // Version of the kernel argument format used by the omp runtime. -#define OMP_KERNEL_ARG_VERSION 2 +#define OMP_KERNEL_ARG_VERSION 3 + +// Minimum version of the compiler that generates a kernel dynamic pointer. +#define OMP_KERNEL_ARG_MIN_VERSION_WITH_DYN_PTR 3 /// \note This needs to be kept in sync with kmp.h enum sched_type. /// Todo: Update kmp.h to include this file, and remove the enums in kmp.h diff --git a/openmp/libomptarget/plugins-nextgen/common/include/PluginInterface.h b/openmp/libomptarget/plugins-nextgen/common/include/PluginInterface.h index 118bb7d3051b..b7be7b645ba3 100644 --- a/openmp/libomptarget/plugins-nextgen/common/include/PluginInterface.h +++ b/openmp/libomptarget/plugins-nextgen/common/include/PluginInterface.h @@ -289,7 +289,7 @@ struct GenericKernelTy { /// Return a device pointer to a new kernel launch environment. Expected<KernelLaunchEnvironmentTy *> - getKernelLaunchEnvironment(GenericDeviceTy &GenericDevice, + getKernelLaunchEnvironment(GenericDeviceTy &GenericDevice, uint32_t Version, AsyncInfoWrapperTy &AsyncInfo) const; /// Indicate whether an execution mode is valid. diff --git a/openmp/libomptarget/plugins-nextgen/common/src/PluginInterface.cpp b/openmp/libomptarget/plugins-nextgen/common/src/PluginInterface.cpp index 414506f30b8f..f39f913d85ee 100644 --- a/openmp/libomptarget/plugins-nextgen/common/src/PluginInterface.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/src/PluginInterface.cpp @@ -468,11 +468,13 @@ Error GenericKernelTy::init(GenericDeviceTy &GenericDevice, Expected<KernelLaunchEnvironmentTy *> GenericKernelTy::getKernelLaunchEnvironment( - GenericDeviceTy &GenericDevice, + GenericDeviceTy &GenericDevice, uint32_t Version, AsyncInfoWrapperTy &AsyncInfoWrapper) const { // Ctor/Dtor have no arguments, replaying uses the original kernel launch - // environment. - if (isCtorOrDtor() || RecordReplay.isReplaying()) + // environment. Older versions of the compiler do not generate a kernel + // launch environment. + if (isCtorOrDtor() || RecordReplay.isReplaying() || + Version < OMP_KERNEL_ARG_MIN_VERSION_WITH_DYN_PTR) return nullptr; if (!KernelEnvironment.Configuration.ReductionDataSize || @@ -544,8 +546,8 @@ Error GenericKernelTy::launch(GenericDeviceTy &GenericDevice, void **ArgPtrs, llvm::SmallVector<void *, 16> Args; llvm::SmallVector<void *, 16> Ptrs; - auto KernelLaunchEnvOrErr = - getKernelLaunchEnvironment(GenericDevice, AsyncInfoWrapper); + auto KernelLaunchEnvOrErr = getKernelLaunchEnvironment( + GenericDevice, KernelArgs.Version, AsyncInfoWrapper); if (!KernelLaunchEnvOrErr) return KernelLaunchEnvOrErr.takeError(); @@ -586,6 +588,9 @@ void *GenericKernelTy::prepareArgs( uint32_t KLEOffset = !!KernelLaunchEnvironment; NumArgs += KLEOffset; + if (NumArgs == 0) + return nullptr; + Args.resize(NumArgs); Ptrs.resize(NumArgs); diff --git a/openmp/libomptarget/src/interface.cpp b/openmp/libomptarget/src/interface.cpp index 8b89bc3ff712..b7f547f1ec3d 100644 --- a/openmp/libomptarget/src/interface.cpp +++ b/openmp/libomptarget/src/interface.cpp @@ -21,6 +21,8 @@ #include "Utils/ExponentialBackoff.h" +#include "llvm/Frontend/OpenMP/OMPConstants.h" + #include <cassert> #include <cstdint> #include <cstdio> @@ -218,11 +220,19 @@ EXTERN void __tgt_target_data_update_nowait_mapper( static KernelArgsTy *upgradeKernelArgs(KernelArgsTy *KernelArgs, KernelArgsTy &LocalKernelArgs, int32_t NumTeams, int32_t ThreadLimit) { - if (KernelArgs->Version > 2) + if (KernelArgs->Version > OMP_KERNEL_ARG_VERSION) DP("Unexpected ABI version: %u\n", KernelArgs->Version); - if (KernelArgs->Version == 1) { - LocalKernelArgs.Version = 2; + uint32_t UpgradedVersion = KernelArgs->Version; + if (KernelArgs->Version < OMP_KERNEL_ARG_VERSION) { + // The upgraded version will be based on the kernel launch environment. + if (KernelArgs->Version < OMP_KERNEL_ARG_MIN_VERSION_WITH_DYN_PTR) + UpgradedVersion = OMP_KERNEL_ARG_MIN_VERSION_WITH_DYN_PTR - 1; + else + UpgradedVersion = OMP_KERNEL_ARG_VERSION; + } + if (UpgradedVersion != KernelArgs->Version) { + LocalKernelArgs.Version = UpgradedVersion; LocalKernelArgs.NumArgs = KernelArgs->NumArgs; LocalKernelArgs.ArgBasePtrs = KernelArgs->ArgBasePtrs; LocalKernelArgs.ArgPtrs = KernelArgs->ArgPtrs; diff --git a/openmp/libomptarget/src/omptarget.cpp b/openmp/libomptarget/src/omptarget.cpp index 3b3e17f0f311..5bbf3a455c72 100644 --- a/openmp/libomptarget/src/omptarget.cpp +++ b/openmp/libomptarget/src/omptarget.cpp @@ -30,6 +30,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/bit.h" +#include "llvm/Frontend/OpenMP/OMPConstants.h" #include "llvm/Object/ObjectFile.h" #include <cassert> @@ -1752,7 +1753,7 @@ int target_replay(ident_t *Loc, DeviceTy &Device, void *HostPtr, Device.submitData(TgtPtr, DeviceMemory, DeviceMemorySize, AsyncInfo); KernelArgsTy KernelArgs = {0}; - KernelArgs.Version = 2; + KernelArgs.Version = OMP_KERNEL_ARG_VERSION; KernelArgs.NumArgs = NumArgs; KernelArgs.Tripcount = LoopTripCount; KernelArgs.NumTeams[0] = NumTeams; -- GitLab From 1bab88df075d87dd66e8a54d88d16f8540452b8f Mon Sep 17 00:00:00 2001 From: Fangrui Song <i@maskray.me> Date: Tue, 19 Mar 2024 16:44:25 -0700 Subject: [PATCH 160/307] [ELF] Move some operations from link to setConfigs. NFC --- lld/ELF/Driver.cpp | 68 +++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index e7160a47bd21..40d3f2caa133 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1800,6 +1800,37 @@ static void setConfigs(opt::InputArgList &args) { args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, m == EM_PPC64); config->pcRelOptimize = args.hasFlag(OPT_pcrel_optimize, OPT_no_pcrel_optimize, m == EM_PPC64); + + if (!args.hasArg(OPT_hash_style)) { + if (config->emachine == EM_MIPS) + config->sysvHash = true; + else + config->sysvHash = config->gnuHash = true; + } + + // Set default entry point and output file if not specified by command line or + // linker scripts. + config->warnMissingEntry = + (!config->entry.empty() || (!config->shared && !config->relocatable)); + if (config->entry.empty() && !config->relocatable) + config->entry = config->emachine == EM_MIPS ? "__start" : "_start"; + if (config->outputFile.empty()) + config->outputFile = "a.out"; + + // Fail early if the output file or map file is not writable. If a user has a + // long link, e.g. due to a large LTO link, they do not wish to run it and + // find that it failed because there was a mistake in their command-line. + { + llvm::TimeTraceScope timeScope("Create output files"); + if (auto e = tryCreateFile(config->outputFile)) + error("cannot open output file " + config->outputFile + ": " + + e.message()); + if (auto e = tryCreateFile(config->mapFile)) + error("cannot open map file " + config->mapFile + ": " + e.message()); + if (auto e = tryCreateFile(config->whyExtract)) + error("cannot open --why-extract= file " + config->whyExtract + ": " + + e.message()); + } } static bool isFormatBinary(StringRef s) { @@ -2682,43 +2713,6 @@ static void postParseObjectFile(ELFFileBase *file) { // all linker scripts have already been parsed. void LinkerDriver::link(opt::InputArgList &args) { llvm::TimeTraceScope timeScope("Link", StringRef("LinkerDriver::Link")); - // If a --hash-style option was not given, set to a default value, - // which varies depending on the target. - if (!args.hasArg(OPT_hash_style)) { - if (config->emachine == EM_MIPS) - config->sysvHash = true; - else - config->sysvHash = config->gnuHash = true; - } - - // Default output filename is "a.out" by the Unix tradition. - if (config->outputFile.empty()) - config->outputFile = "a.out"; - - // Fail early if the output file or map file is not writable. If a user has a - // long link, e.g. due to a large LTO link, they do not wish to run it and - // find that it failed because there was a mistake in their command-line. - { - llvm::TimeTraceScope timeScope("Create output files"); - if (auto e = tryCreateFile(config->outputFile)) - error("cannot open output file " + config->outputFile + ": " + - e.message()); - if (auto e = tryCreateFile(config->mapFile)) - error("cannot open map file " + config->mapFile + ": " + e.message()); - if (auto e = tryCreateFile(config->whyExtract)) - error("cannot open --why-extract= file " + config->whyExtract + ": " + - e.message()); - } - if (errorCount()) - return; - - // Use default entry point name if no name was given via the command - // line nor linker scripts. For some reason, MIPS entry point name is - // different from others. - config->warnMissingEntry = - (!config->entry.empty() || (!config->shared && !config->relocatable)); - if (config->entry.empty() && !config->relocatable) - config->entry = (config->emachine == EM_MIPS) ? "__start" : "_start"; // Handle --trace-symbol. for (auto *arg : args.filtered(OPT_trace_symbol)) -- GitLab From 12a2bc301fe83eea3b214428827d712c8cfb28a9 Mon Sep 17 00:00:00 2001 From: Lei Wang <wlei@fb.com> Date: Tue, 19 Mar 2024 16:50:48 -0700 Subject: [PATCH 161/307] [CSSPGO] Fix the issue of preinliner import function list (#85719) By design, when the nested profile is pre-inliner based, we should fully honor pre-inliner decision, fix it by setting threshold to zero. We observed a perf win on one internal service, no negative impact for other big services. --- llvm/lib/Transforms/IPO/SampleProfile.cpp | 3 ++ .../Inputs/csspgo-import-list-preinliner.prof | 14 ++++++ .../csspgo-import-list-preinliner.ll | 50 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 llvm/test/Transforms/SampleProfile/Inputs/csspgo-import-list-preinliner.prof create mode 100644 llvm/test/Transforms/SampleProfile/csspgo-import-list-preinliner.ll diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp index ffc26f1a0a97..9a8040bc4b06 100644 --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -1167,6 +1167,9 @@ void SampleProfileLoader::findExternalInlineCandidate( // For AutoFDO profile, retrieve candidate profiles by walking over // the nested inlinee profiles. if (!FunctionSamples::ProfileIsCS) { + // Set threshold to zero to honor pre-inliner decision. + if (UsePreInlinerDecision) + Threshold = 0; Samples->findInlinedFunctions(InlinedGUIDs, SymbolMap, Threshold); return; } diff --git a/llvm/test/Transforms/SampleProfile/Inputs/csspgo-import-list-preinliner.prof b/llvm/test/Transforms/SampleProfile/Inputs/csspgo-import-list-preinliner.prof new file mode 100644 index 000000000000..7388d574be5e --- /dev/null +++ b/llvm/test/Transforms/SampleProfile/Inputs/csspgo-import-list-preinliner.prof @@ -0,0 +1,14 @@ +main:8001:0 + 1: 0 + 2: 2000 + 3: 2000 + 4: 0 + 5: 2000 + 6: 2000 + 7: 0 + 8: 0 + 9: bar:1 + 1: 1 + !CFGChecksum: 4294967295 + !Attributes: 2 + !CFGChecksum: 563088156202820 diff --git a/llvm/test/Transforms/SampleProfile/csspgo-import-list-preinliner.ll b/llvm/test/Transforms/SampleProfile/csspgo-import-list-preinliner.ll new file mode 100644 index 000000000000..9e342f2b99da --- /dev/null +++ b/llvm/test/Transforms/SampleProfile/csspgo-import-list-preinliner.ll @@ -0,0 +1,50 @@ +; RUN: opt < %s -passes='thinlto-pre-link<O2>' -pgo-kind=pgo-sample-use-pipeline -sample-profile-file=%S/Inputs/csspgo-import-list-preinliner.prof -S -profile-summary-cutoff-hot=100000 -sample-profile-use-preinliner=0 | FileCheck %s --check-prefix=DISABLE-PREINLINE +; RUN: opt < %s -passes='thinlto-pre-link<O2>' -pgo-kind=pgo-sample-use-pipeline -sample-profile-file=%S/Inputs/csspgo-import-list-preinliner.prof -S -profile-summary-cutoff-hot=100000 | FileCheck %s + +; The GUID of bar is -2012135647395072713 + +; DISABLE-PREINLINE-NOT: -2012135647395072713 +; CHECK: [[#]] = !{!"function_entry_count", i64 1, i64 -2012135647395072713} + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @main() #0 { +entry: + br label %for.cond + +for.cond: ; preds = %for.cond, %entry + call void @llvm.pseudoprobe(i64 0, i64 0, i32 0, i64 0) + %call2 = call i32 @bar(), !dbg !9 + br label %for.cond +} + +declare i32 @bar() + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) +declare void @llvm.pseudoprobe(i64, i64, i32, i64) #1 + +attributes #0 = { "use-sample-profile" } +attributes #1 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7} +!llvm.pseudo_probe_desc = !{!8} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 19.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/home/", checksumkind: CSK_MD5, checksum: "1bff37d8b3f7858b0bc29ab4efdf9422") +!2 = !{!3} +!3 = !DIGlobalVariableExpression(var: !4, expr: !DIExpression()) +!4 = distinct !DIGlobalVariable(name: "x", scope: !0, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true) +!5 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !6) +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i64 -2624081020897602054, i64 563108639284859, !"main"} +!9 = !DILocation(line: 11, column: 10, scope: !10) +!10 = !DILexicalBlockFile(scope: !11, file: !1, discriminator: 186646615) +!11 = distinct !DILexicalBlock(scope: !12, file: !1, line: 8, column: 40) +!12 = distinct !DILexicalBlock(scope: !13, file: !1, line: 8, column: 3) +!13 = distinct !DILexicalBlock(scope: !14, file: !1, line: 8, column: 3) +!14 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 6, type: !15, scopeLine: 7, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !16) +!15 = distinct !DISubroutineType(types: !16) +!16 = !{} -- GitLab From f2bb6fb0ca0bfbaf39d9b8039df22b6918ac99b6 Mon Sep 17 00:00:00 2001 From: Jeremy Kun <jkun@google.com> Date: Tue, 19 Mar 2024 17:02:43 -0700 Subject: [PATCH 162/307] Add Maksim and me to office hours (#85824) Followup from https://discourse.llvm.org/t/extending-an-invitation-to-compiler-newbies-compilers-coffee/77776 --- llvm/docs/GettingInvolved.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/llvm/docs/GettingInvolved.rst b/llvm/docs/GettingInvolved.rst index 763aeb87c688..a4247796cb65 100644 --- a/llvm/docs/GettingInvolved.rst +++ b/llvm/docs/GettingInvolved.rst @@ -323,6 +323,11 @@ The :doc:`CodeOfConduct` applies to all office hours. - Monthly, 4th Wednesday of the month at 9:30am PT, for 30 minutes. - `Google meet <https://meet.google.com/pdd-dibg-cwv>`__ - English + * - Maksim Levental and Jeremy Kun + - MLIR newcomers and general discussion (`livestreamed <https://www.youtube.com/playlist?list=PLhxO86S3jsX2k7kOhZaV-qKWm8tNsUdAE>`__) + - Every two weeks, Fridays at 3:00pm US Pacific, for 90 minutes. + - Livestream chat or `Google meet <https://meet.google.com/wit-tvzc-dwc>`__ + - English * - Rotating hosts - Getting Started, beginner questions, new contributors. - Every Tuesday at 2 PM ET (11 AM PT), for 30 minutes. -- GitLab From 4bf06bebb9d34bb7e3e025442dd0c1cb4e9d3911 Mon Sep 17 00:00:00 2001 From: Jiahan Xie <88367305+jiahanxie353@users.noreply.github.com> Date: Tue, 19 Mar 2024 20:12:26 -0400 Subject: [PATCH 163/307] [GISEL][RISCV] IRTranslator for scalable vector load (#80006) Add IRTranslator for scalable vector load instruction and include corresponding tests with alignment argument included, which can be smaller/equal/larger than element size or smaller/equal/larger than the minimum total vector size. --- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 5 +- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +- .../RISCV/GlobalISel/irtranslator/vec-ld.ll | 948 ++++++++++++++++++ 3 files changed, 951 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/vec-ld.ll diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 4c1467ce1c41..c18574071bfb 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1363,9 +1363,8 @@ static bool isSwiftError(const Value *V) { bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) { const LoadInst &LI = cast<LoadInst>(U); - - unsigned StoreSize = DL->getTypeStoreSize(LI.getType()); - if (StoreSize == 0) + TypeSize StoreSize = DL->getTypeStoreSize(LI.getType()); + if (StoreSize.isZero()) return true; ArrayRef<Register> Regs = getOrCreateVRegs(LI); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index c3d1416ed518..4bfd4d0386a8 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -20909,7 +20909,7 @@ bool RISCVTargetLowering::fallBackToDAGISel(const Instruction &Inst) const { if (Op == Instruction::Add || Op == Instruction::Sub || Op == Instruction::And || Op == Instruction::Or || Op == Instruction::Xor || Op == Instruction::InsertElement || - Op == Instruction::Xor || Op == Instruction::ShuffleVector) + Op == Instruction::ShuffleVector || Op == Instruction::Load) return false; if (Inst.getType()->isScalableTy()) diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/vec-ld.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/vec-ld.ll new file mode 100644 index 000000000000..31b3c3fe3c5b --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/vec-ld.ll @@ -0,0 +1,948 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+v -global-isel -stop-after=irtranslator -verify-machineinstrs < %s | FileCheck -check-prefixes=RV32 %s +; RUN: llc -mtriple=riscv64 -mattr=+v -global-isel -stop-after=irtranslator -verify-machineinstrs < %s | FileCheck -check-prefixes=RV64 %s + +define <vscale x 1 x i8> @vload_nx1i8(ptr %pa) { + ; RV32-LABEL: name: vload_nx1i8 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 1 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 1 x s8>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 1 x s8>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx1i8 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 1 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 1 x s8>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 1 x s8>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 1 x i8>, ptr %pa + ret <vscale x 1 x i8> %va +} + +define <vscale x 2 x i8> @vload_nx2i8(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i8 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s8>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s8>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx2i8 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s8>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s8>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 2 x i8>, ptr %pa + ret <vscale x 2 x i8> %va +} + +define <vscale x 4 x i8> @vload_nx4i8(ptr %pa) { + ; RV32-LABEL: name: vload_nx4i8 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s8>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s8>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx4i8 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s8>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s8>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 4 x i8>, ptr %pa + ret <vscale x 4 x i8> %va +} + +define <vscale x 8 x i8> @vload_nx8i8(ptr %pa) { + ; RV32-LABEL: name: vload_nx8i8 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 8 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 8 x s8>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 8 x s8>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx8i8 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 8 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 8 x s8>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 8 x s8>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 8 x i8>, ptr %pa + ret <vscale x 8 x i8> %va +} + +define <vscale x 16 x i8> @vload_nx16i8(ptr %pa) { + ; RV32-LABEL: name: vload_nx16i8 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s8>) from %ir.pa) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 16 x s8>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx16i8 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s8>) from %ir.pa) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 16 x s8>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 16 x i8>, ptr %pa + ret <vscale x 16 x i8> %va +} + +define <vscale x 32 x i8> @vload_nx32i8(ptr %pa) { + ; RV32-LABEL: name: vload_nx32i8 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 32 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 32 x s8>) from %ir.pa) + ; RV32-NEXT: $v8m4 = COPY [[LOAD]](<vscale x 32 x s8>) + ; RV32-NEXT: PseudoRET implicit $v8m4 + ; + ; RV64-LABEL: name: vload_nx32i8 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 32 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 32 x s8>) from %ir.pa) + ; RV64-NEXT: $v8m4 = COPY [[LOAD]](<vscale x 32 x s8>) + ; RV64-NEXT: PseudoRET implicit $v8m4 + %va = load <vscale x 32 x i8>, ptr %pa + ret <vscale x 32 x i8> %va +} + +define <vscale x 64 x i8> @vload_nx64i8(ptr %pa) { + ; RV32-LABEL: name: vload_nx64i8 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 64 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 64 x s8>) from %ir.pa) + ; RV32-NEXT: $v8m8 = COPY [[LOAD]](<vscale x 64 x s8>) + ; RV32-NEXT: PseudoRET implicit $v8m8 + ; + ; RV64-LABEL: name: vload_nx64i8 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 64 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 64 x s8>) from %ir.pa) + ; RV64-NEXT: $v8m8 = COPY [[LOAD]](<vscale x 64 x s8>) + ; RV64-NEXT: PseudoRET implicit $v8m8 + %va = load <vscale x 64 x i8>, ptr %pa + ret <vscale x 64 x i8> %va +} + +define <vscale x 1 x i16> @vload_nx1i16(ptr %pa) { + ; RV32-LABEL: name: vload_nx1i16 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 1 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 1 x s16>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 1 x s16>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx1i16 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 1 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 1 x s16>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 1 x s16>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 1 x i16>, ptr %pa + ret <vscale x 1 x i16> %va +} + +define <vscale x 2 x i16> @vload_nx2i16(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i16 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s16>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s16>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx2i16 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s16>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s16>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 2 x i16>, ptr %pa + ret <vscale x 2 x i16> %va +} + +define <vscale x 4 x i16> @vload_nx4i16(ptr %pa) { + ; RV32-LABEL: name: vload_nx4i16 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx4i16 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 4 x i16>, ptr %pa + ret <vscale x 4 x i16> %va +} + +define <vscale x 8 x i16> @vload_nx8i16(ptr %pa) { + ; RV32-LABEL: name: vload_nx8i16 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 8 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 8 x s16>) from %ir.pa) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 8 x s16>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx8i16 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 8 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 8 x s16>) from %ir.pa) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 8 x s16>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 8 x i16>, ptr %pa + ret <vscale x 8 x i16> %va +} + +define <vscale x 16 x i16> @vload_nx16i16(ptr %pa) { + ; RV32-LABEL: name: vload_nx16i16 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s16>) from %ir.pa) + ; RV32-NEXT: $v8m4 = COPY [[LOAD]](<vscale x 16 x s16>) + ; RV32-NEXT: PseudoRET implicit $v8m4 + ; + ; RV64-LABEL: name: vload_nx16i16 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s16>) from %ir.pa) + ; RV64-NEXT: $v8m4 = COPY [[LOAD]](<vscale x 16 x s16>) + ; RV64-NEXT: PseudoRET implicit $v8m4 + %va = load <vscale x 16 x i16>, ptr %pa + ret <vscale x 16 x i16> %va +} + +define <vscale x 32 x i16> @vload_nx32i16(ptr %pa) { + ; RV32-LABEL: name: vload_nx32i16 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 32 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 32 x s16>) from %ir.pa) + ; RV32-NEXT: $v8m8 = COPY [[LOAD]](<vscale x 32 x s16>) + ; RV32-NEXT: PseudoRET implicit $v8m8 + ; + ; RV64-LABEL: name: vload_nx32i16 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 32 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 32 x s16>) from %ir.pa) + ; RV64-NEXT: $v8m8 = COPY [[LOAD]](<vscale x 32 x s16>) + ; RV64-NEXT: PseudoRET implicit $v8m8 + %va = load <vscale x 32 x i16>, ptr %pa + ret <vscale x 32 x i16> %va +} + +define <vscale x 1 x i32> @vload_nx1i32(ptr %pa) { + ; RV32-LABEL: name: vload_nx1i32 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 1 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 1 x s32>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 1 x s32>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx1i32 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 1 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 1 x s32>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 1 x s32>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 1 x i32>, ptr %pa + ret <vscale x 1 x i32> %va +} + +define <vscale x 2 x i32> @vload_nx2i32(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i32 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx2i32 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 2 x i32>, ptr %pa + ret <vscale x 2 x i32> %va +} + +define <vscale x 4 x i32> @vload_nx4i32(ptr %pa) { + ; RV32-LABEL: name: vload_nx4i32 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s32>) from %ir.pa) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 4 x s32>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx4i32 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s32>) from %ir.pa) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 4 x s32>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 4 x i32>, ptr %pa + ret <vscale x 4 x i32> %va +} + +define <vscale x 8 x i32> @vload_nx8i32(ptr %pa) { + ; RV32-LABEL: name: vload_nx8i32 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 8 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 8 x s32>) from %ir.pa) + ; RV32-NEXT: $v8m4 = COPY [[LOAD]](<vscale x 8 x s32>) + ; RV32-NEXT: PseudoRET implicit $v8m4 + ; + ; RV64-LABEL: name: vload_nx8i32 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 8 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 8 x s32>) from %ir.pa) + ; RV64-NEXT: $v8m4 = COPY [[LOAD]](<vscale x 8 x s32>) + ; RV64-NEXT: PseudoRET implicit $v8m4 + %va = load <vscale x 8 x i32>, ptr %pa + ret <vscale x 8 x i32> %va +} + +define <vscale x 16 x i32> @vload_nx16i32(ptr %pa) { + ; RV32-LABEL: name: vload_nx16i32 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s32>) from %ir.pa) + ; RV32-NEXT: $v8m8 = COPY [[LOAD]](<vscale x 16 x s32>) + ; RV32-NEXT: PseudoRET implicit $v8m8 + ; + ; RV64-LABEL: name: vload_nx16i32 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s32>) from %ir.pa) + ; RV64-NEXT: $v8m8 = COPY [[LOAD]](<vscale x 16 x s32>) + ; RV64-NEXT: PseudoRET implicit $v8m8 + %va = load <vscale x 16 x i32>, ptr %pa + ret <vscale x 16 x i32> %va +} + +define <vscale x 1 x i64> @vload_nx1i64(ptr %pa) { + ; RV32-LABEL: name: vload_nx1i64 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 1 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 1 x s64>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 1 x s64>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx1i64 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 1 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 1 x s64>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 1 x s64>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 1 x i64>, ptr %pa + ret <vscale x 1 x i64> %va +} + +define <vscale x 2 x i64> @vload_nx2i64(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i64 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s64>) from %ir.pa) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 2 x s64>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx2i64 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s64>) from %ir.pa) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 2 x s64>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 2 x i64>, ptr %pa + ret <vscale x 2 x i64> %va +} + +define <vscale x 4 x i64> @vload_nx4i64(ptr %pa) { + ; RV32-LABEL: name: vload_nx4i64 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s64>) from %ir.pa) + ; RV32-NEXT: $v8m4 = COPY [[LOAD]](<vscale x 4 x s64>) + ; RV32-NEXT: PseudoRET implicit $v8m4 + ; + ; RV64-LABEL: name: vload_nx4i64 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s64>) from %ir.pa) + ; RV64-NEXT: $v8m4 = COPY [[LOAD]](<vscale x 4 x s64>) + ; RV64-NEXT: PseudoRET implicit $v8m4 + %va = load <vscale x 4 x i64>, ptr %pa + ret <vscale x 4 x i64> %va +} + +define <vscale x 8 x i64> @vload_nx8i64(ptr %pa) { + ; RV32-LABEL: name: vload_nx8i64 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 8 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 8 x s64>) from %ir.pa) + ; RV32-NEXT: $v8m8 = COPY [[LOAD]](<vscale x 8 x s64>) + ; RV32-NEXT: PseudoRET implicit $v8m8 + ; + ; RV64-LABEL: name: vload_nx8i64 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 8 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 8 x s64>) from %ir.pa) + ; RV64-NEXT: $v8m8 = COPY [[LOAD]](<vscale x 8 x s64>) + ; RV64-NEXT: PseudoRET implicit $v8m8 + %va = load <vscale x 8 x i64>, ptr %pa + ret <vscale x 8 x i64> %va +} + +define <vscale x 16 x i8> @vload_nx16i8_align1(ptr %pa) { + ; RV32-LABEL: name: vload_nx16i8_align1 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s8>) from %ir.pa, align 1) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 16 x s8>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx16i8_align1 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s8>) from %ir.pa, align 1) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 16 x s8>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 16 x i8>, ptr %pa, align 1 + ret <vscale x 16 x i8> %va +} + +define <vscale x 16 x i8> @vload_nx16i8_align2(ptr %pa) { + ; RV32-LABEL: name: vload_nx16i8_align2 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s8>) from %ir.pa, align 2) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 16 x s8>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx16i8_align2 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s8>) from %ir.pa, align 2) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 16 x s8>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 16 x i8>, ptr %pa, align 2 + ret <vscale x 16 x i8> %va +} + +define <vscale x 16 x i8> @vload_nx16i8_align16(ptr %pa) { + ; RV32-LABEL: name: vload_nx16i8_align16 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s8>) from %ir.pa) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 16 x s8>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx16i8_align16 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s8>) from %ir.pa) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 16 x s8>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 16 x i8>, ptr %pa, align 16 + ret <vscale x 16 x i8> %va +} + +define <vscale x 16 x i8> @vload_nx16i8_align64(ptr %pa) { + ; RV32-LABEL: name: vload_nx16i8_align64 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s8>) from %ir.pa, align 64) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 16 x s8>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx16i8_align64 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 16 x s8>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 16 x s8>) from %ir.pa, align 64) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 16 x s8>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 16 x i8>, ptr %pa, align 64 + ret <vscale x 16 x i8> %va +} + +define <vscale x 4 x i16> @vload_nx4i16_align1(ptr %pa) { + ; RV32-LABEL: name: vload_nx4i16_align1 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa, align 1) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx4i16_align1 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa, align 1) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 4 x i16>, ptr %pa, align 1 + ret <vscale x 4 x i16> %va +} + +define <vscale x 4 x i16> @vload_nx4i16_align2(ptr %pa) { + ; RV32-LABEL: name: vload_nx4i16_align2 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa, align 2) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx4i16_align2 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa, align 2) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 4 x i16>, ptr %pa, align 2 + ret <vscale x 4 x i16> %va +} + +define <vscale x 4 x i16> @vload_nx4i16_align4(ptr %pa) { + ; RV32-LABEL: name: vload_nx4i16_align4 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa, align 4) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx4i16_align4 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa, align 4) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 4 x i16>, ptr %pa, align 4 + ret <vscale x 4 x i16> %va +} +define <vscale x 4 x i16> @vload_nx4i16_align8(ptr %pa) { + ; RV32-LABEL: name: vload_nx4i16_align8 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx4i16_align8 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 4 x i16>, ptr %pa, align 8 + ret <vscale x 4 x i16> %va +} + +define <vscale x 4 x i16> @vload_nx4i16_align16(ptr %pa) { + ; RV32-LABEL: name: vload_nx4i16_align16 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa, align 16) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx4i16_align16 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s16>) from %ir.pa, align 16) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 4 x s16>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 4 x i16>, ptr %pa, align 16 + ret <vscale x 4 x i16> %va +} + +define <vscale x 2 x i32> @vload_nx2i32_align2(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i32_align2 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa, align 2) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx2i32_align2 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa, align 2) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 2 x i32>, ptr %pa, align 2 + ret <vscale x 2 x i32> %va +} + +define <vscale x 2 x i32> @vload_nx2i32_align4(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i32_align4 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa, align 4) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx2i32_align4 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa, align 4) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 2 x i32>, ptr %pa, align 4 + ret <vscale x 2 x i32> %va +} + +define <vscale x 2 x i32> @vload_nx2i32_align8(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i32_align8 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx2i32_align8 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 2 x i32>, ptr %pa, align 8 + ret <vscale x 2 x i32> %va +} + +define <vscale x 2 x i32> @vload_nx2i32_align16(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i32_align16 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa, align 16) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx2i32_align16 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa, align 16) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 2 x i32>, ptr %pa, align 16 + ret <vscale x 2 x i32> %va +} + +define <vscale x 2 x i32> @vload_nx2i32_align256(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i32_align256 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa, align 256) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx2i32_align256 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s32>) from %ir.pa, align 256) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x s32>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 2 x i32>, ptr %pa, align 256 + ret <vscale x 2 x i32> %va +} +define <vscale x 2 x i64> @vload_nx2i64_align4(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i64_align4 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s64>) from %ir.pa, align 4) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 2 x s64>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx2i64_align4 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s64>) from %ir.pa, align 4) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 2 x s64>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 2 x i64>, ptr %pa, align 4 + ret <vscale x 2 x i64> %va +} + +define <vscale x 2 x i64> @vload_nx2i64_align8(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i64_align8 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s64>) from %ir.pa, align 8) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 2 x s64>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx2i64_align8 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s64>) from %ir.pa, align 8) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 2 x s64>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 2 x i64>, ptr %pa, align 8 + ret <vscale x 2 x i64> %va +} + +define <vscale x 2 x i64> @vload_nx2i64_align16(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i64_align16 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s64>) from %ir.pa) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 2 x s64>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx2i64_align16 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s64>) from %ir.pa) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 2 x s64>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 2 x i64>, ptr %pa, align 16 + ret <vscale x 2 x i64> %va +} + +define <vscale x 2 x i64> @vload_nx2i64_align32(ptr %pa) { + ; RV32-LABEL: name: vload_nx2i64_align32 + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s64>) from %ir.pa, align 32) + ; RV32-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 2 x s64>) + ; RV32-NEXT: PseudoRET implicit $v8m2 + ; + ; RV64-LABEL: name: vload_nx2i64_align32 + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x s64>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x s64>) from %ir.pa, align 32) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 2 x s64>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 2 x i64>, ptr %pa, align 32 + ret <vscale x 2 x i64> %va +} + +define <vscale x 1 x ptr> @vload_nx1ptr(ptr %pa) { + ; RV32-LABEL: name: vload_nx1ptr + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 1 x p0>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 1 x p0>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 1 x p0>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx1ptr + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 1 x p0>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 1 x p0>) from %ir.pa) + ; RV64-NEXT: $v8 = COPY [[LOAD]](<vscale x 1 x p0>) + ; RV64-NEXT: PseudoRET implicit $v8 + %va = load <vscale x 1 x ptr>, ptr %pa + ret <vscale x 1 x ptr> %va +} + +define <vscale x 2 x ptr> @vload_nx2ptr(ptr %pa) { + ; RV32-LABEL: name: vload_nx2ptr + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x p0>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x p0>) from %ir.pa) + ; RV32-NEXT: $v8 = COPY [[LOAD]](<vscale x 2 x p0>) + ; RV32-NEXT: PseudoRET implicit $v8 + ; + ; RV64-LABEL: name: vload_nx2ptr + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 2 x p0>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 2 x p0>) from %ir.pa) + ; RV64-NEXT: $v8m2 = COPY [[LOAD]](<vscale x 2 x p0>) + ; RV64-NEXT: PseudoRET implicit $v8m2 + %va = load <vscale x 2x ptr>, ptr %pa + ret <vscale x 2 x ptr> %va +} + +define <vscale x 8 x ptr> @vload_nx8ptr(ptr %pa) { + ; RV32-LABEL: name: vload_nx8ptr + ; RV32: bb.1 (%ir-block.0): + ; RV32-NEXT: liveins: $x10 + ; RV32-NEXT: {{ $}} + ; RV32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV32-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 8 x p0>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 8 x p0>) from %ir.pa) + ; RV32-NEXT: $v8m4 = COPY [[LOAD]](<vscale x 8 x p0>) + ; RV32-NEXT: PseudoRET implicit $v8m4 + ; + ; RV64-LABEL: name: vload_nx8ptr + ; RV64: bb.1 (%ir-block.0): + ; RV64-NEXT: liveins: $x10 + ; RV64-NEXT: {{ $}} + ; RV64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 + ; RV64-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 8 x p0>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 8 x p0>) from %ir.pa) + ; RV64-NEXT: $v8m8 = COPY [[LOAD]](<vscale x 8 x p0>) + ; RV64-NEXT: PseudoRET implicit $v8m8 + %va = load <vscale x 8 x ptr>, ptr %pa + ret <vscale x 8 x ptr> %va +} + -- GitLab From 36146d2b6be53e5e98dee3c1fce8699db9615728 Mon Sep 17 00:00:00 2001 From: Fangrui Song <i@maskray.me> Date: Tue, 19 Mar 2024 17:12:40 -0700 Subject: [PATCH 164/307] [ELF] Make LinkerDrive::link a template. NFC This avoids many invokeELFT in `link`. --- lld/ELF/Config.h | 2 +- lld/ELF/Driver.cpp | 26 +++++++++++++------------- lld/ELF/InputFiles.cpp | 2 +- lld/ELF/InputFiles.h | 1 + 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 6c46249c5287..bb3608da80b2 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -126,7 +126,7 @@ public: private: void createFiles(llvm::opt::InputArgList &args); void inferMachineType(); - void link(llvm::opt::InputArgList &args); + template <class ELFT> void link(llvm::opt::InputArgList &args); template <class ELFT> void compileBitcodeFiles(bool skipLinkedOutput); bool tryAddFatLTOFile(MemoryBufferRef mb, StringRef archiveName, uint64_t offsetInArchive, bool lazy); diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 40d3f2caa133..7257ebd0fac9 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -650,7 +650,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) { if (errorCount()) return; - link(args); + invokeELFT(link, args); } if (config->timeTraceEnabled) { @@ -2711,7 +2711,7 @@ static void postParseObjectFile(ELFFileBase *file) { // Do actual linking. Note that when this function is called, // all linker scripts have already been parsed. -void LinkerDriver::link(opt::InputArgList &args) { +template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) { llvm::TimeTraceScope timeScope("Link", StringRef("LinkerDriver::Link")); // Handle --trace-symbol. @@ -2733,7 +2733,7 @@ void LinkerDriver::link(opt::InputArgList &args) { llvm::TimeTraceScope timeScope("Parse input files"); for (size_t i = 0; i < files.size(); ++i) { llvm::TimeTraceScope timeScope("Parse input files", files[i]->getName()); - parseFile(files[i]); + doParseFile<ELFT>(files[i]); } if (armCmseImpLib) parseArmCMSEImportLib(*armCmseImpLib); @@ -2867,7 +2867,7 @@ void LinkerDriver::link(opt::InputArgList &args) { // Handle --lto-validate-all-vtables-have-type-infos. if (config->ltoValidateAllVtablesHaveTypeInfos) - invokeELFT(ltoValidateAllVtablesHaveTypeInfos, args); + ltoValidateAllVtablesHaveTypeInfos<ELFT>(args); // Do link-time optimization if given files are LLVM bitcode files. // This compiles bitcode files into real object files. @@ -2875,7 +2875,7 @@ void LinkerDriver::link(opt::InputArgList &args) { // With this the symbol table should be complete. After this, no new names // except a few linker-synthesized ones will be added to the symbol table. const size_t numObjsBeforeLTO = ctx.objectFiles.size(); - invokeELFT(compileBitcodeFiles, skipLinkedOutput); + compileBitcodeFiles<ELFT>(skipLinkedOutput); // Symbol resolution finished. Report backward reference problems, // --print-archive-stats=, and --why-extract=. @@ -2940,7 +2940,7 @@ void LinkerDriver::link(opt::InputArgList &args) { llvm::erase_if(ctx.inputSections, [](InputSectionBase *s) { if (s->type != SHT_LLVM_SYMPART) return false; - invokeELFT(readSymbolPartitionSection, s); + readSymbolPartitionSection<ELFT>(s); return true; }); } @@ -2998,10 +2998,10 @@ void LinkerDriver::link(opt::InputArgList &args) { ctx.inputSections.push_back(createCommentSection()); // Split SHF_MERGE and .eh_frame sections into pieces in preparation for garbage collection. - invokeELFT(splitSections,); + splitSections<ELFT>(); // Garbage collection and removal of shared symbols from unused shared objects. - invokeELFT(markLive,); + markLive<ELFT>(); // Make copies of any input sections that need to be copied into each // partition. @@ -3014,7 +3014,7 @@ void LinkerDriver::link(opt::InputArgList &args) { // Create synthesized sections such as .got and .plt. This is called before // processSectionCommands() so that they can be placed by SECTIONS commands. - invokeELFT(createSyntheticSections,); + createSyntheticSections<ELFT>(); // Some input sections that are used for exception handling need to be moved // into synthetic sections. Do that now so that they aren't assigned to @@ -3054,8 +3054,8 @@ void LinkerDriver::link(opt::InputArgList &args) { // Two input sections with different output sections should not be folded. // ICF runs after processSectionCommands() so that we know the output sections. if (config->icf != ICFLevel::None) { - invokeELFT(findKeepUniqueSections, args); - invokeELFT(doIcf,); + findKeepUniqueSections<ELFT>(args); + doIcf<ELFT>(); } // Read the callgraph now that we know what was gced or icfed @@ -3063,9 +3063,9 @@ void LinkerDriver::link(opt::InputArgList &args) { if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file)) if (std::optional<MemoryBufferRef> buffer = readFile(arg->getValue())) readCallGraph(*buffer); - invokeELFT(readCallGraphsFromObjectFiles,); + readCallGraphsFromObjectFiles<ELFT>(); } // Write the result to the file. - invokeELFT(writeResult,); + writeResult<ELFT>(); } diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index e6bf39b6b0bf..4a6e691938cf 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -288,7 +288,7 @@ static bool isCompatible(InputFile *file) { return false; } -template <class ELFT> static void doParseFile(InputFile *file) { +template <class ELFT> void elf::doParseFile(InputFile *file) { if (!isCompatible(file)) return; diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 54de842a81cf..3beb5a3cb9a8 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -46,6 +46,7 @@ extern std::unique_ptr<llvm::TarWriter> tar; std::optional<MemoryBufferRef> readFile(StringRef path); // Add symbols in File to the symbol table. +template <class ELFT> void doParseFile(InputFile *file); void parseFile(InputFile *file); void parseArmCMSEImportLib(InputFile *file); -- GitLab From 595280af561fdba156efbdd654ed4076855aac9c Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jonas@devlieghere.com> Date: Tue, 19 Mar 2024 17:16:47 -0700 Subject: [PATCH 165/307] Revert "[llvm] Include LLVM_REPOSITORY and LLVM_REVISION in tool version" (#85879) Reverts llvm/llvm-project#84990 because this causes a full rebuild after the commit hash changes. --- llvm/lib/Support/CMakeLists.txt | 3 --- llvm/lib/Support/CommandLine.cpp | 11 +---------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index da2a4b4cdec5..e18beddf7bc5 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -288,9 +288,6 @@ add_llvm_component_library(LLVMSupport ${LLVM_MAIN_INCLUDE_DIR}/llvm/Support ${Backtrace_INCLUDE_DIRS} - DEPENDS - llvm_vcsrevision_h - LINK_LIBS ${system_libs} ${imported_libs} ${delayload_flags} diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index 42dbc4de2003..c076ae8b8431 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -39,7 +39,6 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/StringSaver.h" -#include "llvm/Support/VCSRevision.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include <cstdlib> @@ -2539,15 +2538,7 @@ public: #else OS << "LLVM (http://llvm.org/):\n "; #endif - OS << PACKAGE_NAME << " version " << PACKAGE_VERSION; -#ifdef LLVM_REPOSITORY - OS << " (" << LLVM_REPOSITORY; -#ifdef LLVM_REVISION - OS << ' ' << LLVM_REVISION; -#endif - OS << ')'; -#endif - OS << "\n "; + OS << PACKAGE_NAME << " version " << PACKAGE_VERSION << "\n "; #if LLVM_IS_DEBUG_BUILD OS << "DEBUG build"; #else -- GitLab From 22ac5f743811ae1e5004fdd43be556ebbd0496d1 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme <thomas.preudhomme@arm.com> Date: Wed, 20 Mar 2024 00:25:37 +0000 Subject: [PATCH 166/307] [MLIR] Add missing MLIRFuncDialect dep to MLIRMemRefToLLVM (#84546) This fixes the following failure when doing a clean build (in particular no .ninja* lying around) of lib/libMLIRMemRefToLLVM.a only: ``` In file included from mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp:18: mlir/include/mlir/Dialect/Func/IR/FuncOps.h:29:10: fatal error: mlir/Dialect/Func/IR/FuncOps.h.inc: No such file or directory ``` --- mlir/lib/Conversion/MemRefToLLVM/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/mlir/lib/Conversion/MemRefToLLVM/CMakeLists.txt b/mlir/lib/Conversion/MemRefToLLVM/CMakeLists.txt index 1400618c93e8..f0d95f5ada29 100644 --- a/mlir/lib/Conversion/MemRefToLLVM/CMakeLists.txt +++ b/mlir/lib/Conversion/MemRefToLLVM/CMakeLists.txt @@ -14,6 +14,7 @@ add_mlir_conversion_library(MLIRMemRefToLLVM LINK_LIBS PUBLIC MLIRAnalysis MLIRDataLayoutInterfaces + MLIRFuncDialect MLIRLLVMCommonConversion MLIRMemRefDialect MLIRMemRefUtils -- GitLab From f5f3d5d6534f0a38c771119653dac3330c9f207f Mon Sep 17 00:00:00 2001 From: Qizhi Hu <836744285@qq.com> Date: Wed, 20 Mar 2024 08:33:30 +0800 Subject: [PATCH 167/307] [Clang][Sema] Fix a crash in lambda instantiation (#85565) Fix https://github.com/llvm/llvm-project/issues/85343 When build lambda expression in lambda instantiation, `ThisType` is required in `Sema::CheckCXXThisCapture` to build `this` capture. Set `this` type by import `Sema::CXXThisScopeRAII` and it will be used later in lambda expression transformation. Co-authored-by: huqizhi <836744285@qq.com> --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/TreeTransform.h | 10 ++++++++++ clang/test/Sema/PR85343.cpp | 22 ++++++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 clang/test/Sema/PR85343.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 5ddad61e27c9..0ce3cbe3266e 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -401,6 +401,7 @@ Bug Fixes to C++ Support expression references to an entity declared outside of the lambda. (#GH64808) - Clang's __builtin_bit_cast will now produce a constant value for records with empty bases. See: (#GH82383) +- Fix a crash when instantiating a lambda that captures ``this`` outside of its context. Fixes (#GH85343). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 2d22692f3ab7..f2f7d7ab9c7c 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -13714,6 +13714,16 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { // Capturing 'this' is trivial. if (C->capturesThis()) { + // If this is a lambda that is part of a default member initialiser + // and which we're instantiating outside the class that 'this' is + // supposed to refer to, adjust the type of 'this' accordingly. + // + // Otherwise, leave the type of 'this' as-is. + Sema::CXXThisScopeRAII ThisScope( + getSema(), + dyn_cast_if_present<CXXRecordDecl>( + getSema().getFunctionLevelDeclContext()), + Qualifiers()); getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(), /*BuildAndDiagnose*/ true, nullptr, C->getCaptureKind() == LCK_StarThis); diff --git a/clang/test/Sema/PR85343.cpp b/clang/test/Sema/PR85343.cpp new file mode 100644 index 000000000000..d90ef19d4234 --- /dev/null +++ b/clang/test/Sema/PR85343.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++14 -verify %s +// expected-no-diagnostics + +template <typename c> auto ab() -> c ; + +template <typename> struct e {}; + +template <typename f> struct ac { + template <typename h> static e<decltype(ab<h>()(ab<int>))> i; + decltype(i<f>) j; +}; + +struct d { + template <typename f> + d(f) { + ac<f> a; + } +}; +struct a { + d b = [=](auto) { (void)[this] {}; }; +}; +void b() { new a; } -- GitLab From e2fa90fa0a4b7950dd0d7fae6933e89c075d0af0 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani <ismail@bennani.ma> Date: Wed, 20 Mar 2024 00:42:59 +0000 Subject: [PATCH 168/307] [lldb/API] Add missing `eBroadcastBitSymbolsChanged` to SBTarget (NFC) (#85883) This patch exposes the missing `eBroadcastBitSymbolsChanged` event bit in `SBTarget`. Signed-off-by: Med Ismail Bennani <ismail@bennani.ma> --- lldb/include/lldb/API/SBTarget.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index f7bdd3093d20..3644ac056da3 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -42,7 +42,8 @@ public: eBroadcastBitModulesLoaded = (1 << 1), eBroadcastBitModulesUnloaded = (1 << 2), eBroadcastBitWatchpointChanged = (1 << 3), - eBroadcastBitSymbolsLoaded = (1 << 4) + eBroadcastBitSymbolsLoaded = (1 << 4), + eBroadcastBitSymbolsChanged = (1 << 5), }; // Constructors -- GitLab From a289f66efd638c2af14cdb88968e4eaeea0c0605 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jonas@devlieghere.com> Date: Tue, 19 Mar 2024 17:48:46 -0700 Subject: [PATCH 169/307] Revert "[lldb] Store SupportFile in FileEntry (NFC)" (#85885) Reverts llvm/llvm-project#85468 because @slackito reports this broke stepping in one of their tests [1] and this patch was meant to be NFC. [1] https://github.com/llvm/llvm-project/commit/d5a277d309e92b1d3e493da6036cffdf815105b1#commitcomment-139991120 --- lldb/include/lldb/Core/Disassembler.h | 2 +- lldb/include/lldb/Symbol/LineEntry.h | 34 +++++++------------ lldb/include/lldb/Utility/SupportFile.h | 3 -- lldb/source/API/SBLineEntry.cpp | 10 +++--- lldb/source/API/SBThread.cpp | 2 +- lldb/source/Breakpoint/BreakpointResolver.cpp | 2 +- .../Breakpoint/BreakpointResolverFileLine.cpp | 7 ++-- .../Commands/CommandObjectBreakpoint.cpp | 4 +-- lldb/source/Commands/CommandObjectSource.cpp | 14 ++++---- lldb/source/Commands/CommandObjectThread.cpp | 2 +- lldb/source/Core/Address.cpp | 2 +- lldb/source/Core/Disassembler.cpp | 8 ++--- lldb/source/Core/FormatEntity.cpp | 2 +- lldb/source/Core/IOHandlerCursesGUI.cpp | 11 +++--- lldb/source/Core/SourceManager.cpp | 2 +- .../Clang/ClangExpressionSourceCode.cpp | 2 +- .../Plugins/Language/CPlusPlus/LibCxx.cpp | 4 +-- lldb/source/Symbol/CompileUnit.cpp | 2 +- lldb/source/Symbol/Function.cpp | 4 +-- lldb/source/Symbol/LineEntry.cpp | 17 ++++------ lldb/source/Symbol/LineTable.cpp | 4 +-- lldb/source/Symbol/SymbolContext.cpp | 4 +-- lldb/source/Target/StackFrame.cpp | 2 +- lldb/source/Target/StackFrameList.cpp | 4 +-- lldb/source/Target/Thread.cpp | 8 ++--- lldb/source/Target/TraceDumper.cpp | 4 +-- 26 files changed, 71 insertions(+), 89 deletions(-) diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h index e037a49f152c..885ac1bb4a7e 100644 --- a/lldb/include/lldb/Core/Disassembler.h +++ b/lldb/include/lldb/Core/Disassembler.h @@ -538,7 +538,7 @@ protected: ElideMixedSourceAndDisassemblyLine(const ExecutionContext &exe_ctx, const SymbolContext &sc, LineEntry &line) { SourceLine sl; - sl.file = line.GetFile(); + sl.file = line.file; sl.line = line.line; sl.column = line.column; return ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, sl); diff --git a/lldb/include/lldb/Symbol/LineEntry.h b/lldb/include/lldb/Symbol/LineEntry.h index eb8ad6ee9368..c2daba916e3f 100644 --- a/lldb/include/lldb/Symbol/LineEntry.h +++ b/lldb/include/lldb/Symbol/LineEntry.h @@ -130,28 +130,18 @@ struct LineEntry { /// Shared pointer to the target this LineEntry belongs to. void ApplyFileMappings(lldb::TargetSP target_sp); - const FileSpec &GetFile() const { - assert(file_sp); - return file_sp->GetSpecOnly(); - } - - /// The section offset address range for this line entry. - AddressRange range; - - /// The source file, possibly mapped by the target.source-map setting. - lldb::SupportFileSP file_sp; - - /// The original source file, from debug info. - lldb::SupportFileSP original_file_sp; - - /// The source line number, or LLDB_INVALID_LINE_NUMBER if there is no line - /// number information. - uint32_t line = LLDB_INVALID_LINE_NUMBER; - - /// The column number of the source line, or zero if there is no column - /// information. - uint16_t column = 0; - + // Member variables. + AddressRange range; ///< The section offset address range for this line entry. + FileSpec file; ///< The source file, possibly mapped by the target.source-map + ///setting + lldb::SupportFileSP + original_file_sp; ///< The original source file, from debug info. + uint32_t line = LLDB_INVALID_LINE_NUMBER; ///< The source line number, or zero + ///< if there is no line number + /// information. + uint16_t column = + 0; ///< The column number of the source line, or zero if there + /// is no column information. uint16_t is_start_of_statement : 1, ///< Indicates this entry is the beginning ///of a statement. is_start_of_basic_block : 1, ///< Indicates this entry is the beginning of diff --git a/lldb/include/lldb/Utility/SupportFile.h b/lldb/include/lldb/Utility/SupportFile.h index 7505d7f345c5..0ea0ca4e7c97 100644 --- a/lldb/include/lldb/Utility/SupportFile.h +++ b/lldb/include/lldb/Utility/SupportFile.h @@ -45,9 +45,6 @@ public: /// Materialize the file to disk and return the path to that temporary file. virtual const FileSpec &Materialize() { return m_file_spec; } - /// Change the file name. - void Update(const FileSpec &file_spec) { m_file_spec = file_spec; } - protected: FileSpec m_file_spec; Checksum m_checksum; diff --git a/lldb/source/API/SBLineEntry.cpp b/lldb/source/API/SBLineEntry.cpp index f9fd750c2ee6..28d12e65fdaf 100644 --- a/lldb/source/API/SBLineEntry.cpp +++ b/lldb/source/API/SBLineEntry.cpp @@ -81,8 +81,8 @@ SBFileSpec SBLineEntry::GetFileSpec() const { LLDB_INSTRUMENT_VA(this); SBFileSpec sb_file_spec; - if (m_opaque_up.get() && m_opaque_up->GetFile()) - sb_file_spec.SetFileSpec(m_opaque_up->GetFile()); + if (m_opaque_up.get() && m_opaque_up->file) + sb_file_spec.SetFileSpec(m_opaque_up->file); return sb_file_spec; } @@ -109,9 +109,9 @@ void SBLineEntry::SetFileSpec(lldb::SBFileSpec filespec) { LLDB_INSTRUMENT_VA(this, filespec); if (filespec.IsValid()) - ref().file_sp->Update(filespec.ref()); + ref().file = filespec.ref(); else - ref().file_sp->Update(FileSpec()); + ref().file.Clear(); } void SBLineEntry::SetLine(uint32_t line) { LLDB_INSTRUMENT_VA(this, line); @@ -168,7 +168,7 @@ bool SBLineEntry::GetDescription(SBStream &description) { if (m_opaque_up) { char file_path[PATH_MAX * 2]; - m_opaque_up->GetFile().GetPath(file_path, sizeof(file_path)); + m_opaque_up->file.GetPath(file_path, sizeof(file_path)); strm.Printf("%s:%u", file_path, GetLine()); if (GetColumn() > 0) strm.Printf(":%u", GetColumn()); diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index eb9cf063802c..fa4c80e59d97 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -819,7 +819,7 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, step_file_spec = sb_file_spec.ref(); } else { if (frame_sc.line_entry.IsValid()) - step_file_spec = frame_sc.line_entry.GetFile(); + step_file_spec = frame_sc.line_entry.file; else { sb_error.SetErrorString("invalid file argument or no file for frame"); return sb_error; diff --git a/lldb/source/Breakpoint/BreakpointResolver.cpp b/lldb/source/Breakpoint/BreakpointResolver.cpp index ff4e2a998519..1861a0fe7c4f 100644 --- a/lldb/source/Breakpoint/BreakpointResolver.cpp +++ b/lldb/source/Breakpoint/BreakpointResolver.cpp @@ -221,7 +221,7 @@ void BreakpointResolver::SetSCMatchesByLine( auto &match = all_scs[0]; auto worklist_begin = std::partition( all_scs.begin(), all_scs.end(), [&](const SymbolContext &sc) { - if (sc.line_entry.GetFile() == match.line_entry.GetFile() || + if (sc.line_entry.file == match.line_entry.file || *sc.line_entry.original_file_sp == *match.line_entry.original_file_sp) { // When a match is found, keep track of the smallest line number. diff --git a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp index d7d8c714867e..cc4e1d26724f 100644 --- a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -147,9 +147,8 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list) { else continue; - if (file != sc.line_entry.GetFile()) { - LLDB_LOG(log, "unexpected symbol context file {0}", - sc.line_entry.GetFile()); + if (file != sc.line_entry.file) { + LLDB_LOG(log, "unexpected symbol context file {0}", sc.line_entry.file); continue; } @@ -224,7 +223,7 @@ void BreakpointResolverFileLine::DeduceSourceMapping( const bool case_sensitive = request_file.IsCaseSensitive(); for (const SymbolContext &sc : sc_list) { - FileSpec sc_file = sc.line_entry.GetFile(); + FileSpec sc_file = sc.line_entry.file; if (FileSpec::Equal(sc_file, request_file, /*full*/ true)) continue; diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index cd4c7790f447..fbece865f113 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -780,8 +780,8 @@ private: } else { const SymbolContext &sc = cur_frame->GetSymbolContext(eSymbolContextLineEntry); - if (sc.line_entry.GetFile()) { - file = sc.line_entry.GetFile(); + if (sc.line_entry.file) { + file = sc.line_entry.file; } else { result.AppendError("Can't find the file for the selected frame to " "use as the default file."); diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp index 0c1267456a18..fde74f02aea6 100644 --- a/lldb/source/Commands/CommandObjectSource.cpp +++ b/lldb/source/Commands/CommandObjectSource.cpp @@ -158,7 +158,7 @@ protected: if (module_list.GetSize() && module_list.GetIndexForModule(module) == LLDB_INVALID_INDEX32) continue; - if (!FileSpec::Match(file_spec, line_entry.GetFile())) + if (!FileSpec::Match(file_spec, line_entry.file)) continue; if (start_line > 0 && line_entry.line < start_line) continue; @@ -239,7 +239,7 @@ protected: num_matches++; if (num_lines > 0 && num_matches > num_lines) break; - assert(cu_file_spec == line_entry.GetFile()); + assert(cu_file_spec == line_entry.file); if (!cu_header_printed) { if (num_matches > 0) strm << "\n\n"; @@ -760,11 +760,11 @@ protected: bool operator<(const SourceInfo &rhs) const { if (function.GetCString() < rhs.function.GetCString()) return true; - if (line_entry.GetFile().GetDirectory().GetCString() < - rhs.line_entry.GetFile().GetDirectory().GetCString()) + if (line_entry.file.GetDirectory().GetCString() < + rhs.line_entry.file.GetDirectory().GetCString()) return true; - if (line_entry.GetFile().GetFilename().GetCString() < - rhs.line_entry.GetFile().GetFilename().GetCString()) + if (line_entry.file.GetFilename().GetCString() < + rhs.line_entry.file.GetFilename().GetCString()) return true; if (line_entry.line < rhs.line_entry.line) return true; @@ -799,7 +799,7 @@ protected: sc.function->GetEndLineSourceInfo(end_file, end_line); } else { // We have an inlined function - start_file = source_info.line_entry.GetFile(); + start_file = source_info.line_entry.file; start_line = source_info.line_entry.line; end_line = start_line + m_options.num_lines; } diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index aee4e84ea0e4..cf4f8ccaa0c4 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -1705,7 +1705,7 @@ protected: line = sym_ctx.line_entry.line + m_options.m_line_offset; // Try the current file, but override if asked. - FileSpec file = sym_ctx.line_entry.file_sp->GetSpecOnly(); + FileSpec file = sym_ctx.line_entry.file; if (m_options.m_filenames.GetSize() == 1) file = m_options.m_filenames.GetFileSpecAtIndex(0); diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index b23398883fa5..6f5c366ab38a 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -398,7 +398,7 @@ bool Address::GetDescription(Stream &s, Target &target, "Non-brief descriptions not implemented"); LineEntry line_entry; if (CalculateSymbolContextLineEntry(line_entry)) { - s.Printf(" (%s:%u:%u)", line_entry.GetFile().GetFilename().GetCString(), + s.Printf(" (%s:%u:%u)", line_entry.file.GetFilename().GetCString(), line_entry.line, line_entry.column); return true; } diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp index cf37c3961ef1..7b07fcb26813 100644 --- a/lldb/source/Core/Disassembler.cpp +++ b/lldb/source/Core/Disassembler.cpp @@ -201,7 +201,7 @@ Disassembler::GetFunctionDeclLineEntry(const SymbolContext &sc) { uint32_t func_decl_line; sc.function->GetStartLineSourceInfo(func_decl_file, func_decl_line); - if (func_decl_file != prologue_end_line.file_sp->GetSpecOnly() && + if (func_decl_file != prologue_end_line.file && func_decl_file != prologue_end_line.original_file_sp->GetSpecOnly()) return {}; @@ -354,7 +354,7 @@ void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch, } if (sc.line_entry.IsValid()) { SourceLine this_line; - this_line.file = sc.line_entry.GetFile(); + this_line.file = sc.line_entry.file; this_line.line = sc.line_entry.line; this_line.column = sc.line_entry.column; if (!ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, this_line)) @@ -406,7 +406,7 @@ void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch, uint32_t func_decl_line; sc.function->GetStartLineSourceInfo(func_decl_file, func_decl_line); - if (func_decl_file == prologue_end_line.GetFile() || + if (func_decl_file == prologue_end_line.file || func_decl_file == prologue_end_line.original_file_sp->GetSpecOnly()) { // Add all the lines between the function declaration and @@ -439,7 +439,7 @@ void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch, if (sc != prev_sc && sc.comp_unit && sc.line_entry.IsValid()) { SourceLine this_line; - this_line.file = sc.line_entry.GetFile(); + this_line.file = sc.line_entry.file; this_line.line = sc.line_entry.line; if (!ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp index ba62e2625259..cf82676bedda 100644 --- a/lldb/source/Core/FormatEntity.cpp +++ b/lldb/source/Core/FormatEntity.cpp @@ -1792,7 +1792,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, if (sc && sc->line_entry.IsValid()) { Module *module = sc->module_sp.get(); if (module) { - if (DumpFile(s, sc->line_entry.GetFile(), (FileKind)entry.number)) + if (DumpFile(s, sc->line_entry.file, (FileKind)entry.number)) return true; } } diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp b/lldb/source/Core/IOHandlerCursesGUI.cpp index d922d32f9105..f86dce247135 100644 --- a/lldb/source/Core/IOHandlerCursesGUI.cpp +++ b/lldb/source/Core/IOHandlerCursesGUI.cpp @@ -6894,8 +6894,7 @@ public: if (context_changed) m_selected_line = m_pc_line; - if (m_file_sp && - m_file_sp->GetFileSpec() == m_sc.line_entry.GetFile()) { + if (m_file_sp && m_file_sp->GetFileSpec() == m_sc.line_entry.file) { // Same file, nothing to do, we should either have the lines or // not (source file missing) if (m_selected_line >= static_cast<size_t>(m_first_visible_line)) { @@ -6910,8 +6909,8 @@ public: } else { // File changed, set selected line to the line with the PC m_selected_line = m_pc_line; - m_file_sp = m_debugger.GetSourceManager().GetFile( - m_sc.line_entry.GetFile()); + m_file_sp = + m_debugger.GetSourceManager().GetFile(m_sc.line_entry.file); if (m_file_sp) { const size_t num_lines = m_file_sp->GetNumLines(); m_line_width = 1; @@ -7001,7 +7000,7 @@ public: LineEntry bp_loc_line_entry; if (bp_loc_sp->GetAddress().CalculateSymbolContextLineEntry( bp_loc_line_entry)) { - if (m_file_sp->GetFileSpec() == bp_loc_line_entry.GetFile()) { + if (m_file_sp->GetFileSpec() == bp_loc_line_entry.file) { bp_lines.insert(bp_loc_line_entry.line); } } @@ -7478,7 +7477,7 @@ public: LineEntry bp_loc_line_entry; if (bp_loc_sp->GetAddress().CalculateSymbolContextLineEntry( bp_loc_line_entry)) { - if (m_file_sp->GetFileSpec() == bp_loc_line_entry.GetFile() && + if (m_file_sp->GetFileSpec() == bp_loc_line_entry.file && m_selected_line + 1 == bp_loc_line_entry.line) { bool removed = exe_ctx.GetTargetRef().RemoveBreakpointByID(bp_sp->GetID()); diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp index 0d70c554e534..517a4b0268d2 100644 --- a/lldb/source/Core/SourceManager.cpp +++ b/lldb/source/Core/SourceManager.cpp @@ -418,7 +418,7 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) { if (sc.function->GetAddressRange() .GetBaseAddress() .CalculateSymbolContextLineEntry(line_entry)) { - SetDefaultFileAndLine(line_entry.GetFile(), line_entry.line); + SetDefaultFileAndLine(line_entry.file, line_entry.line); file_spec = m_last_file_spec; line = m_last_line; return true; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp index 3b601726388d..3d43ed3f99ff 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp @@ -417,7 +417,7 @@ bool ClangExpressionSourceCode::GetText( if (sc.comp_unit && sc.line_entry.IsValid()) { DebugMacros *dm = sc.comp_unit->GetDebugMacros(); if (dm) { - AddMacroState state(sc.line_entry.GetFile(), sc.line_entry.line); + AddMacroState state(sc.line_entry.file, sc.line_entry.line); AddMacros(dm, sc.comp_unit, state, debug_macros_stream); } } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index bcb04fae15bd..10a1fe039189 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -106,13 +106,13 @@ bool lldb_private::formatters::LibcxxFunctionSummaryProvider( case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Lambda: stream.Printf( " Lambda in File %s at Line %u", - callable_info.callable_line_entry.GetFile().GetFilename().GetCString(), + callable_info.callable_line_entry.file.GetFilename().GetCString(), callable_info.callable_line_entry.line); break; case CPPLanguageRuntime::LibCppStdFunctionCallableCase::CallableObject: stream.Printf( " Function in File %s at Line %u", - callable_info.callable_line_entry.GetFile().GetFilename().GetCString(), + callable_info.callable_line_entry.file.GetFilename().GetCString(), callable_info.callable_line_entry.line); break; case CPPLanguageRuntime::LibCppStdFunctionCallableCase::FreeOrMemberFunction: diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp index ddeacf18e855..1b3cd23d9400 100644 --- a/lldb/source/Symbol/CompileUnit.cpp +++ b/lldb/source/Symbol/CompileUnit.cpp @@ -320,7 +320,7 @@ void CompileUnit::ResolveSymbolContext( src_location_spec.GetColumn() ? std::optional<uint16_t>(line_entry.column) : std::nullopt; - SourceLocationSpec found_entry(line_entry.GetFile(), line_entry.line, column, + SourceLocationSpec found_entry(line_entry.file, line_entry.line, column, inlines, exact); while (line_idx != UINT32_MAX) { diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp index 194f89bc51d8..fdc090355771 100644 --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -289,7 +289,7 @@ void Function::GetStartLineSourceInfo(FileSpec &source_file, if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress(), line_entry, nullptr)) { line_no = line_entry.line; - source_file = line_entry.GetFile(); + source_file = line_entry.file; } } } @@ -311,7 +311,7 @@ void Function::GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no) { LineEntry line_entry; if (line_table->FindLineEntryByAddress(scratch_addr, line_entry, nullptr)) { line_no = line_entry.line; - source_file = line_entry.GetFile(); + source_file = line_entry.file; } } diff --git a/lldb/source/Symbol/LineEntry.cpp b/lldb/source/Symbol/LineEntry.cpp index 58166e2aa951..389f8dcb65d8 100644 --- a/lldb/source/Symbol/LineEntry.cpp +++ b/lldb/source/Symbol/LineEntry.cpp @@ -14,14 +14,12 @@ using namespace lldb_private; LineEntry::LineEntry() - : range(), file_sp(std::make_shared<SupportFile>()), - original_file_sp(std::make_shared<SupportFile>()), - is_start_of_statement(0), is_start_of_basic_block(0), is_prologue_end(0), - is_epilogue_begin(0), is_terminal_entry(0) {} + : range(), file(), is_start_of_statement(0), is_start_of_basic_block(0), + is_prologue_end(0), is_epilogue_begin(0), is_terminal_entry(0) {} void LineEntry::Clear() { range.Clear(); - file_sp = std::make_shared<SupportFile>(); + file.Clear(); original_file_sp = std::make_shared<SupportFile>(); line = LLDB_INVALID_LINE_NUMBER; column = 0; @@ -37,7 +35,6 @@ bool LineEntry::IsValid() const { } bool LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const { - const FileSpec &file = GetFile(); if (file) { if (show_fullpaths) file.Dump(s->AsRawOstream()); @@ -70,7 +67,7 @@ bool LineEntry::Dump(Stream *s, Target *target, bool show_file, return false; } if (show_file) - *s << ", file = " << file_sp->GetSpecOnly(); + *s << ", file = " << file; if (line) s->Printf(", line = %u", line); if (column) @@ -106,7 +103,7 @@ bool LineEntry::GetDescription(Stream *s, lldb::DescriptionLevel level, Address::DumpStyleFileAddress); } - *s << ": " << file_sp->GetSpecOnly(); + *s << ": " << file; if (line) { s->Printf(":%u", line); @@ -176,7 +173,7 @@ int LineEntry::Compare(const LineEntry &a, const LineEntry &b) { if (a.column > b.column) return +1; - return FileSpec::Compare(a.GetFile(), b.GetFile(), true); + return FileSpec::Compare(a.file, b.file, true); } AddressRange LineEntry::GetSameLineContiguousAddressRange( @@ -245,6 +242,6 @@ void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp) { // Apply any file remappings to our file. if (auto new_file_spec = target_sp->GetSourcePathMap().FindFile( original_file_sp->GetSpecOnly())) - file_sp->Update(*new_file_spec); + file = *new_file_spec; } } diff --git a/lldb/source/Symbol/LineTable.cpp b/lldb/source/Symbol/LineTable.cpp index 23c5eb617925..444135f63bc0 100644 --- a/lldb/source/Symbol/LineTable.cpp +++ b/lldb/source/Symbol/LineTable.cpp @@ -288,8 +288,8 @@ bool LineTable::ConvertEntryAtIndexToLineEntry(uint32_t idx, else line_entry.range.SetByteSize(0); - line_entry.file_sp = - m_comp_unit->GetSupportFiles().GetSupportFileAtIndex(entry.file_idx); + line_entry.file = + m_comp_unit->GetSupportFiles().GetFileSpecAtIndex(entry.file_idx); line_entry.original_file_sp = m_comp_unit->GetSupportFiles().GetSupportFileAtIndex(entry.file_idx); line_entry.line = entry.line; diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index f368896fbad4..3c70b8d8743c 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -472,8 +472,8 @@ bool SymbolContext::GetParentOfInlinedScope(const Address &curr_frame_pc, curr_inlined_block->GetInlinedFunctionInfo(); next_frame_pc = range.GetBaseAddress(); next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc; - next_frame_sc.line_entry.file_sp = std::make_shared<SupportFile>( - curr_inlined_block_inlined_info->GetCallSite().GetFile()); + next_frame_sc.line_entry.file = + curr_inlined_block_inlined_info->GetCallSite().GetFile(); next_frame_sc.line_entry.original_file_sp = std::make_shared<SupportFile>( curr_inlined_block_inlined_info->GetCallSite().GetFile()); diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index 3af62f52d575..c29a71d92572 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -1922,7 +1922,7 @@ bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source, size_t num_lines = target->GetSourceManager().DisplaySourceLinesWithLineNumbers( - m_sc.line_entry.GetFile(), start_line, m_sc.line_entry.column, + m_sc.line_entry.file, start_line, m_sc.line_entry.column, source_lines_before, source_lines_after, "->", &strm); if (num_lines != 0) have_source = true; diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp index 314b5e39c716..2273e52e2e04 100644 --- a/lldb/source/Target/StackFrameList.cpp +++ b/lldb/source/Target/StackFrameList.cpp @@ -884,9 +884,9 @@ void StackFrameList::SetDefaultFileAndLineToSelectedFrame() { GetFrameAtIndex(GetSelectedFrameIndex(DoNoSelectMostRelevantFrame))); if (frame_sp) { SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextLineEntry); - if (sc.line_entry.GetFile()) + if (sc.line_entry.file) m_thread.CalculateTarget()->GetSourceManager().SetDefaultFileAndLine( - sc.line_entry.GetFile(), sc.line_entry.line); + sc.line_entry.file, sc.line_entry.line); } } } diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 412e44ede9c1..4dfad23b56e2 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -302,10 +302,10 @@ bool Thread::SetSelectedFrameByIndexNoisily(uint32_t frame_idx, SymbolContext frame_sc( frame_sp->GetSymbolContext(eSymbolContextLineEntry)); const Debugger &debugger = GetProcess()->GetTarget().GetDebugger(); - if (debugger.GetUseExternalEditor() && frame_sc.line_entry.GetFile() && + if (debugger.GetUseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0) { if (llvm::Error e = Host::OpenFileInExternalEditor( - debugger.GetExternalEditor(), frame_sc.line_entry.GetFile(), + debugger.GetExternalEditor(), frame_sc.line_entry.file, frame_sc.line_entry.line)) { LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(e), "OpenFileInExternalEditor failed: {0}"); @@ -1753,10 +1753,10 @@ size_t Thread::GetStatus(Stream &strm, uint32_t start_frame, if (frame_sp) { SymbolContext frame_sc( frame_sp->GetSymbolContext(eSymbolContextLineEntry)); - if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.GetFile()) { + if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) { if (llvm::Error e = Host::OpenFileInExternalEditor( target->GetDebugger().GetExternalEditor(), - frame_sc.line_entry.GetFile(), frame_sc.line_entry.line)) { + frame_sc.line_entry.file, frame_sc.line_entry.line)) { LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(e), "OpenFileInExternalEditor failed: {0}"); } diff --git a/lldb/source/Target/TraceDumper.cpp b/lldb/source/Target/TraceDumper.cpp index 4ef8efc1a676..e92419e70b32 100644 --- a/lldb/source/Target/TraceDumper.cpp +++ b/lldb/source/Target/TraceDumper.cpp @@ -57,7 +57,7 @@ static bool FileLineAndColumnMatches(const LineEntry &a, const LineEntry &b) { return false; if (a.column != b.column) return false; - return a.GetFile() == b.GetFile(); + return a.file == b.file; } /// Compare the symbol contexts of the provided \a SymbolInfo @@ -396,7 +396,7 @@ public: m_j.attribute( "source", ToOptionalString( - item.symbol_info->sc.line_entry.GetFile().GetPath().c_str())); + item.symbol_info->sc.line_entry.file.GetPath().c_str())); m_j.attribute("line", item.symbol_info->sc.line_entry.line); m_j.attribute("column", item.symbol_info->sc.line_entry.column); } -- GitLab From 6f31cf51dfdc2c317ba8149d57d2ffb583403833 Mon Sep 17 00:00:00 2001 From: Owen Pan <owenpiano@gmail.com> Date: Tue, 19 Mar 2024 18:02:09 -0700 Subject: [PATCH 170/307] Revert "[clang-format][NFC] Eliminate the IsCpp parameter in all functions (#84599)" This reverts c3a1eb6207d8 (and the related commit f3c5278efa3b) which makes cleanupAroundReplacements() no longer thread-safe. --- clang/lib/Format/ContinuationIndenter.cpp | 12 ++--- clang/lib/Format/Format.cpp | 8 +-- clang/lib/Format/FormatToken.cpp | 8 ++- clang/lib/Format/FormatToken.h | 9 ++-- clang/lib/Format/FormatTokenLexer.cpp | 5 +- clang/lib/Format/QualifierAlignmentFixer.cpp | 29 ++++++----- clang/lib/Format/QualifierAlignmentFixer.h | 5 +- clang/lib/Format/TokenAnnotator.cpp | 49 ++++++++++--------- clang/lib/Format/TokenAnnotator.h | 6 +-- clang/lib/Format/UnwrappedLineParser.cpp | 22 ++++----- clang/lib/Format/UnwrappedLineParser.h | 1 + clang/unittests/Format/TokenAnnotatorTest.cpp | 13 ----- 12 files changed, 76 insertions(+), 91 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index b3de317f1633..6ccc81909368 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -232,9 +232,7 @@ ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style, : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr), Whitespaces(Whitespaces), Encoding(Encoding), BinPackInconclusiveFunctions(BinPackInconclusiveFunctions), - CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) { - assert(IsCpp == Style.isCpp()); -} + CommentPragmasRegex(Style.CommentPragmas), RawStringFormats(Style) {} LineState ContinuationIndenter::getInitialState(unsigned FirstIndent, unsigned FirstStartColumn, @@ -399,7 +397,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) || (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) && - State.Line->First->isNot(TT_AttributeSquare) && IsCpp && + State.Line->First->isNot(TT_AttributeSquare) && Style.isCpp() && // FIXME: This is a temporary workaround for the case where clang-format // sets BreakBeforeParameter to avoid bin packing and this creates a // completely unnecessary line break after a template type that isn't @@ -670,8 +668,8 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, auto &CurrentState = State.Stack.back(); bool DisallowLineBreaksOnThisLine = - Style.LambdaBodyIndentation == FormatStyle::LBI_Signature && IsCpp && - [&Current] { + Style.LambdaBodyIndentation == FormatStyle::LBI_Signature && + Style.isCpp() && [&Current] { // Deal with lambda arguments in C++. The aim here is to ensure that we // don't over-indent lambda function bodies when lambdas are passed as // arguments to function calls. We do this by ensuring that either all @@ -1085,7 +1083,7 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, // Any break on this level means that the parent level has been broken // and we need to avoid bin packing there. bool NestedBlockSpecialCase = - (!IsCpp && Current.is(tok::r_brace) && State.Stack.size() > 1 && + (!Style.isCpp() && Current.is(tok::r_brace) && State.Stack.size() > 1 && State.Stack[State.Stack.size() - 2].NestedBlockInlined) || (Style.Language == FormatStyle::LK_ObjC && Current.is(tok::r_brace) && State.Stack.size() > 1 && !Style.ObjCBreakBeforeNestedBlockParam); diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 89813badc8ec..63ec3a88978d 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3827,15 +3827,13 @@ tooling::Replacements sortUsingDeclarations(const FormatStyle &Style, } LangOptions getFormattingLangOpts(const FormatStyle &Style) { - IsCpp = Style.isCpp(); + LangOptions LangOpts; FormatStyle::LanguageStandard LexingStd = Style.Standard; if (LexingStd == FormatStyle::LS_Auto) LexingStd = FormatStyle::LS_Latest; if (LexingStd == FormatStyle::LS_Latest) LexingStd = FormatStyle::LS_Cpp20; - - LangOptions LangOpts; LangOpts.CPlusPlus = 1; LangOpts.CPlusPlus11 = LexingStd >= FormatStyle::LS_Cpp11; LangOpts.CPlusPlus14 = LexingStd >= FormatStyle::LS_Cpp14; @@ -3846,8 +3844,10 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style) { // the sequence "<::" will be unconditionally treated as "[:". // Cf. Lexer::LexTokenInternal. LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11; + LangOpts.LineComment = 1; - LangOpts.CXXOperatorNames = IsCpp; + bool AlternativeOperators = Style.isCpp(); + LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0; LangOpts.Bool = 1; LangOpts.ObjC = 1; LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally. diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp index cd94a9df6cff..99405fb9d08d 100644 --- a/clang/lib/Format/FormatToken.cpp +++ b/clang/lib/Format/FormatToken.cpp @@ -18,8 +18,6 @@ namespace clang { namespace format { -bool IsCpp = false; - const char *getTokenTypeName(TokenType Type) { static const char *const TokNames[] = { #define TYPE(X) #X, @@ -77,15 +75,15 @@ static SmallVector<StringRef> CppNonKeywordTypes = { "uint32_t", "uint64_t", "uint8_t", "uintptr_t", }; -bool FormatToken::isTypeName() const { +bool FormatToken::isTypeName(bool IsCpp) const { return is(TT_TypeName) || isSimpleTypeSpecifier() || (IsCpp && is(tok::identifier) && std::binary_search(CppNonKeywordTypes.begin(), CppNonKeywordTypes.end(), TokenText)); } -bool FormatToken::isTypeOrIdentifier() const { - return isTypeName() || isOneOf(tok::kw_auto, tok::identifier); +bool FormatToken::isTypeOrIdentifier(bool IsCpp) const { + return isTypeName(IsCpp) || isOneOf(tok::kw_auto, tok::identifier); } bool FormatToken::isBlockIndentedInitRBrace(const FormatStyle &Style) const { diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index a141db3d41d7..06f567059c35 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -24,9 +24,6 @@ namespace clang { namespace format { -/// Whether the language is C/C++/Objective-C/Objective-C++. -extern bool IsCpp; - #define LIST_TOKEN_TYPES \ TYPE(ArrayInitializerLSquare) \ TYPE(ArraySubscriptLSquare) \ @@ -681,9 +678,9 @@ public: /// Determine whether the token is a simple-type-specifier. [[nodiscard]] bool isSimpleTypeSpecifier() const; - [[nodiscard]] bool isTypeName() const; + [[nodiscard]] bool isTypeName(bool IsCpp) const; - [[nodiscard]] bool isTypeOrIdentifier() const; + [[nodiscard]] bool isTypeOrIdentifier(bool IsCpp) const; bool isObjCAccessSpecifier() const { return is(tok::at) && Next && @@ -828,7 +825,7 @@ public: /// Returns whether the token is the left square bracket of a C++ /// structured binding declaration. - bool isCppStructuredBinding() const { + bool isCppStructuredBinding(bool IsCpp) const { if (!IsCpp || isNot(tok::l_square)) return false; const FormatToken *T = this; diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index a1c8df80e6a9..12db4def10fb 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -30,7 +30,6 @@ FormatTokenLexer::FormatTokenLexer( Encoding(Encoding), Allocator(Allocator), FirstInLineIndex(0), FormattingDisabled(false), MacroBlockBeginRegex(Style.MacroBlockBegin), MacroBlockEndRegex(Style.MacroBlockEnd) { - assert(IsCpp == Style.isCpp()); Lex.reset(new Lexer(ID, SourceMgr.getBufferOrFake(ID), SourceMgr, LangOpts)); Lex->SetKeepWhitespaceMode(true); @@ -111,7 +110,7 @@ void FormatTokenLexer::tryMergePreviousTokens() { return; if (tryMergeForEach()) return; - if (IsCpp && tryTransformTryUsageForC()) + if (Style.isCpp() && tryTransformTryUsageForC()) return; if (Style.isJavaScript() || Style.isCSharp()) { @@ -1338,7 +1337,7 @@ FormatToken *FormatTokenLexer::getNextToken() { Column = FormatTok->LastLineColumnWidth; } - if (IsCpp) { + if (Style.isCpp()) { auto *Identifier = FormatTok->Tok.getIdentifierInfo(); auto it = Macros.find(Identifier); if (!(Tokens.size() > 0 && Tokens.back()->Tok.getIdentifierInfo() && diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp index 32d5153fc815..4bc2698a1146 100644 --- a/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -262,11 +262,13 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight( if (isPossibleMacro(TypeToken)) return Tok; + const bool IsCpp = Style.isCpp(); + // The case `const long long int volatile` -> `long long int const volatile` // The case `long const long int volatile` -> `long long int const volatile` // The case `long long volatile int const` -> `long long int const volatile` // The case `const long long volatile int` -> `long long int const volatile` - if (TypeToken->isTypeName()) { + if (TypeToken->isTypeName(IsCpp)) { // The case `const decltype(foo)` -> `const decltype(foo)` // The case `const typeof(foo)` -> `const typeof(foo)` // The case `const _Atomic(foo)` -> `const _Atomic(foo)` @@ -274,8 +276,10 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight( return Tok; const FormatToken *LastSimpleTypeSpecifier = TypeToken; - while (isQualifierOrType(LastSimpleTypeSpecifier->getNextNonComment())) + while (isQualifierOrType(LastSimpleTypeSpecifier->getNextNonComment(), + IsCpp)) { LastSimpleTypeSpecifier = LastSimpleTypeSpecifier->getNextNonComment(); + } rotateTokens(SourceMgr, Fixes, Tok, LastSimpleTypeSpecifier, /*Left=*/false); @@ -285,7 +289,7 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight( // The case `unsigned short const` -> `unsigned short const` // The case: // `unsigned short volatile const` -> `unsigned short const volatile` - if (PreviousCheck && PreviousCheck->isTypeName()) { + if (PreviousCheck && PreviousCheck->isTypeName(IsCpp)) { if (LastQual != Tok) rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false); return Tok; @@ -402,11 +406,11 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft( // The case `volatile long long const int` -> `const volatile long long int` // The case `const long long volatile int` -> `const volatile long long int` // The case `long volatile long int const` -> `const volatile long long int` - if (TypeToken->isTypeName()) { + if (const bool IsCpp = Style.isCpp(); TypeToken->isTypeName(IsCpp)) { const FormatToken *LastSimpleTypeSpecifier = TypeToken; while (isConfiguredQualifierOrType( LastSimpleTypeSpecifier->getPreviousNonComment(), - ConfiguredQualifierTokens)) { + ConfiguredQualifierTokens, IsCpp)) { LastSimpleTypeSpecifier = LastSimpleTypeSpecifier->getPreviousNonComment(); } @@ -521,9 +525,7 @@ LeftRightQualifierAlignmentFixer::LeftRightQualifierAlignmentFixer( const std::string &Qualifier, const std::vector<tok::TokenKind> &QualifierTokens, bool RightAlign) : TokenAnalyzer(Env, Style), Qualifier(Qualifier), RightAlign(RightAlign), - ConfiguredQualifierTokens(QualifierTokens) { - IsCpp = Style.isCpp(); -} + ConfiguredQualifierTokens(QualifierTokens) {} std::pair<tooling::Replacements, unsigned> LeftRightQualifierAlignmentFixer::analyze( @@ -606,15 +608,16 @@ void prepareLeftRightOrderingForQualifierAlignmentFixer( } } -bool LeftRightQualifierAlignmentFixer::isQualifierOrType( - const FormatToken *Tok) { +bool LeftRightQualifierAlignmentFixer::isQualifierOrType(const FormatToken *Tok, + bool IsCpp) { return Tok && - (Tok->isTypeName() || Tok->is(tok::kw_auto) || isQualifier(Tok)); + (Tok->isTypeName(IsCpp) || Tok->is(tok::kw_auto) || isQualifier(Tok)); } bool LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType( - const FormatToken *Tok, const std::vector<tok::TokenKind> &Qualifiers) { - return Tok && (Tok->isTypeName() || Tok->is(tok::kw_auto) || + const FormatToken *Tok, const std::vector<tok::TokenKind> &Qualifiers, + bool IsCpp) { + return Tok && (Tok->isTypeName(IsCpp) || Tok->is(tok::kw_auto) || isConfiguredQualifier(Tok, Qualifiers)); } diff --git a/clang/lib/Format/QualifierAlignmentFixer.h b/clang/lib/Format/QualifierAlignmentFixer.h index e922d8005595..e1cc27e62b13 100644 --- a/clang/lib/Format/QualifierAlignmentFixer.h +++ b/clang/lib/Format/QualifierAlignmentFixer.h @@ -71,10 +71,11 @@ public: tok::TokenKind QualifierType); // Is the Token a simple or qualifier type - static bool isQualifierOrType(const FormatToken *Tok); + static bool isQualifierOrType(const FormatToken *Tok, bool IsCpp = true); static bool isConfiguredQualifierOrType(const FormatToken *Tok, - const std::vector<tok::TokenKind> &Qualifiers); + const std::vector<tok::TokenKind> &Qualifiers, + bool IsCpp = true); // Is the Token likely a Macro static bool isPossibleMacro(const FormatToken *Tok); diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 911f7cca470a..8dc8e13688ed 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -80,7 +80,7 @@ static bool isKeywordWithCondition(const FormatToken &Tok) { } /// Returns \c true if the token starts a C++ attribute, \c false otherwise. -static bool isCppAttribute(const FormatToken &Tok) { +static bool isCppAttribute(bool IsCpp, const FormatToken &Tok) { if (!IsCpp || !Tok.startsSequence(tok::l_square, tok::l_square)) return false; // The first square bracket is part of an ObjC array literal @@ -122,8 +122,7 @@ public: const AdditionalKeywords &Keywords, SmallVector<ScopeType> &Scopes) : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false), - Keywords(Keywords), Scopes(Scopes) { - assert(IsCpp == Style.isCpp()); + IsCpp(Style.isCpp()), Keywords(Keywords), Scopes(Scopes) { Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false)); resetTokenMetadata(); } @@ -559,7 +558,7 @@ private: (CurrentToken->is(tok::l_paren) && CurrentToken->Next && CurrentToken->Next->isOneOf(tok::star, tok::amp, tok::caret)); if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) || - CurrentToken->Previous->isTypeName()) && + CurrentToken->Previous->isTypeName(IsCpp)) && !(CurrentToken->is(tok::l_brace) || (CurrentToken->is(tok::l_paren) && !ProbablyFunctionTypeLParen))) { Contexts.back().IsExpression = false; @@ -679,7 +678,7 @@ private: const bool IsInnerSquare = Contexts.back().InCpp11AttributeSpecifier; const bool IsCpp11AttributeSpecifier = - isCppAttribute(*Left) || IsInnerSquare; + isCppAttribute(IsCpp, *Left) || IsInnerSquare; // Treat C# Attributes [STAThread] much like C++ attributes [[...]]. bool IsCSharpAttributeSpecifier = @@ -687,7 +686,7 @@ private: Contexts.back().InCSharpAttributeSpecifier; bool InsideInlineASM = Line.startsWith(tok::kw_asm); - bool IsCppStructuredBinding = Left->isCppStructuredBinding(); + bool IsCppStructuredBinding = Left->isCppStructuredBinding(IsCpp); bool StartsObjCMethodExpr = !IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates && IsCpp && !IsCpp11AttributeSpecifier && !IsCSharpAttributeSpecifier && @@ -2613,7 +2612,7 @@ private: return true; // MyClass a; - if (PreviousNotConst->isTypeName()) + if (PreviousNotConst->isTypeName(IsCpp)) return true; // type[] a in Java @@ -2728,7 +2727,7 @@ private: if (Tok.Next->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const, tok::kw_requires, tok::kw_throw, tok::arrow, Keywords.kw_override, Keywords.kw_final) || - isCppAttribute(*Tok.Next)) { + isCppAttribute(IsCpp, *Tok.Next)) { return false; } @@ -2744,9 +2743,10 @@ private: } // Heuristically try to determine whether the parentheses contain a type. - auto IsQualifiedPointerOrReference = [](FormatToken *T) { + auto IsQualifiedPointerOrReference = [this](FormatToken *T) { // This is used to handle cases such as x = (foo *const)&y; - assert(!T->isTypeName() && "Should have already been checked"); + assert(!T->isTypeName(IsCpp) && "Should have already been checked"); + (void)IsCpp; // Avoid -Wunused-lambda-capture when assertion is disabled. // Strip trailing qualifiers such as const or volatile when checking // whether the parens could be a cast to a pointer/reference type. while (T) { @@ -2778,7 +2778,7 @@ private: bool ParensAreType = !Tok.Previous || Tok.Previous->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) || - Tok.Previous->isTypeName() || + Tok.Previous->isTypeName(IsCpp) || IsQualifiedPointerOrReference(Tok.Previous); bool ParensCouldEndDecl = Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater); @@ -3049,6 +3049,7 @@ private: AnnotatedLine &Line; FormatToken *CurrentToken; bool AutoFound; + bool IsCpp; const AdditionalKeywords &Keywords; SmallVector<ScopeType> &Scopes; @@ -3623,7 +3624,7 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) { // This function heuristically determines whether 'Current' starts the name of a // function declaration. -static bool isFunctionDeclarationName(const FormatToken &Current, +static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current, const AnnotatedLine &Line, FormatToken *&ClosingParen) { assert(Current.Previous); @@ -3641,7 +3642,8 @@ static bool isFunctionDeclarationName(const FormatToken &Current, return false; } - auto skipOperatorName = [](const FormatToken *Next) -> const FormatToken * { + auto skipOperatorName = + [IsCpp](const FormatToken *Next) -> const FormatToken * { for (; Next; Next = Next->Next) { if (Next->is(TT_OverloadedOperatorLParen)) return Next; @@ -3660,8 +3662,8 @@ static bool isFunctionDeclarationName(const FormatToken &Current, Next = Next->Next; continue; } - if ((Next->isTypeName() || Next->is(tok::identifier)) && Next->Next && - Next->Next->isPointerOrReference()) { + if ((Next->isTypeName(IsCpp) || Next->is(tok::identifier)) && + Next->Next && Next->Next->isPointerOrReference()) { // For operator void*(), operator char*(), operator Foo*(). Next = Next->Next; continue; @@ -3708,7 +3710,7 @@ static bool isFunctionDeclarationName(const FormatToken &Current, } if (Next->isNot(tok::identifier)) return false; - } else if (isCppAttribute(*Next)) { + } else if (isCppAttribute(IsCpp, *Next)) { Next = Next->MatchingParen; if (!Next) return false; @@ -3757,7 +3759,7 @@ static bool isFunctionDeclarationName(const FormatToken &Current, Tok = Tok->MatchingParen; continue; } - if (Tok->is(tok::kw_const) || Tok->isTypeName() || + if (Tok->is(tok::kw_const) || Tok->isTypeName(IsCpp) || Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) { return true; } @@ -3819,7 +3821,8 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const { if (Tok->Previous->EndsCppAttributeGroup) AfterLastAttribute = Tok; if (const bool IsCtorOrDtor = Tok->is(TT_CtorDtorDeclName); - IsCtorOrDtor || isFunctionDeclarationName(*Tok, Line, ClosingParen)) { + IsCtorOrDtor || + isFunctionDeclarationName(IsCpp, *Tok, Line, ClosingParen)) { if (!IsCtorOrDtor) Tok->setFinalizedType(TT_FunctionDeclarationName); LineIsFunctionDeclaration = true; @@ -4423,7 +4426,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (Left.Tok.isLiteral()) return true; // for (auto a = 0, b = 0; const auto & c : {1, 2, 3}) - if (Left.isTypeOrIdentifier() && Right.Next && Right.Next->Next && + if (Left.isTypeOrIdentifier(IsCpp) && Right.Next && Right.Next->Next && Right.Next->Next->is(TT_RangeBasedForLoopColon)) { return getTokenPointerOrReferenceAlignment(Right) != FormatStyle::PAS_Left; @@ -4466,8 +4469,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (Right.is(tok::l_brace) && Right.is(BK_Block)) return true; // for (auto a = 0, b = 0; const auto& c : {1, 2, 3}) - if (Left.Previous && Left.Previous->isTypeOrIdentifier() && Right.Next && - Right.Next->is(TT_RangeBasedForLoopColon)) { + if (Left.Previous && Left.Previous->isTypeOrIdentifier(IsCpp) && + Right.Next && Right.Next->is(TT_RangeBasedForLoopColon)) { return getTokenPointerOrReferenceAlignment(Left) != FormatStyle::PAS_Right; } @@ -4505,7 +4508,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (Right.isPointerOrReference()) { const FormatToken *Previous = &Left; while (Previous && Previous->isNot(tok::kw_operator)) { - if (Previous->is(tok::identifier) || Previous->isTypeName()) { + if (Previous->is(tok::identifier) || Previous->isTypeName(IsCpp)) { Previous = Previous->getPreviousNonComment(); continue; } @@ -4694,7 +4697,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, if (!Style.isVerilog() && (Left.isOneOf(tok::identifier, tok::greater, tok::r_square, tok::r_paren) || - Left.isTypeName()) && + Left.isTypeName(IsCpp)) && Right.is(tok::l_brace) && Right.getNextNonComment() && Right.isNot(BK_Block)) { return false; diff --git a/clang/lib/Format/TokenAnnotator.h b/clang/lib/Format/TokenAnnotator.h index aa44b31e0fce..25a24dccb1b8 100644 --- a/clang/lib/Format/TokenAnnotator.h +++ b/clang/lib/Format/TokenAnnotator.h @@ -211,9 +211,7 @@ private: class TokenAnnotator { public: TokenAnnotator(const FormatStyle &Style, const AdditionalKeywords &Keywords) - : Style(Style), Keywords(Keywords) { - assert(IsCpp == Style.isCpp()); - } + : Style(Style), IsCpp(Style.isCpp()), Keywords(Keywords) {} /// Adapts the indent levels of comment lines to the indent of the /// subsequent line. @@ -261,6 +259,8 @@ private: const FormatStyle &Style; + bool IsCpp; + const AdditionalKeywords &Keywords; SmallVector<ScopeType> Scopes; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 6ac4c7dc1a18..e89dfbdb2e0c 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -148,16 +148,14 @@ UnwrappedLineParser::UnwrappedLineParser( llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator, IdentifierTable &IdentTable) : Line(new UnwrappedLine), MustBreakBeforeNextToken(false), - CurrentLines(&Lines), Style(Style), Keywords(Keywords), - CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr), - Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1), + CurrentLines(&Lines), Style(Style), IsCpp(Style.isCpp()), + Keywords(Keywords), CommentPragmasRegex(Style.CommentPragmas), + Tokens(nullptr), Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1), IncludeGuard(Style.IndentPPDirectives == FormatStyle::PPDIS_None ? IG_Rejected : IG_Inited), IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn), - Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) { - assert(IsCpp == Style.isCpp()); -} + Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {} void UnwrappedLineParser::reset() { PPBranchLevel = -1; @@ -1855,7 +1853,7 @@ void UnwrappedLineParser::parseStructuralElement( case tok::caret: nextToken(); // Block return type. - if (FormatTok->Tok.isAnyIdentifier() || FormatTok->isTypeName()) { + if (FormatTok->Tok.isAnyIdentifier() || FormatTok->isTypeName(IsCpp)) { nextToken(); // Return types: pointers are ok too. while (FormatTok->is(tok::star)) @@ -2211,7 +2209,7 @@ bool UnwrappedLineParser::tryToParseLambda() { bool InTemplateParameterList = false; while (FormatTok->isNot(tok::l_brace)) { - if (FormatTok->isTypeName()) { + if (FormatTok->isTypeName(IsCpp)) { nextToken(); continue; } @@ -2328,7 +2326,7 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() { !Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return)) || Previous->closesScope())) || - LeftSquare->isCppStructuredBinding()) { + LeftSquare->isCppStructuredBinding(IsCpp)) { return false; } if (FormatTok->is(tok::l_square) || tok::isLiteral(FormatTok->Tok.getKind())) @@ -3404,7 +3402,7 @@ bool clang::format::UnwrappedLineParser::parseRequires() { break; } default: - if (PreviousNonComment->isTypeOrIdentifier()) { + if (PreviousNonComment->isTypeOrIdentifier(IsCpp)) { // This is a requires clause. parseRequiresClause(RequiresToken); return true; @@ -3467,7 +3465,7 @@ bool clang::format::UnwrappedLineParser::parseRequires() { --OpenAngles; break; default: - if (NextToken->isTypeName()) { + if (NextToken->isTypeName(IsCpp)) { FormatTok = Tokens->setPosition(StoredPosition); parseRequiresExpression(RequiresToken); return false; @@ -3956,7 +3954,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { if (FormatTok->is(tok::l_square)) { FormatToken *Previous = FormatTok->Previous; if (!Previous || (Previous->isNot(tok::r_paren) && - !Previous->isTypeOrIdentifier())) { + !Previous->isTypeOrIdentifier(IsCpp))) { // Don't try parsing a lambda if we had a closing parenthesis before, // it was probably a pointer to an array: int (*)[]. if (!tryToParseLambda()) diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index da3188ed240c..e2cf28c0c065 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -315,6 +315,7 @@ private: llvm::BitVector DeclarationScopeStack; const FormatStyle &Style; + bool IsCpp; const AdditionalKeywords &Keywords; llvm::Regex CommentPragmasRegex; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index bfb71d1f7e97..1aa855b34198 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1776,22 +1776,9 @@ TEST_F(TokenAnnotatorTest, UnderstandsFunctionDeclarationNames) { auto Style = getLLVMStyle(); Style.TypeNames.push_back("MyType"); Tokens = annotate("int iso_time(MyType);", Style); - ASSERT_TRUE(IsCpp); ASSERT_EQ(Tokens.size(), 7u) << Tokens; EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); EXPECT_TOKEN(Tokens[3], tok::identifier, TT_TypeName); - - Style.Language = FormatStyle::LK_CSharp; - Tokens = annotate("int iso_time(time_t);", Style); - ASSERT_FALSE(IsCpp); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; - EXPECT_TOKEN(Tokens[1], tok::identifier, TT_StartOfName); - - Style.Language = FormatStyle::LK_ObjC; - Tokens = annotate("int iso_time(time_t);", Style); - ASSERT_TRUE(IsCpp); - ASSERT_EQ(Tokens.size(), 7u) << Tokens; - EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName); } TEST_F(TokenAnnotatorTest, UnderstandsCtorAndDtorDeclNames) { -- GitLab From 456c239d775e10a68c65cd9d461bb47e651ccbe5 Mon Sep 17 00:00:00 2001 From: Fangrui Song <i@maskray.me> Date: Tue, 19 Mar 2024 18:21:20 -0700 Subject: [PATCH 171/307] [ELF] Set ctx.internalFile for PPC64 _savegpr[01]_{14..31} and _restgpr[01]_{14..31}. NFC Ensure that every InputFile has a non-null file so that we enforce this in the future. --- lld/ELF/Arch/PPC64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index 657332deebfd..3188772f7c49 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -286,7 +286,7 @@ static void writeSequence(MutableArrayRef<uint32_t> buf, const char *prefix, // The full section content has the extent of [begin, end). We drop unused // instructions and write [first,end). auto *sec = make<InputSection>( - nullptr, SHF_ALLOC, SHT_PROGBITS, 4, + ctx.internalFile, SHF_ALLOC, SHT_PROGBITS, 4, ArrayRef(reinterpret_cast<uint8_t *>(buf.data() + first), 4 * (buf.size() - first)), ".text"); -- GitLab From 09db84cc5910a3546ab5b9410c295d93ed3e95cf Mon Sep 17 00:00:00 2001 From: Fangrui Song <i@maskray.me> Date: Tue, 19 Mar 2024 18:25:22 -0700 Subject: [PATCH 172/307] [ELF] Remove unneeded null check in getRelocatedSection. NFC --- lld/ELF/InputSection.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 19a6595d10ce..082e840adde4 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -316,7 +316,9 @@ InputSection::InputSection(InputFile *f, uint64_t flags, uint32_t type, StringRef name, Kind k) : InputSectionBase(f, flags, type, /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, addralign, data, - name, k) {} + name, k) { + assert(f || this == &InputSection::discarded); +} template <class ELFT> InputSection::InputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header, @@ -346,7 +348,7 @@ template <class ELFT> void InputSection::copyShtGroup(uint8_t *buf) { } InputSectionBase *InputSection::getRelocatedSection() const { - if (!file || file->isInternal() || (type != SHT_RELA && type != SHT_REL)) + if (file->isInternal() || (type != SHT_RELA && type != SHT_REL)) return nullptr; ArrayRef<InputSectionBase *> sections = file->getSections(); return sections[info]; -- GitLab From de159aeca95edc38ddd4d729ea91b4b8160d9b83 Mon Sep 17 00:00:00 2001 From: Alex MacLean <amaclean@nvidia.com> Date: Tue, 19 Mar 2024 18:32:26 -0700 Subject: [PATCH 173/307] [NVPTX][DebugInfo] avoid emitting extra .loc directives (#84584) This change removes an extra, unneeded debug directive emitted in the PTX at the beginning on non-empty functions: ```nvptx .visible .func (.param .b32 func_retval0) foo( .param .b32 foo_param_0, .param .b32 foo_param_1 ) { .reg .b32 %r<4>; .loc 1 26 0 <---- unneeded (removed by the PR) $L__func_begin0: .loc 1 26 0 ``` --- llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp | 7 ++++-- llvm/test/DebugInfo/NVPTX/no-extra-loc.ll | 26 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 llvm/test/DebugInfo/NVPTX/no-extra-loc.ll diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp index 2219d9f6619a..2783b1e0ec73 100644 --- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -489,8 +489,11 @@ void NVPTXAsmPrinter::emitFunctionEntryLabel() { OutStreamer->emitRawText(StringRef("{\n")); setAndEmitFunctionVirtualRegisters(*MF); // Emit initial .loc debug directive for correct relocation symbol data. - if (MMI && MMI->hasDebugInfo()) - emitInitialRawDwarfLocDirective(*MF); + if (const DISubprogram *SP = MF->getFunction().getSubprogram()) { + assert(SP->getUnit()); + if (!SP->getUnit()->isDebugDirectivesOnly() && MMI && MMI->hasDebugInfo()) + emitInitialRawDwarfLocDirective(*MF); + } } bool NVPTXAsmPrinter::runOnMachineFunction(MachineFunction &F) { diff --git a/llvm/test/DebugInfo/NVPTX/no-extra-loc.ll b/llvm/test/DebugInfo/NVPTX/no-extra-loc.ll new file mode 100644 index 000000000000..6d3a69beffe8 --- /dev/null +++ b/llvm/test/DebugInfo/NVPTX/no-extra-loc.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s -mtriple=nvptx64-nvidia-cuda | FileCheck %s +; RUN: %if ptxas %{ llc < %s -mtriple=nvptx64-nvidia-cuda | %ptxas-verify %} + + +define i32 @foo(i32 %a, i32 %b) !dbg !3 { + +; CHECK: .loc [[FILE:[0-9]+]] 26 0 // extra-lineinfo.cu:26:0 +; CHECK-NOT: .loc [[FILE]] 26 0 // extra-lineinfo.cu:26:0 +; CHECK: .file [[FILE]] "/test/directory/extra-lineinfo.cu" + + %add = add i32 %b, %a, !dbg !6 + ret i32 %add, !dbg !6 +} + +!llvm.dbg.cu = !{!0} +!nvvm.annotations = !{} +!llvm.module.flags = !{!2} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: DebugDirectivesOnly) +!1 = !DIFile(filename: "extra-lineinfo.cu", directory: "/test/directory/") +!2 = !{i32 1, !"Debug Info Version", i32 3} +!3 = distinct !DISubprogram(name: "kernel", linkageName: "foo", scope: !1, file: !1, line: 123, type: !4, scopeLine: 26, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!4 = !DISubroutineType(types: !5) +!5 = !{} +!6 = !DILocation(line: 40, column: 22, scope: !31) +!31 = distinct !DILexicalBlock(scope: !3, file: !1, line: 3, column: 17) -- GitLab From 936519f25cb4fabc19f1241e838e938926801156 Mon Sep 17 00:00:00 2001 From: Cyndy Ishida <cyndy_ishida@apple.com> Date: Tue, 19 Mar 2024 18:36:46 -0700 Subject: [PATCH 174/307] [InstallAPI] Verify that declarations in headers map to exports found in dylib (#85348) * This completes support for verifying every declaration found in a header is discovered in the dylib. Diagnostics are reported for each class for differences that are representable in TBD files. * This patch also now captures unavailable attributes that depend on target triples. This is needed for proper tbd file generation. --- clang/include/clang/AST/Availability.h | 16 +- clang/include/clang/Basic/DiagnosticGroups.td | 4 + .../clang/Basic/DiagnosticInstallAPIKinds.td | 23 + .../include/clang/InstallAPI/DylibVerifier.h | 61 +- clang/include/clang/InstallAPI/Frontend.h | 3 + clang/include/clang/InstallAPI/MachO.h | 1 + clang/lib/AST/Availability.cpp | 6 +- clang/lib/InstallAPI/DylibVerifier.cpp | 326 ++++++++- clang/lib/InstallAPI/Visitor.cpp | 2 +- clang/test/InstallAPI/availability.test | 631 ++++++++++++++++++ clang/test/InstallAPI/diagnostics-cpp.test | 462 +++++++++++++ clang/test/InstallAPI/hiddens.test | 262 ++++++++ .../clang-installapi/ClangInstallAPI.cpp | 6 +- clang/tools/clang-installapi/Options.cpp | 4 +- clang/tools/diagtool/DiagnosticNames.cpp | 1 + 15 files changed, 1782 insertions(+), 26 deletions(-) create mode 100644 clang/test/InstallAPI/availability.test create mode 100644 clang/test/InstallAPI/diagnostics-cpp.test create mode 100644 clang/test/InstallAPI/hiddens.test diff --git a/clang/include/clang/AST/Availability.h b/clang/include/clang/AST/Availability.h index 5cfbaf0cdfbd..26ae622e5b44 100644 --- a/clang/include/clang/AST/Availability.h +++ b/clang/include/clang/AST/Availability.h @@ -67,6 +67,7 @@ struct AvailabilityInfo { VersionTuple Introduced; VersionTuple Deprecated; VersionTuple Obsoleted; + bool Unavailable = false; bool UnconditionallyDeprecated = false; bool UnconditionallyUnavailable = false; @@ -78,6 +79,12 @@ struct AvailabilityInfo { /// Check if the symbol has been obsoleted. bool isObsoleted() const { return !Obsoleted.empty(); } + /// Check if the symbol is unavailable unconditionally or + /// on the active platform and os version. + bool isUnavailable() const { + return Unavailable || isUnconditionallyUnavailable(); + } + /// Check if the symbol is unconditionally deprecated. /// /// i.e. \code __attribute__((deprecated)) \endcode @@ -91,9 +98,10 @@ struct AvailabilityInfo { } AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D, - VersionTuple O, bool UD, bool UU) + VersionTuple O, bool U, bool UD, bool UU) : Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O), - UnconditionallyDeprecated(UD), UnconditionallyUnavailable(UU) {} + Unavailable(U), UnconditionallyDeprecated(UD), + UnconditionallyUnavailable(UU) {} friend bool operator==(const AvailabilityInfo &Lhs, const AvailabilityInfo &Rhs); @@ -105,10 +113,10 @@ public: inline bool operator==(const AvailabilityInfo &Lhs, const AvailabilityInfo &Rhs) { return std::tie(Lhs.Introduced, Lhs.Deprecated, Lhs.Obsoleted, - Lhs.UnconditionallyDeprecated, + Lhs.Unavailable, Lhs.UnconditionallyDeprecated, Lhs.UnconditionallyUnavailable) == std::tie(Rhs.Introduced, Rhs.Deprecated, Rhs.Obsoleted, - Rhs.UnconditionallyDeprecated, + Rhs.Unavailable, Rhs.UnconditionallyDeprecated, Rhs.UnconditionallyUnavailable); } diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index f5ff89111d11..dee555f783cc 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1508,3 +1508,7 @@ def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">; // Warnings and fixes to support the "safe buffers" programming model. def UnsafeBufferUsageInContainer : DiagGroup<"unsafe-buffer-usage-in-container">; def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInContainer]>; + +// Warnings and notes InstallAPI verification. +def InstallAPIViolation : DiagGroup<"installapi-violation">; + diff --git a/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td b/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td index 31be4f09cf3a..f99a5fca64cb 100644 --- a/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td +++ b/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td @@ -17,4 +17,27 @@ def err_no_install_name : Error<"no install name specified: add -install_name <p def err_no_output_file: Error<"no output file specified">; } // end of command line category. +let CategoryName = "Verification" in { +def warn_target: Warning<"violations found for %0">, InGroup<InstallAPIViolation>; +def err_library_missing_symbol : Error<"declaration has external linkage, but dynamic library doesn't have symbol '%0'">; +def warn_library_missing_symbol : Warning<"declaration has external linkage, but dynamic library doesn't have symbol '%0'">, InGroup<InstallAPIViolation>; +def err_library_hidden_symbol : Error<"declaration has external linkage, but symbol has internal linkage in dynamic library '%0'">; +def warn_library_hidden_symbol : Warning<"declaration has external linkage, but symbol has internal linkage in dynamic library '%0'">, InGroup<InstallAPIViolation>; +def warn_header_hidden_symbol : Warning<"symbol exported in dynamic library, but marked hidden in declaration '%0'">, InGroup<InstallAPIViolation>; +def err_header_hidden_symbol : Error<"symbol exported in dynamic library, but marked hidden in declaration '%0'">; +def err_header_symbol_missing : Error<"no declaration found for exported symbol '%0' in dynamic library">; +def warn_header_availability_mismatch : Warning<"declaration '%0' is marked %select{available|unavailable}1," + " but symbol is %select{not |}2exported in dynamic library">, InGroup<InstallAPIViolation>; +def err_header_availability_mismatch : Error<"declaration '%0' is marked %select{available|unavailable}1," + " but symbol is %select{not |}2exported in dynamic library">; +def warn_dylib_symbol_flags_mismatch : Warning<"dynamic library symbol '%0' is " + "%select{weak defined|thread local}1, but its declaration is not">, InGroup<InstallAPIViolation>; +def warn_header_symbol_flags_mismatch : Warning<"declaration '%0' is " + "%select{weak defined|thread local}1, but symbol is not in dynamic library">, InGroup<InstallAPIViolation>; +def err_dylib_symbol_flags_mismatch : Error<"dynamic library symbol '%0' is " + "%select{weak defined|thread local}1, but its declaration is not">; +def err_header_symbol_flags_mismatch : Error<"declaration '%0' is " + "%select{weak defined|thread local}1, but symbol is not in dynamic library">; +} // end of Verification category. + } // end of InstallAPI component diff --git a/clang/include/clang/InstallAPI/DylibVerifier.h b/clang/include/clang/InstallAPI/DylibVerifier.h index 72c4743fdf65..8269715c7f23 100644 --- a/clang/include/clang/InstallAPI/DylibVerifier.h +++ b/clang/include/clang/InstallAPI/DylibVerifier.h @@ -38,19 +38,34 @@ public: // Current target being verified against the AST. llvm::MachO::Target Target; + // Target specific API from binary. + RecordsSlice *DylibSlice = nullptr; + // Query state of verification after AST has been traversed. - Result FrontendState; + Result FrontendState = Result::Ignore; // First error for AST traversal, which is tied to the target triple. - bool DiscoveredFirstError; + bool DiscoveredFirstError = false; + + // Determines what kind of banner to print a violation for. + bool PrintArch = false; + + // Engine for reporting violations. + DiagnosticsEngine *Diag = nullptr; + + // Handle diagnostics reporting for target level violations. + void emitDiag(llvm::function_ref<void()> Report); + + VerifierContext() = default; + VerifierContext(DiagnosticsEngine *Diag) : Diag(Diag) {} }; DylibVerifier() = default; DylibVerifier(llvm::MachO::Records &&Dylib, DiagnosticsEngine *Diag, VerificationMode Mode, bool Demangle) - : Dylib(std::move(Dylib)), Diag(Diag), Mode(Mode), Demangle(Demangle), - Exports(std::make_unique<SymbolSet>()) {} + : Dylib(std::move(Dylib)), Mode(Mode), Demangle(Demangle), + Exports(std::make_unique<SymbolSet>()), Ctx(VerifierContext{Diag}) {} Result verify(GlobalRecord *R, const FrontendAttrs *FA); Result verify(ObjCInterfaceRecord *R, const FrontendAttrs *FA); @@ -66,6 +81,13 @@ public: /// Get result of verification. Result getState() const { return Ctx.FrontendState; } + /// Set different source managers to the same diagnostics engine. + void setSourceManager(SourceManager &SourceMgr) const { + if (!Ctx.Diag) + return; + Ctx.Diag->setSourceManager(&SourceMgr); + } + private: /// Determine whether to compare declaration to symbol in binary. bool canVerify(); @@ -73,6 +95,29 @@ private: /// Shared implementation for verifying exported symbols. Result verifyImpl(Record *R, SymbolContext &SymCtx); + /// Check if declaration is marked as obsolete, they are + // expected to result in a symbol mismatch. + bool shouldIgnoreObsolete(const Record *R, SymbolContext &SymCtx, + const Record *DR); + + /// Compare the visibility declarations to the linkage of symbol found in + /// dylib. + Result compareVisibility(const Record *R, SymbolContext &SymCtx, + const Record *DR); + + /// An ObjCInterfaceRecord can represent up to three symbols. When verifying, + // account for this granularity. + bool compareObjCInterfaceSymbols(const Record *R, SymbolContext &SymCtx, + const ObjCInterfaceRecord *DR); + + /// Validate availability annotations against dylib. + Result compareAvailability(const Record *R, SymbolContext &SymCtx, + const Record *DR); + + /// Compare and validate matching symbol flags. + bool compareSymbolFlags(const Record *R, SymbolContext &SymCtx, + const Record *DR); + /// Update result state on each call to `verify`. void updateState(Result State); @@ -80,14 +125,14 @@ private: void addSymbol(const Record *R, SymbolContext &SymCtx, TargetList &&Targets = {}); + /// Find matching dylib slice for target triple that is being parsed. + void assignSlice(const Target &T); + // Symbols in dylib. llvm::MachO::Records Dylib; - // Engine for reporting violations. - [[maybe_unused]] DiagnosticsEngine *Diag = nullptr; - // Controls what class of violations to report. - [[maybe_unused]] VerificationMode Mode = VerificationMode::Invalid; + VerificationMode Mode = VerificationMode::Invalid; // Attempt to demangle when reporting violations. bool Demangle = false; diff --git a/clang/include/clang/InstallAPI/Frontend.h b/clang/include/clang/InstallAPI/Frontend.h index 660fc8cd69a5..5cccd891c580 100644 --- a/clang/include/clang/InstallAPI/Frontend.h +++ b/clang/include/clang/InstallAPI/Frontend.h @@ -17,6 +17,7 @@ #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" #include "clang/InstallAPI/Context.h" +#include "clang/InstallAPI/DylibVerifier.h" #include "clang/InstallAPI/Visitor.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/MemoryBuffer.h" @@ -34,6 +35,8 @@ public: std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override { + Ctx.Diags->getClient()->BeginSourceFile(CI.getLangOpts()); + Ctx.Verifier->setSourceManager(CI.getSourceManager()); return std::make_unique<InstallAPIVisitor>( CI.getASTContext(), Ctx, CI.getSourceManager(), CI.getPreprocessor()); } diff --git a/clang/include/clang/InstallAPI/MachO.h b/clang/include/clang/InstallAPI/MachO.h index 6dee6f224203..a77766511fa3 100644 --- a/clang/include/clang/InstallAPI/MachO.h +++ b/clang/include/clang/InstallAPI/MachO.h @@ -32,6 +32,7 @@ using ObjCInterfaceRecord = llvm::MachO::ObjCInterfaceRecord; using ObjCCategoryRecord = llvm::MachO::ObjCCategoryRecord; using ObjCIVarRecord = llvm::MachO::ObjCIVarRecord; using Records = llvm::MachO::Records; +using RecordsSlice = llvm::MachO::RecordsSlice; using BinaryAttrs = llvm::MachO::RecordsSlice::BinaryAttrs; using SymbolSet = llvm::MachO::SymbolSet; using SimpleSymbol = llvm::MachO::SimpleSymbol; diff --git a/clang/lib/AST/Availability.cpp b/clang/lib/AST/Availability.cpp index d0054e37e4dc..238359a2dedf 100644 --- a/clang/lib/AST/Availability.cpp +++ b/clang/lib/AST/Availability.cpp @@ -28,9 +28,9 @@ AvailabilityInfo AvailabilityInfo::createFromDecl(const Decl *Decl) { for (const auto *A : RD->specific_attrs<AvailabilityAttr>()) { if (A->getPlatform()->getName() != PlatformName) continue; - Availability = - AvailabilityInfo(A->getPlatform()->getName(), A->getIntroduced(), - A->getDeprecated(), A->getObsoleted(), false, false); + Availability = AvailabilityInfo( + A->getPlatform()->getName(), A->getIntroduced(), A->getDeprecated(), + A->getObsoleted(), A->getUnavailable(), false, false); break; } diff --git a/clang/lib/InstallAPI/DylibVerifier.cpp b/clang/lib/InstallAPI/DylibVerifier.cpp index b7dd85d63fa1..700763b3fee0 100644 --- a/clang/lib/InstallAPI/DylibVerifier.cpp +++ b/clang/lib/InstallAPI/DylibVerifier.cpp @@ -1,5 +1,6 @@ #include "clang/InstallAPI/DylibVerifier.h" #include "clang/InstallAPI/FrontendRecords.h" +#include "clang/InstallAPI/InstallAPIDiagnostic.h" #include "llvm/Demangle/Demangle.h" using namespace llvm::MachO; @@ -24,6 +25,9 @@ struct DylibVerifier::SymbolContext { // The ObjCInterface symbol type, if applicable. ObjCIFSymbolKind ObjCIFKind = ObjCIFSymbolKind::None; + + // Whether Decl is inlined. + bool Inlined = false; }; static std::string @@ -80,10 +84,11 @@ getAnnotatedName(const Record *R, EncodeKind Kind, StringRef Name, } static std::string demangle(StringRef Name) { - // Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'. - if (!(Name.starts_with("_Z") || Name.starts_with("___Z"))) + // InstallAPI currently only supports itanium manglings. + if (!(Name.starts_with("_Z") || Name.starts_with("__Z") || + Name.starts_with("___Z"))) return Name.str(); - char *Result = llvm::itaniumDemangle(Name.data()); + char *Result = llvm::itaniumDemangle(Name); if (!Result) return Name.str(); @@ -109,6 +114,30 @@ static DylibVerifier::Result updateResult(const DylibVerifier::Result Prev, return Curr; } +// __private_extern__ is a deprecated specifier that clang does not +// respect in all contexts, it should just be considered hidden for InstallAPI. +static bool shouldIgnorePrivateExternAttr(const Decl *D) { + if (const FunctionDecl *FD = cast<FunctionDecl>(D)) + return FD->getStorageClass() == StorageClass::SC_PrivateExtern; + if (const VarDecl *VD = cast<VarDecl>(D)) + return VD->getStorageClass() == StorageClass::SC_PrivateExtern; + + return false; +} + +Record *findRecordFromSlice(const RecordsSlice *Slice, StringRef Name, + EncodeKind Kind) { + switch (Kind) { + case EncodeKind::GlobalSymbol: + return Slice->findGlobal(Name); + case EncodeKind::ObjectiveCInstanceVariable: + return Slice->findObjCIVar(Name.contains('.'), Name); + case EncodeKind::ObjectiveCClass: + case EncodeKind::ObjectiveCClassEHType: + return Slice->findObjCInterface(Name); + } + llvm_unreachable("unexpected end when finding record"); +} void DylibVerifier::updateState(Result State) { Ctx.FrontendState = updateResult(Ctx.FrontendState, State); @@ -122,17 +151,272 @@ void DylibVerifier::addSymbol(const Record *R, SymbolContext &SymCtx, Exports->addGlobal(SymCtx.Kind, SymCtx.SymbolName, R->getFlags(), Targets); } +bool DylibVerifier::shouldIgnoreObsolete(const Record *R, SymbolContext &SymCtx, + const Record *DR) { + return SymCtx.FA->Avail.isObsoleted(); +} + +bool DylibVerifier::compareObjCInterfaceSymbols(const Record *R, + SymbolContext &SymCtx, + const ObjCInterfaceRecord *DR) { + const bool IsDeclVersionComplete = + ((SymCtx.ObjCIFKind & ObjCIFSymbolKind::Class) == + ObjCIFSymbolKind::Class) && + ((SymCtx.ObjCIFKind & ObjCIFSymbolKind::MetaClass) == + ObjCIFSymbolKind::MetaClass); + + const bool IsDylibVersionComplete = DR->isCompleteInterface(); + + // The common case, a complete ObjCInterface. + if (IsDeclVersionComplete && IsDylibVersionComplete) + return true; + + auto PrintDiagnostic = [&](auto SymLinkage, const Record *Record, + StringRef SymName, bool PrintAsWarning = false) { + if (SymLinkage == RecordLinkage::Unknown) + Ctx.emitDiag([&]() { + Ctx.Diag->Report(SymCtx.FA->D->getLocation(), + PrintAsWarning ? diag::warn_library_missing_symbol + : diag::err_library_missing_symbol) + << SymName; + }); + else + Ctx.emitDiag([&]() { + Ctx.Diag->Report(SymCtx.FA->D->getLocation(), + PrintAsWarning ? diag::warn_library_hidden_symbol + : diag::err_library_hidden_symbol) + << SymName; + }); + }; + + if (IsDeclVersionComplete) { + // The decl represents a complete ObjCInterface, but the symbols in the + // dylib do not. Determine which symbol is missing. To keep older projects + // building, treat this as a warning. + if (!DR->isExportedSymbol(ObjCIFSymbolKind::Class)) + PrintDiagnostic(DR->getLinkageForSymbol(ObjCIFSymbolKind::Class), R, + getAnnotatedName(R, SymCtx.Kind, SymCtx.PrettyPrintName, + /*ValidSourceLoc=*/true, + ObjCIFSymbolKind::Class), + /*PrintAsWarning=*/true); + + if (!DR->isExportedSymbol(ObjCIFSymbolKind::MetaClass)) + PrintDiagnostic(DR->getLinkageForSymbol(ObjCIFSymbolKind::MetaClass), R, + getAnnotatedName(R, SymCtx.Kind, SymCtx.PrettyPrintName, + /*ValidSourceLoc=*/true, + ObjCIFSymbolKind::MetaClass), + /*PrintAsWarning=*/true); + return true; + } + + if (DR->isExportedSymbol(SymCtx.ObjCIFKind)) { + if (!IsDylibVersionComplete) { + // Both the declaration and dylib have a non-complete interface. + SymCtx.Kind = EncodeKind::GlobalSymbol; + SymCtx.SymbolName = R->getName(); + } + return true; + } + + // At this point that means there was not a matching class symbol + // to represent the one discovered as a declaration. + PrintDiagnostic(DR->getLinkageForSymbol(SymCtx.ObjCIFKind), R, + SymCtx.PrettyPrintName); + return false; +} + +DylibVerifier::Result DylibVerifier::compareVisibility(const Record *R, + SymbolContext &SymCtx, + const Record *DR) { + + if (R->isExported()) { + if (!DR) { + Ctx.emitDiag([&]() { + Ctx.Diag->Report(SymCtx.FA->D->getLocation(), + diag::err_library_missing_symbol) + << SymCtx.PrettyPrintName; + }); + return Result::Invalid; + } + if (DR->isInternal()) { + Ctx.emitDiag([&]() { + Ctx.Diag->Report(SymCtx.FA->D->getLocation(), + diag::err_library_hidden_symbol) + << SymCtx.PrettyPrintName; + }); + return Result::Invalid; + } + } + + // Emit a diagnostic for hidden declarations with external symbols, except + // when theres an inlined attribute. + if ((R->isInternal() && !SymCtx.Inlined) && DR && DR->isExported()) { + + if (Mode == VerificationMode::ErrorsOnly) + return Result::Ignore; + + if (shouldIgnorePrivateExternAttr(SymCtx.FA->D)) + return Result::Ignore; + + unsigned ID; + Result Outcome; + if (Mode == VerificationMode::ErrorsAndWarnings) { + ID = diag::warn_header_hidden_symbol; + Outcome = Result::Ignore; + } else { + ID = diag::err_header_hidden_symbol; + Outcome = Result::Invalid; + } + Ctx.emitDiag([&]() { + Ctx.Diag->Report(SymCtx.FA->D->getLocation(), ID) + << SymCtx.PrettyPrintName; + }); + return Outcome; + } + + if (R->isInternal()) + return Result::Ignore; + + return Result::Valid; +} + +DylibVerifier::Result DylibVerifier::compareAvailability(const Record *R, + SymbolContext &SymCtx, + const Record *DR) { + if (!SymCtx.FA->Avail.isUnavailable()) + return Result::Valid; + + const bool IsDeclAvailable = SymCtx.FA->Avail.isUnavailable(); + + switch (Mode) { + case VerificationMode::ErrorsAndWarnings: + Ctx.emitDiag([&]() { + Ctx.Diag->Report(SymCtx.FA->D->getLocation(), + diag::warn_header_availability_mismatch) + << SymCtx.PrettyPrintName << IsDeclAvailable << IsDeclAvailable; + }); + return Result::Ignore; + case VerificationMode::Pedantic: + Ctx.emitDiag([&]() { + Ctx.Diag->Report(SymCtx.FA->D->getLocation(), + diag::err_header_availability_mismatch) + << SymCtx.PrettyPrintName << IsDeclAvailable << IsDeclAvailable; + }); + return Result::Invalid; + case VerificationMode::ErrorsOnly: + return Result::Ignore; + case VerificationMode::Invalid: + llvm_unreachable("Unexpected verification mode symbol verification"); + } + llvm_unreachable("Unexpected verification mode symbol verification"); +} + +bool DylibVerifier::compareSymbolFlags(const Record *R, SymbolContext &SymCtx, + const Record *DR) { + std::string DisplayName = + Demangle ? demangle(DR->getName()) : DR->getName().str(); + + if (DR->isThreadLocalValue() && !R->isThreadLocalValue()) { + Ctx.emitDiag([&]() { + Ctx.Diag->Report(SymCtx.FA->D->getLocation(), + diag::err_dylib_symbol_flags_mismatch) + << getAnnotatedName(DR, SymCtx.Kind, DisplayName) + << DR->isThreadLocalValue(); + }); + return false; + } + if (!DR->isThreadLocalValue() && R->isThreadLocalValue()) { + Ctx.emitDiag([&]() { + SymCtx.FA->D->getLocation(), + Ctx.Diag->Report(diag::err_header_symbol_flags_mismatch) + << SymCtx.PrettyPrintName << R->isThreadLocalValue(); + }); + return false; + } + + if (DR->isWeakDefined() && !R->isWeakDefined()) { + Ctx.emitDiag([&]() { + Ctx.Diag->Report(SymCtx.FA->D->getLocation(), + diag::err_dylib_symbol_flags_mismatch) + << getAnnotatedName(DR, SymCtx.Kind, DisplayName) + << R->isWeakDefined(); + }); + return false; + } + if (!DR->isWeakDefined() && R->isWeakDefined()) { + Ctx.emitDiag([&]() { + Ctx.Diag->Report(SymCtx.FA->D->getLocation(), + diag::err_header_symbol_flags_mismatch) + << SymCtx.PrettyPrintName << R->isWeakDefined(); + }); + return false; + } + + return true; +} + DylibVerifier::Result DylibVerifier::verifyImpl(Record *R, SymbolContext &SymCtx) { R->setVerify(); if (!canVerify()) { // Accumulate symbols when not in verifying against dylib. - if (R->isExported() && !SymCtx.FA->Avail.isUnconditionallyUnavailable() && + if (R->isExported() && !SymCtx.FA->Avail.isUnavailable() && !SymCtx.FA->Avail.isObsoleted()) { addSymbol(R, SymCtx); } return Ctx.FrontendState; } + + Record *DR = + findRecordFromSlice(Ctx.DylibSlice, SymCtx.SymbolName, SymCtx.Kind); + if (DR) + DR->setVerify(); + + if (shouldIgnoreObsolete(R, SymCtx, DR)) { + updateState(Result::Ignore); + return Ctx.FrontendState; + } + + // Unavailable declarations don't need matching symbols. + if (SymCtx.FA->Avail.isUnavailable() && (!DR || DR->isInternal())) { + updateState(Result::Valid); + return Ctx.FrontendState; + } + + Result VisibilityCheck = compareVisibility(R, SymCtx, DR); + if (VisibilityCheck != Result::Valid) { + updateState(VisibilityCheck); + return Ctx.FrontendState; + } + + // All missing symbol cases to diagnose have been handled now. + if (!DR) { + updateState(Result::Ignore); + return Ctx.FrontendState; + } + + // Check for mismatching ObjC interfaces. + if (SymCtx.ObjCIFKind != ObjCIFSymbolKind::None) { + if (!compareObjCInterfaceSymbols( + R, SymCtx, Ctx.DylibSlice->findObjCInterface(DR->getName()))) { + updateState(Result::Invalid); + return Ctx.FrontendState; + } + } + + Result AvailabilityCheck = compareAvailability(R, SymCtx, DR); + if (AvailabilityCheck != Result::Valid) { + updateState(AvailabilityCheck); + return Ctx.FrontendState; + } + + if (!compareSymbolFlags(R, SymCtx, DR)) { + updateState(Result::Invalid); + return Ctx.FrontendState; + } + + addSymbol(R, SymCtx); + updateState(Result::Valid); return Ctx.FrontendState; } @@ -140,10 +424,29 @@ bool DylibVerifier::canVerify() { return Ctx.FrontendState != Result::NoVerify; } +void DylibVerifier::assignSlice(const Target &T) { + assert(T == Ctx.Target && "Active targets should match."); + if (Dylib.empty()) + return; + + // Note: there are no reexport slices with binaries, as opposed to TBD files, + // so it can be assumed that the target match is the active top-level library. + auto It = find_if( + Dylib, [&T](const auto &Slice) { return T == Slice->getTarget(); }); + + assert(It != Dylib.end() && "Target slice should always exist."); + Ctx.DylibSlice = It->get(); +} + void DylibVerifier::setTarget(const Target &T) { Ctx.Target = T; Ctx.DiscoveredFirstError = false; - updateState(Dylib.empty() ? Result::NoVerify : Result::Ignore); + if (Dylib.empty()) { + updateState(Result::NoVerify); + return; + } + updateState(Result::Ignore); + assignSlice(T); } DylibVerifier::Result DylibVerifier::verify(ObjCIVarRecord *R, @@ -205,8 +508,21 @@ DylibVerifier::Result DylibVerifier::verify(GlobalRecord *R, getAnnotatedName(R, Sym.Kind, Demangle ? demangle(Sym.Name) : Sym.Name); SymCtx.Kind = Sym.Kind; SymCtx.FA = FA; + SymCtx.Inlined = R->isInlined(); return verifyImpl(R, SymCtx); } +void DylibVerifier::VerifierContext::emitDiag( + llvm::function_ref<void()> Report) { + if (!DiscoveredFirstError) { + Diag->Report(diag::warn_target) + << (PrintArch ? getArchitectureName(Target.Arch) + : getTargetTripleName(Target)); + DiscoveredFirstError = true; + } + + Report(); +} + } // namespace installapi } // namespace clang diff --git a/clang/lib/InstallAPI/Visitor.cpp b/clang/lib/InstallAPI/Visitor.cpp index 187afe59309d..452c8f2fb1e4 100644 --- a/clang/lib/InstallAPI/Visitor.cpp +++ b/clang/lib/InstallAPI/Visitor.cpp @@ -681,7 +681,7 @@ bool InstallAPIVisitor::VisitCXXRecordDecl(const CXXRecordDecl *D) { std::string Name = getMangledName(M); auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported, - GlobalRecord::Kind::Function, Avail, D, + GlobalRecord::Kind::Function, Avail, M, *Access, getFlags(WeakDef)); Ctx.Verifier->verify(GR, FA); } diff --git a/clang/test/InstallAPI/availability.test b/clang/test/InstallAPI/availability.test new file mode 100644 index 000000000000..55c890b6d882 --- /dev/null +++ b/clang/test/InstallAPI/availability.test @@ -0,0 +1,631 @@ +; RUN: rm -rf %t +; RUN: split-file %s %t +; RUN: sed -e "s|DSTROOT|%/t|g" %t/inputs.json.in > %t/inputs.json + +; RUN: yaml2obj %t/Availability.yaml -o %t/System/Library/Frameworks/Availability.framework/Availability + +; RUN: clang-installapi \ +; RUN: --target=x86_64-apple-macos13 \ +; RUN: -install_name /System/Library/Frameworks/Availability.framework/Versions/A/Availability \ +; RUN: -current_version 1 -compatibility_version 1 \ +; RUN: -F %t/System/Library/Frameworks \ +; RUN: %t/inputs.json -o %t/output.tbd \ +; RUN: --verify-against=%t/System/Library/Frameworks/Availability.framework/Availability \ +; RUN: --verify-mode=ErrorsOnly --filetype=tbd-v5 2> %t/errors.log +; RUN: FileCheck -allow-empty -check-prefix=ERRORSONLY -input-file %t/errors.log %s + +; RUN: clang-installapi \ +; RUN: --target=x86_64-apple-macos13 \ +; RUN: -install_name /System/Library/Frameworks/Availability.framework/Versions/A/Availability \ +; RUN: -current_version 1 -compatibility_version 1 \ +; RUN: -F %t/System/Library/Frameworks \ +; RUN: %t/inputs.json -o %t/output-warnings.tbd \ +; RUN: --verify-against=%t/System/Library/Frameworks/Availability.framework/Availability \ +; RUN: --verify-mode=ErrorsAndWarnings 2> %t/errors.log +; RUN: FileCheck -check-prefixes=VIOLATIONS,ERRORSANDWARNINGS -input-file %t/errors.log %s + +; RUN: not clang-installapi \ +; RUN: --target=x86_64-apple-macos13 \ +; RUN: -install_name /System/Library/Frameworks/Availability.framework/Versions/A/Availability \ +; RUN: -current_version 1 -compatibility_version 1 \ +; RUN: -F %t/System/Library/Frameworks \ +; RUN: %t/inputs.json -o %t/output-pedantic.tbd \ +; RUN: --verify-against=%t/System/Library/Frameworks/Availability.framework/Availability \ +; RUN: --verify-mode=Pedantic 2> %t/errors.log +; RUN: FileCheck -check-prefixes=VIOLATIONS,PEDANTIC -input-file %t/errors.log %s + +; ERRORSONLY-NOT: error +; ERRORSONLY-NOT: warning + +; ERRORSANDWARNINGS-NOT: error +; VIOLATIONS: warning: violations found for x86_64-apple-macos +; VIOLATIONS: declaration 'publicGlobalVariable' is marked unavailable, but symbol is exported in dynamic library +; VIOLATIONS-NEXT: extern int publicGlobalVariable NS_AVAILABLE +; VIOLATIONS: declaration 'Foo' is marked unavailable, but symbol is exported in dynamic library +; VIOLATIONS-NEXT: @interface Foo : NSObject +; VIOLATIONS: declaration 'publicGlobalVariable3' is marked unavailable, but symbol is exported in dynamic library +; VIOLATIONS-NEXT: extern int publicGlobalVariable3 __attribute__((unavailable)) +; VIOLATIONS: declaration 'privateGlobalVariable' is marked unavailable, but symbol is exported in dynamic library +; VIOLATIONS-NEXT: extern int privateGlobalVariable; + +; ERRORSANDWARNINGS-NOT: warning +; PEDANTIC-NOT: error + +;--- inputs.json.in +{ + "headers": [ { + "path" : "DSTROOT/System/Library/Frameworks/Availability.framework/Headers/Availability.h", + "type" : "public" + }, + { + "path" : "DSTROOT/System/Library/Frameworks/Availability.framework/PrivateHeaders/AvailabilityPrivate.h", + "type" : "private" + } + ], + "version": "3" +} + +;--- System/Library/Frameworks/Availability.framework/Headers/AV_Defines.h +#ifndef AV_DEFINES +#define AV_DEFINES + +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=NA))) + +@interface NSObject +@end + +#endif //AV_DEFINES + +;--- System/Library/Frameworks/Availability.framework/PrivateHeaders/AvailabilityPrivate.h +#import <Availability/AV_Defines.h> +// Test private global variable. +NS_AVAILABLE +extern int privateGlobalVariable; + +;--- System/Library/Frameworks/Availability.framework/Headers/Availability.h +#import <Availability/AV_Defines.h> +extern int publicGlobalVariable NS_AVAILABLE; + +// Test public ObjC class +NS_AVAILABLE +@interface Foo : NSObject +@end + +// Test unavailable attribute. +#ifdef __i386__ +#define UNAVAILABLE_I386 __attribute__((unavailable)) +#else +#define UNAVAILABLE_I386 +#endif +extern int publicGlobalVariable2 UNAVAILABLE_I386; + +extern int publicGlobalVariable3 __attribute__((unavailable)) +__attribute__((availability(macosx, introduced = 10.9))); + +// Test obsoleted with exported variable. +extern int publicGlobalVariable4 __attribute__((availability( + macosx, introduced = 10.9, deprecated = 10.10, obsoleted = 10.11))); +// Test obsoleted with non-existent variable. +extern int publicGlobalVariable5 __attribute__((availability( + macosx, introduced = 10.9, deprecated = 10.10, obsoleted = 10.11))); + +#ifdef __i386__ +#define OBSOLETE_I386 __attribute__((availability(macosx, obsoleted = 10.11))) +#else +#define OBSOLETE_I386 +#endif +extern int publicGlobalVariable6 OBSOLETE_I386; + + +/// Created from: +// int publicGlobalVariable; int privateGlobalVariable; +// +// @implementation Foo +// @end +// +// #ifndef __i386__ +// int publicGlobalVariable2; +// #endif +// +// int publicGlobalVariable3; +// int publicGlobalVariable4; +// +// #ifndef __i386__ +// int publicGlobalVariable6; +// #endif +;--- Availability.yaml +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x1000007 + cpusubtype: 0x3 + filetype: 0x6 + ncmds: 14 + sizeofcmds: 1312 + flags: 0x100085 + reserved: 0x0 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __TEXT + vmaddr: 0 + vmsize: 8192 + fileoff: 0 + filesize: 8192 + maxprot: 5 + initprot: 5 + nsects: 2 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x1140 + size: 0 + offset: 0x1140 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x80000000 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: '' + - sectname: __cstring + segname: __TEXT + addr: 0x1140 + size: 4 + offset: 0x1140 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x2 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 466F6F00 + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __DATA_CONST + vmaddr: 8192 + vmsize: 4096 + fileoff: 8192 + filesize: 4096 + maxprot: 3 + initprot: 3 + nsects: 2 + flags: 16 + Sections: + - sectname: __objc_classlist + segname: __DATA_CONST + addr: 0x2000 + size: 8 + offset: 0x2000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x10000000 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: B830000000000000 + - sectname: __objc_imageinfo + segname: __DATA_CONST + addr: 0x2008 + size: 8 + offset: 0x2008 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: '0000000040000000' + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: __DATA + vmaddr: 12288 + vmsize: 4096 + fileoff: 12288 + filesize: 4096 + maxprot: 3 + initprot: 3 + nsects: 3 + flags: 0 + Sections: + - sectname: __objc_const + segname: __DATA + addr: 0x3000 + size: 144 + offset: 0x3000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: '010000002800000028000000000000000000000000000000401100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000000401100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + - sectname: __objc_data + segname: __DATA + addr: 0x3090 + size: 80 + offset: 0x3090 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: '0000000000000000000000000000000000000000000000000000000000000000003000000000000090300000000000000000000000000000000000000000000000000000000000004830000000000000' + - sectname: __common + segname: __DATA + addr: 0x30E0 + size: 24 + offset: 0x0 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x1 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 16384 + vmsize: 824 + fileoff: 16384 + filesize: 824 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_DYLD_INFO_ONLY + cmdsize: 48 + rebase_off: 16384 + rebase_size: 16 + bind_off: 16400 + bind_size: 104 + weak_bind_off: 0 + weak_bind_size: 0 + lazy_bind_off: 0 + lazy_bind_size: 0 + export_off: 16504 + export_size: 152 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 16664 + nsyms: 14 + stroff: 16888 + strsize: 320 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 2 + iextdefsym: 2 + nextdefsym: 8 + iundefsym: 10 + nundefsym: 4 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 0 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_ID_DYLIB + cmdsize: 112 + dylib: + name: 24 + timestamp: 0 + current_version: 65536 + compatibility_version: 65536 + Content: '/System/Library/Frameworks/Availability.framework/Versions/A/Availability' + ZeroPadBytes: 7 + - cmd: LC_UUID + cmdsize: 24 + uuid: 4C4C4470-5555-3144-A142-4EE44DA08D2F + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 851968 + sdk: 983040 + ntools: 1 + Tools: + - tool: 4 + version: 1245184 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 0 + current_version: 14942208 + compatibility_version: 65536 + Content: '/usr/lib/libobjc.A.dylib' + ZeroPadBytes: 8 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 0 + current_version: 88473600 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 16656 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 16664 + datasize: 0 +LinkEditData: + RebaseOpcodes: + - Opcode: REBASE_OPCODE_SET_TYPE_IMM + Imm: 1 + - Opcode: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 1 + ExtraData: [ 0x0 ] + - Opcode: REBASE_OPCODE_DO_REBASE_IMM_TIMES + Imm: 1 + - Opcode: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 2 + ExtraData: [ 0x18 ] + - Opcode: REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB + Imm: 0 + ExtraData: [ 0x2, 0x40 ] + - Opcode: REBASE_OPCODE_ADD_ADDR_IMM_SCALED + Imm: 1 + - Opcode: REBASE_OPCODE_DO_REBASE_IMM_TIMES + Imm: 2 + - Opcode: REBASE_OPCODE_ADD_ADDR_IMM_SCALED + Imm: 3 + - Opcode: REBASE_OPCODE_DO_REBASE_IMM_TIMES + Imm: 1 + - Opcode: REBASE_OPCODE_DONE + Imm: 0 + BindOpcodes: + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: '_OBJC_METACLASS_$_NSObject' + - Opcode: BIND_OPCODE_SET_TYPE_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 2 + ULEBExtraData: [ 0x90 ] + Symbol: '' + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: __objc_empty_cache + - Opcode: BIND_OPCODE_SET_TYPE_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_ADD_ADDR_ULEB + Imm: 0 + ULEBExtraData: [ 0x20 ] + Symbol: '' + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: '_OBJC_CLASS_$_NSObject' + - Opcode: BIND_OPCODE_SET_TYPE_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_ADD_ADDR_ULEB + Imm: 0 + ULEBExtraData: [ 0xFFFFFFFFFFFFFFF0 ] + Symbol: '' + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_DONE + Imm: 0 + Symbol: '' + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 0 + NodeOffset: 5 + Name: _ + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 0 + NodeOffset: 17 + Name: OBJC_ + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 49 + Name: 'METACLASS_$_Foo' + Flags: 0x0 + Address: 0x3090 + Other: 0x0 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 54 + Name: 'CLASS_$_Foo' + Flags: 0x0 + Address: 0x30B8 + Other: 0x0 + ImportName: '' + - TerminalSize: 0 + NodeOffset: 59 + Name: p + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 104 + Name: rivateGlobalVariable + Flags: 0x0 + Address: 0x30E0 + Other: 0x0 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 109 + Name: ublicGlobalVariable + Flags: 0x0 + Address: 0x30E4 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 130 + Name: '4' + Flags: 0x0 + Address: 0x30F0 + Other: 0x0 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 135 + Name: '3' + Flags: 0x0 + Address: 0x30EC + Other: 0x0 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 140 + Name: '2' + Flags: 0x0 + Address: 0x30E8 + Other: 0x0 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 145 + Name: '6' + Flags: 0x0 + Address: 0x30F4 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0xE + n_sect: 5 + n_desc: 0 + n_value: 12288 + - n_strx: 28 + n_type: 0xE + n_sect: 5 + n_desc: 0 + n_value: 12360 + - n_strx: 50 + n_type: 0xF + n_sect: 7 + n_desc: 0 + n_value: 12512 + - n_strx: 73 + n_type: 0xF + n_sect: 7 + n_desc: 0 + n_value: 12516 + - n_strx: 95 + n_type: 0xF + n_sect: 7 + n_desc: 0 + n_value: 12520 + - n_strx: 118 + n_type: 0xF + n_sect: 7 + n_desc: 0 + n_value: 12524 + - n_strx: 141 + n_type: 0xF + n_sect: 7 + n_desc: 0 + n_value: 12528 + - n_strx: 164 + n_type: 0xF + n_sect: 7 + n_desc: 0 + n_value: 12532 + - n_strx: 187 + n_type: 0xF + n_sect: 6 + n_desc: 0 + n_value: 12432 + - n_strx: 209 + n_type: 0xF + n_sect: 6 + n_desc: 0 + n_value: 12472 + - n_strx: 227 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 250 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 277 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 296 + n_type: 0x1 + n_sect: 0 + n_desc: 512 + n_value: 0 + StringTable: + - ' ' + - '__OBJC_METACLASS_RO_$_Foo' + - '__OBJC_CLASS_RO_$_Foo' + - _privateGlobalVariable + - _publicGlobalVariable + - _publicGlobalVariable2 + - _publicGlobalVariable3 + - _publicGlobalVariable4 + - _publicGlobalVariable6 + - '_OBJC_METACLASS_$_Foo' + - '_OBJC_CLASS_$_Foo' + - '_OBJC_CLASS_$_NSObject' + - '_OBJC_METACLASS_$_NSObject' + - __objc_empty_cache + - dyld_stub_binder + - '' + - '' + - '' + - '' + - '' + - '' + - '' +... diff --git a/clang/test/InstallAPI/diagnostics-cpp.test b/clang/test/InstallAPI/diagnostics-cpp.test new file mode 100644 index 000000000000..9319a7a61d48 --- /dev/null +++ b/clang/test/InstallAPI/diagnostics-cpp.test @@ -0,0 +1,462 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DSTROOT|%/t|g" %t/inputs.json.in > %t/inputs.json + +// RUN: yaml2obj %t/Mismatch.yaml -o %t/System/Library/Frameworks/MismatchCpp.framework/MismatchCpp + +// RUN: not clang-installapi --target=arm64-apple-macos13 -x objective-c++ \ +// RUN: -F %t/System/Library/Frameworks \ +// RUN: -install_name /System/Library/Frameworks/MismatchCpp.framework/Versions/A/MismatchCpp \ +// RUN: -current_version 1 -compatibility_version 1 %t/inputs.json \ +// RUN: --verify-against=%t/System/Library/Frameworks/MismatchCpp.framework/MismatchCpp \ +// RUN: --verify-mode=Pedantic -o %t/output.tbd --demangle 2> %t/errors.log +// RUN: FileCheck -input-file %t/errors.log %s + +CHECK: warning: violations found for arm64-apple-macos13 +CHECK: CPP.h:5:7: error: declaration has external linkage, but symbol has internal linkage in dynamic library 'vtable for Bar' +CHECK-NEXT: class Bar : Foo { +CHECK-NEXT: ^ +CHECK-NEXT: CPP.h:5:7: error: declaration has external linkage, but symbol has internal linkage in dynamic library 'typeinfo for Bar' +CHECK-NEXT: CPP.h:5:7: error: declaration has external linkage, but symbol has internal linkage in dynamic library 'typeinfo name for Bar' +CHECK-NEXT: CPP.h:6:7: error: dynamic library symbol '(weak-def) Bar::init()' is weak defined, but its declaration is not +CHECK-NEXT: int init(); +CHECK-NEXT: ^ + +//--- inputs.json.in +{ + "headers": [ { + "path" : "DSTROOT/System/Library/Frameworks/MismatchCpp.framework/Headers/CPP.h", + "type" : "public" + } + ], + "version": "3" +} + +//--- System/Library/Frameworks/MismatchCpp.framework/Headers/CPP.h +class Foo { + virtual int init() = 0; +}; + +class Bar : Foo { + int init(); +}; + +/// Created from: +// With LD flags: -exported_symbol,"__ZN3Bar4initEv" -exported_symbol,"__Z3fooIjEiT_" +// class Foo { virtual int init() = 0;}; +// +// class Bar : Foo {int init() { return 1;}}; +// Bar bar; +// +// template <typename T> int foo(T val) { return 1; } +// template <> int foo(unsigned val) { return 1; } + +//--- Mismatch.yaml +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x0 + filetype: 0x6 + ncmds: 15 + sizeofcmds: 1224 + flags: 0x118085 + reserved: 0x0 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: __TEXT + vmaddr: 0 + vmsize: 16384 + fileoff: 0 + filesize: 16384 + maxprot: 5 + initprot: 5 + nsects: 3 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x10E8 + size: 16 + offset: 0x10E8 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 20008052C0035FD620008052C0035FD6 + - sectname: __const + segname: __TEXT + addr: 0x10F8 + size: 10 + offset: 0x10F8 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 334261720033466F6F00 + - sectname: __unwind_info + segname: __TEXT + addr: 0x1104 + size: 4152 + offset: 0x1104 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000010000002000000000000000200000000200000000000002E81000003800000038000000F81000000000000038000000030000000C0001001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __DATA_CONST + vmaddr: 16384 + vmsize: 16384 + fileoff: 16384 + filesize: 16384 + maxprot: 3 + initprot: 3 + nsects: 2 + flags: 16 + Sections: + - sectname: __const + segname: __DATA_CONST + addr: 0x4000 + size: 80 + offset: 0x4000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 00000000000000002840000000000000F0100000000000001000000000000000FD100000000000801000000000000000F810000000000080000000000100000018400000000000000000000000000000 + - sectname: __objc_imageinfo + segname: __DATA_CONST + addr: 0x4050 + size: 8 + offset: 0x4050 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: '0000000040000000' + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA + vmaddr: 32768 + vmsize: 16384 + fileoff: 32768 + filesize: 16384 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 0 + Sections: + - sectname: __data + segname: __DATA + addr: 0x8000 + size: 8 + offset: 0x8000 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: '1040000000000000' + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 49152 + vmsize: 1104 + fileoff: 49152 + filesize: 1104 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_DYLD_INFO_ONLY + cmdsize: 48 + rebase_off: 49152 + rebase_size: 16 + bind_off: 49168 + bind_size: 96 + weak_bind_off: 49264 + weak_bind_size: 24 + lazy_bind_off: 0 + lazy_bind_size: 0 + export_off: 49288 + export_size: 48 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 49344 + nsyms: 11 + stroff: 49520 + strsize: 192 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 6 + iextdefsym: 6 + nextdefsym: 2 + iundefsym: 8 + nundefsym: 3 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 0 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_ID_DYLIB + cmdsize: 96 + dylib: + name: 24 + timestamp: 0 + current_version: 65536 + compatibility_version: 65536 + Content: '/System/Library/Frameworks/MismatchCpp.framework/Versions/A/MismatchCpp' + ZeroPadBytes: 1 + - cmd: LC_UUID + cmdsize: 24 + uuid: 4C4C44F3-5555-3144-A13F-B3FE15787197 + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 851968 + sdk: 983040 + ntools: 1 + Tools: + - tool: 4 + version: 1245184 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 0 + current_version: 117985024 + compatibility_version: 65536 + Content: '/usr/lib/libc++.1.dylib' + ZeroPadBytes: 1 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 0 + current_version: 88473600 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 49336 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 49344 + datasize: 0 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 49712 + datasize: 544 +LinkEditData: + RebaseOpcodes: + - Opcode: REBASE_OPCODE_SET_TYPE_IMM + Imm: 1 + - Opcode: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 1 + ExtraData: [ 0x8 ] + - Opcode: REBASE_OPCODE_DO_REBASE_IMM_TIMES + Imm: 2 + - Opcode: REBASE_OPCODE_ADD_ADDR_IMM_SCALED + Imm: 1 + - Opcode: REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB + Imm: 0 + ExtraData: [ 0x3, 0x8 ] + - Opcode: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 2 + ExtraData: [ 0x0 ] + - Opcode: REBASE_OPCODE_DO_REBASE_IMM_TIMES + Imm: 1 + - Opcode: REBASE_OPCODE_DONE + Imm: 0 + BindOpcodes: + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: __ZTVN10__cxxabiv117__class_type_infoE + - Opcode: BIND_OPCODE_SET_TYPE_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 1 + ULEBExtraData: [ 0x18 ] + Symbol: '' + - Opcode: BIND_OPCODE_SET_ADDEND_SLEB + Imm: 0 + SLEBExtraData: [ 16 ] + Symbol: '' + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: __ZTVN10__cxxabiv121__vmi_class_type_infoE + - Opcode: BIND_OPCODE_SET_TYPE_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_ADD_ADDR_ULEB + Imm: 0 + ULEBExtraData: [ 0x8 ] + Symbol: '' + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_DONE + Imm: 0 + Symbol: '' + WeakBindOpcodes: + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: __ZN3Bar4initEv + - Opcode: BIND_OPCODE_SET_TYPE_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 1 + ULEBExtraData: [ 0x10 ] + Symbol: '' + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_DONE + Imm: 0 + Symbol: '' + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 0 + NodeOffset: 7 + Name: __Z + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 35 + Name: 3fooIjEiT_ + Flags: 0x0 + Address: 0x10E8 + Other: 0x0 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 40 + Name: N3Bar4initEv + Flags: 0x4 + Address: 0x10F0 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 32 + n_type: 0x1E + n_sect: 4 + n_desc: 0 + n_value: 16384 + - n_strx: 42 + n_type: 0x1E + n_sect: 4 + n_desc: 0 + n_value: 16408 + - n_strx: 52 + n_type: 0x1E + n_sect: 4 + n_desc: 0 + n_value: 16424 + - n_strx: 62 + n_type: 0x1E + n_sect: 6 + n_desc: 0 + n_value: 32768 + - n_strx: 67 + n_type: 0x1E + n_sect: 2 + n_desc: 0 + n_value: 4344 + - n_strx: 77 + n_type: 0x1E + n_sect: 2 + n_desc: 0 + n_value: 4349 + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 4328 + - n_strx: 16 + n_type: 0xF + n_sect: 1 + n_desc: 128 + n_value: 4336 + - n_strx: 87 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 126 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 169 + n_type: 0x1 + n_sect: 0 + n_desc: 512 + n_value: 0 + StringTable: + - ' ' + - __Z3fooIjEiT_ + - __ZN3Bar4initEv + - __ZTV3Bar + - __ZTI3Foo + - __ZTI3Bar + - _bar + - __ZTS3Bar + - __ZTS3Foo + - __ZTVN10__cxxabiv117__class_type_infoE + - __ZTVN10__cxxabiv121__vmi_class_type_infoE + - dyld_stub_binder + - '' + - '' + - '' + - '' + - '' + - '' + FunctionStarts: [ 0x10E8, 0x10F0 ] +... diff --git a/clang/test/InstallAPI/hiddens.test b/clang/test/InstallAPI/hiddens.test new file mode 100644 index 000000000000..b3196ef945cd --- /dev/null +++ b/clang/test/InstallAPI/hiddens.test @@ -0,0 +1,262 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DSTROOT|%/t|g" %t/inputs.json.in > %t/inputs.json + +// RUN: yaml2obj %t/Hidden.yaml -o %t/System/Library/Frameworks/Hidden.framework/Hidden + +// RUN: clang-installapi --target=x86_64-apple-macos13 -x objective-c \ +// RUN: -F %t/System/Library/Frameworks \ +// RUN: -install_name /System/Library/Frameworks/Hidden.framework/Versions/A/Hidden\ +// RUN: -current_version 1 -compatibility_version 1 %t/inputs.json \ +// RUN: --verify-against=%t/System/Library/Frameworks/Hidden.framework/Hidden \ +// RUN: --verify-mode=Pedantic -o %t/output.tbd 2>&1 | FileCheck %s + +// CHECK-NOT: error +// CHECK: warning: use of __private_extern__ + +// RUN: llvm-readtapi --compare %t/output.tbd %t/expected.tbd + +//--- inputs.json.in +{ + "headers": [ { + "path" : "DSTROOT/System/Library/Frameworks/Hidden.framework/Headers/Hidden.h", + "type" : "public" + } + ], + "version": "3" +} + +//--- System/Library/Frameworks/Hidden.framework/Headers/Hidden.h +__private_extern__ int foo(); // Clang doesn't warn on this, but should. +__private_extern__ int baz; +__attribute__((visibility("hidden"))) int bar(); + +/// Created from: +/// #import "Hidden.h" int foo(void) { return 1; } int bar(void) { return 1; } +//--- Hidden.yaml +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x1000007 + cpusubtype: 0x3 + filetype: 0x6 + ncmds: 12 + sizeofcmds: 920 + flags: 0x100085 + reserved: 0x0 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: __TEXT + vmaddr: 0 + vmsize: 8192 + fileoff: 0 + filesize: 8192 + maxprot: 5 + initprot: 5 + nsects: 3 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0xBB8 + size: 22 + offset: 0xBB8 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 554889E5B8010000005DC3554889E5B8010000005DC3 + - sectname: __unwind_info + segname: __TEXT + addr: 0xBD0 + size: 4152 + offset: 0xBD0 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000010000002000000000000000200000000200000000000001B80B00003800000038000000CE0B00000000000038000000030000000C0001001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + - sectname: __eh_frame + segname: __TEXT + addr: 0x1C08 + size: 24 + offset: 0x1C08 + align: 3 + reloff: 0x0 + nreloc: 0 + flags: 0x6000000B + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 1400000000000000017A520001781001100C070890010000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA_CONST + vmaddr: 8192 + vmsize: 4096 + fileoff: 8192 + filesize: 4096 + maxprot: 3 + initprot: 3 + nsects: 1 + flags: 16 + Sections: + - sectname: __objc_imageinfo + segname: __DATA_CONST + addr: 0x2000 + size: 8 + offset: 0x2000 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: '0000000040000000' + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 12288 + vmsize: 104 + fileoff: 12288 + filesize: 104 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_DYLD_INFO_ONLY + cmdsize: 48 + rebase_off: 0 + rebase_size: 0 + bind_off: 0 + bind_size: 0 + weak_bind_off: 0 + weak_bind_size: 0 + lazy_bind_off: 0 + lazy_bind_size: 0 + export_off: 12288 + export_size: 16 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 12312 + nsyms: 3 + stroff: 12360 + strsize: 32 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 1 + iextdefsym: 1 + nextdefsym: 1 + iundefsym: 2 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 0 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_ID_DYLIB + cmdsize: 88 + dylib: + name: 24 + timestamp: 0 + current_version: 65536 + compatibility_version: 65536 + Content: '/System/Library/Frameworks/Hidden.framework/Versions/A/Hidden' + ZeroPadBytes: 3 + - cmd: LC_UUID + cmdsize: 24 + uuid: 4C4C44E7-5555-3144-A133-0271E799C487 + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 851968 + sdk: 983040 + ntools: 1 + Tools: + - tool: 4 + version: 1245184 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 0 + current_version: 88473600 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 12304 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 12312 + datasize: 0 +LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0 + Address: 0x0 + Other: 0x0 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 8 + Name: _foo + Flags: 0x0 + Address: 0xBB8 + Other: 0x0 + ImportName: '' + NameList: + - n_strx: 7 + n_type: 0x1E + n_sect: 1 + n_desc: 0 + n_value: 3011 + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 3000 + - n_strx: 12 + n_type: 0x1 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - _foo + - _bar + - dyld_stub_binder + - '' + - '' + - '' + FunctionStarts: [ 0xBB8, 0xBC3 ] +... + +//--- expected.tbd +--- !tapi-tbd +tbd-version: 4 +targets: [ x86_64-macos ] +flags: [ not_app_extension_safe ] +install-name: '/System/Library/Frameworks/Hidden.framework/Versions/A/Hidden' +... + diff --git a/clang/tools/clang-installapi/ClangInstallAPI.cpp b/clang/tools/clang-installapi/ClangInstallAPI.cpp index d758f7311790..54e82d78d4d2 100644 --- a/clang/tools/clang-installapi/ClangInstallAPI.cpp +++ b/clang/tools/clang-installapi/ClangInstallAPI.cpp @@ -111,17 +111,15 @@ static bool run(ArrayRef<const char *> Args, const char *ProgName) { // Execute and gather AST results. // An invocation is ran for each unique target triple and for each header // access level. - Records FrontendResults; for (const auto &[Targ, Trip] : Opts.DriverOpts.Targets) { + Ctx.Verifier->setTarget(Targ); + Ctx.Slice = std::make_shared<FrontendRecordsSlice>(Trip); for (const HeaderType Type : {HeaderType::Public, HeaderType::Private, HeaderType::Project}) { - Ctx.Slice = std::make_shared<FrontendRecordsSlice>(Trip); - Ctx.Verifier->setTarget(Targ); Ctx.Type = Type; if (!runFrontend(ProgName, Opts.DriverOpts.Verbose, Ctx, InMemoryFileSystem.get(), Opts.getClangFrontendArgs())) return EXIT_FAILURE; - FrontendResults.emplace_back(std::move(Ctx.Slice)); } } diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp index e5ff8a1aaa4f..b8696bb7896d 100644 --- a/clang/tools/clang-installapi/Options.cpp +++ b/clang/tools/clang-installapi/Options.cpp @@ -261,6 +261,9 @@ Options::Options(DiagnosticsEngine &Diag, FileManager *FM, if (!processFrontendOptions(ArgList)) return; + /// Force cc1 options that should always be on. + FrontendArgs = {"-fsyntax-only", "-Wprivate-extern"}; + /// Any unclaimed arguments should be handled by invoking the clang frontend. for (const Arg *A : ArgList) { if (A->isClaimed()) @@ -268,7 +271,6 @@ Options::Options(DiagnosticsEngine &Diag, FileManager *FM, FrontendArgs.emplace_back(A->getSpelling()); llvm::copy(A->getValues(), std::back_inserter(FrontendArgs)); } - FrontendArgs.push_back("-fsyntax-only"); } InstallAPIContext Options::createContext() { diff --git a/clang/tools/diagtool/DiagnosticNames.cpp b/clang/tools/diagtool/DiagnosticNames.cpp index 852b8c226e88..eb90f082437b 100644 --- a/clang/tools/diagtool/DiagnosticNames.cpp +++ b/clang/tools/diagtool/DiagnosticNames.cpp @@ -42,6 +42,7 @@ static const DiagnosticRecord BuiltinDiagnosticsByID[] = { #include "clang/Basic/DiagnosticSemaKinds.inc" #include "clang/Basic/DiagnosticAnalysisKinds.inc" #include "clang/Basic/DiagnosticRefactoringKinds.inc" +#include "clang/Basic/DiagnosticInstallAPIKinds.inc" #undef DIAG }; -- GitLab From 0412840ef877b0b4efe117f0328ac57fc669a871 Mon Sep 17 00:00:00 2001 From: Jie Fu <jiefu@tencent.com> Date: Wed, 20 Mar 2024 10:07:00 +0800 Subject: [PATCH 175/307] [lld] Fix -Wstring-conversion in ObjC.cpp (NFC) llvm-project/lld/MachO/ObjC.cpp:617:12: error: implicit conversion turns string literal into bool: 'const char[55]' to 'bool' [-Werror,-Wstring-conversion] 617 | assert("Tried to read pointer list beyond protocol section end"); | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- lld/MachO/ObjC.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp index f54127638b86..40df2243b26f 100644 --- a/lld/MachO/ObjC.cpp +++ b/lld/MachO/ObjC.cpp @@ -613,8 +613,8 @@ void ObjcCategoryMerger::collectCategoryWriterInfoFromCategory( void ObjcCategoryMerger::parseProtocolListInfo(const ConcatInputSection *isec, uint32_t secOffset, PointerListInfo &ptrList) { - if (!isec || (secOffset + target->wordSize > isec->data.size())) - assert("Tried to read pointer list beyond protocol section end"); + assert((isec && (secOffset + target->wordSize <= isec->data.size())) && + "Tried to read pointer list beyond protocol section end"); const Reloc *reloc = isec->getRelocAt(secOffset); if (!reloc) -- GitLab From db7d0ed71c6444bbe710ba107c1601d9c90bfdcc Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jonas@devlieghere.com> Date: Tue, 19 Mar 2024 19:32:12 -0700 Subject: [PATCH 176/307] Revert "[lldb] Update SymbolFilePDBTests for LineEntry change (d5a277d309e9)" This reverts commit 113214e15b5ce3f3ec313eb1fa91a7038ecd072f as the corresponding change was reverted in a289f66. --- lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp b/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp index 4379ffac9d74..f237dd63ab1c 100644 --- a/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ b/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -102,7 +102,7 @@ protected: EXPECT_EQ(line, entry.line); EXPECT_EQ(address, entry.range.GetBaseAddress()); - EXPECT_TRUE(FileSpecMatchesAsBaseOrFull(spec, entry.GetFile())); + EXPECT_TRUE(FileSpecMatchesAsBaseOrFull(spec, entry.file)); } bool ContainsCompileUnit(const SymbolContextList &sc_list, -- GitLab From e7175b07047d1ba7b012f811064091f12ebf8a40 Mon Sep 17 00:00:00 2001 From: "Yaxun (Sam) Liu" <yaxun.liu@amd.com> Date: Tue, 19 Mar 2024 23:03:57 -0400 Subject: [PATCH 177/307] [HIP] do not link runtime for -r (#85675) since it will cause duplicate symbols when the partially linked object is linked again. --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 2 +- clang/test/Driver/hip-partial-link.hip | 2 +- clang/test/Driver/hip-runtime-libs-linux.hip | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 83015b0cb81a..447886531363 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -2830,7 +2830,7 @@ void tools::addHIPRuntimeLibArgs(const ToolChain &TC, Compilation &C, llvm::opt::ArgStringList &CmdArgs) { if ((C.getActiveOffloadKinds() & Action::OFK_HIP) && !Args.hasArg(options::OPT_nostdlib) && - !Args.hasArg(options::OPT_no_hip_rt)) { + !Args.hasArg(options::OPT_no_hip_rt) && !Args.hasArg(options::OPT_r)) { TC.AddHIPRuntimeLibArgs(Args, CmdArgs); } else { // Claim "no HIP libraries" arguments if any diff --git a/clang/test/Driver/hip-partial-link.hip b/clang/test/Driver/hip-partial-link.hip index faa185972abc..c8451ec81ed3 100644 --- a/clang/test/Driver/hip-partial-link.hip +++ b/clang/test/Driver/hip-partial-link.hip @@ -47,7 +47,7 @@ // OBJ: D __hip_gpubin_handle_[[ID2]] // RUN: %clang -v --target=x86_64-unknown-linux-gnu --no-offload-new-driver \ -// RUN: --hip-link -no-hip-rt -fgpu-rdc --offload-arch=gfx906 \ +// RUN: --hip-link -fgpu-rdc --offload-arch=gfx906 \ // RUN: -fuse-ld=lld -nostdlib -r %t.main.o %t.lib.o -o %t.final.o \ // RUN: 2>&1 | FileCheck -check-prefix=LINK-O %s // LINK-O-NOT: Found undefined HIP {{.*}}symbol diff --git a/clang/test/Driver/hip-runtime-libs-linux.hip b/clang/test/Driver/hip-runtime-libs-linux.hip index 142582963c95..a4cd2733114b 100644 --- a/clang/test/Driver/hip-runtime-libs-linux.hip +++ b/clang/test/Driver/hip-runtime-libs-linux.hip @@ -43,6 +43,11 @@ // RUN: --rocm-path=%S/Inputs/rocm %t.o 2>&1 \ // RUN: | FileCheck -check-prefixes=NOHIPRT %s +// Test HIP runtime lib is not linked with -r. +// RUN: %clang -### --hip-link -r --target=x86_64-linux-gnu \ +// RUN: --rocm-path=%S/Inputs/rocm %t.o 2>&1 \ +// RUN: | FileCheck -check-prefixes=NOHIPRT %s + // Test HIP runtime lib is linked without hip-link if there is HIP input file. // RUN: %clang -### --target=x86_64-linux-gnu -nogpuinc -nogpulib \ // RUN: --rocm-path=%S/Inputs/rocm %s 2>&1 \ -- GitLab From 92b2b49994eb804253db1deeb7e9f63904cd96d1 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jonas@devlieghere.com> Date: Fri, 15 Mar 2024 11:42:44 -0700 Subject: [PATCH 178/307] [lldb] Outline Doxygen comments in LineEntry.h (NFC) Outline and correct Doxygen comments in LineEntry. --- lldb/include/lldb/Symbol/LineEntry.h | 59 ++++++++++++++++------------ 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/lldb/include/lldb/Symbol/LineEntry.h b/lldb/include/lldb/Symbol/LineEntry.h index c2daba916e3f..31e1cd0b36f9 100644 --- a/lldb/include/lldb/Symbol/LineEntry.h +++ b/lldb/include/lldb/Symbol/LineEntry.h @@ -130,31 +130,40 @@ struct LineEntry { /// Shared pointer to the target this LineEntry belongs to. void ApplyFileMappings(lldb::TargetSP target_sp); - // Member variables. - AddressRange range; ///< The section offset address range for this line entry. - FileSpec file; ///< The source file, possibly mapped by the target.source-map - ///setting - lldb::SupportFileSP - original_file_sp; ///< The original source file, from debug info. - uint32_t line = LLDB_INVALID_LINE_NUMBER; ///< The source line number, or zero - ///< if there is no line number - /// information. - uint16_t column = - 0; ///< The column number of the source line, or zero if there - /// is no column information. - uint16_t is_start_of_statement : 1, ///< Indicates this entry is the beginning - ///of a statement. - is_start_of_basic_block : 1, ///< Indicates this entry is the beginning of - ///a basic block. - is_prologue_end : 1, ///< Indicates this entry is one (of possibly many) - ///where execution should be suspended for an entry - ///breakpoint of a function. - is_epilogue_begin : 1, ///< Indicates this entry is one (of possibly many) - ///where execution should be suspended for an exit - ///breakpoint of a function. - is_terminal_entry : 1; ///< Indicates this entry is that of the first byte - ///after the end of a sequence of target machine - ///instructions. + /// The section offset address range for this line entry. + AddressRange range; + + /// The source file, possibly mapped by the target.source-map setting. + FileSpec file; + + /// The original source file, from debug info. + lldb::SupportFileSP original_file_sp; + + /// The source line number, or LLDB_INVALID_LINE_NUMBER if there is no line + /// number information. + uint32_t line = LLDB_INVALID_LINE_NUMBER; + + /// The column number of the source line, or zero if there is no column + /// information. + uint16_t column = 0; + + /// Indicates this entry is the beginning of a statement. + uint16_t is_start_of_statement : 1; + + /// Indicates this entry is the beginning of a basic block. + uint16_t is_start_of_basic_block : 1; + + /// Indicates this entry is one (of possibly many) where execution should be + /// suspended for an entry breakpoint of a function. + uint16_t is_prologue_end : 1; + + /// Indicates this entry is one (of possibly many) where execution should be + /// suspended for an exit breakpoint of a function. + uint16_t is_epilogue_begin : 1; + + /// Indicates this entry is that of the first byte after the end of a sequence + /// of target machine instructions. + uint16_t is_terminal_entry : 1; }; /// Less than operator. -- GitLab From a29234445ca7162a6db4913ec900fd9aae1fa18e Mon Sep 17 00:00:00 2001 From: Craig Topper <craig.topper@sifive.com> Date: Tue, 19 Mar 2024 20:56:58 -0700 Subject: [PATCH 179/307] [RISCV] Refactor code to reduce nesting and remove repeated calls to getOpcode(). NFC (#85847) --- llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp | 25 ++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index a68674b221d3..10bf1e88d741 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -431,29 +431,28 @@ bool RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, } if (!IsRVVSpill) { - if (MI.getOpcode() == RISCV::ADDI && !isInt<12>(Offset.getFixed())) { + int64_t Val = Offset.getFixed(); + int64_t Lo12 = SignExtend64<12>(Val); + unsigned Opc = MI.getOpcode(); + if (Opc == RISCV::ADDI && !isInt<12>(Val)) { // We chose to emit the canonical immediate sequence rather than folding // the offset into the using add under the theory that doing so doesn't // save dynamic instruction count and some target may fuse the canonical // 32 bit immediate sequence. We still need to clear the portion of the // offset encoded in the immediate. MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0); + } else if ((Opc == RISCV::PREFETCH_I || Opc == RISCV::PREFETCH_R || + Opc == RISCV::PREFETCH_W) && + (Lo12 & 0b11111) != 0) { + // Prefetch instructions require the offset to be 32 byte aligned. + MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0); } else { // We can encode an add with 12 bit signed immediate in the immediate // operand of our user instruction. As a result, the remaining // offset can by construction, at worst, a LUI and a ADD. - int64_t Val = Offset.getFixed(); - int64_t Lo12 = SignExtend64<12>(Val); - if ((MI.getOpcode() == RISCV::PREFETCH_I || - MI.getOpcode() == RISCV::PREFETCH_R || - MI.getOpcode() == RISCV::PREFETCH_W) && - (Lo12 & 0b11111) != 0) - MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0); - else { - MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Lo12); - Offset = StackOffset::get((uint64_t)Val - (uint64_t)Lo12, - Offset.getScalable()); - } + MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Lo12); + Offset = StackOffset::get((uint64_t)Val - (uint64_t)Lo12, + Offset.getScalable()); } } -- GitLab From f375aff594d97fc9f6cf2cffb502882833c15cdd Mon Sep 17 00:00:00 2001 From: Craig Topper <craig.topper@sifive.com> Date: Tue, 19 Mar 2024 21:27:25 -0700 Subject: [PATCH 180/307] [RISCV] Add the CSR names from Smrnmi. (#83370) Specification is here https://github.com/riscv/riscv-isa-manual/blob/main/src/rnmi.adoc CSRs numbers defined here https://github.com/riscv/riscv-isa-manual/blob/main/src/priv-csrs.adoc --- llvm/docs/ReleaseNotes.rst | 1 + llvm/lib/Target/RISCV/RISCVSystemOperands.td | 9 ++++ llvm/test/MC/RISCV/rv32-machine-csr-names.s | 56 ++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 254f76d9e514..03691efe836f 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -108,6 +108,7 @@ Changes to the RISC-V Backend * The experimental Ssnpm, Smnpm, Smmpm, Sspm, and Supm 0.8.1 Pointer Masking extensions are supported. * The experimental Ssqosid extension is supported. * Zacas is no longer experimental. +* Added the CSR names from the Resumable Non-Maskable Interrupts (Smrnmi) extension. Changes to the WebAssembly Backend ---------------------------------- diff --git a/llvm/lib/Target/RISCV/RISCVSystemOperands.td b/llvm/lib/Target/RISCV/RISCVSystemOperands.td index 79f977e5b322..01c276711950 100644 --- a/llvm/lib/Target/RISCV/RISCVSystemOperands.td +++ b/llvm/lib/Target/RISCV/RISCVSystemOperands.td @@ -418,7 +418,16 @@ def : SysReg<"vsieh", 0x214>; def : SysReg<"vsiph", 0x254>; } // isRV32Only +//===----------------------------------------------- // Jump Vector Table CSR //===----------------------------------------------- def : SysReg<"jvt", 0x017>; + +//===----------------------------------------------- +// Resumable Non-Maskable Interrupts(Smrnmi) CSRs +//===----------------------------------------------- +def : SysReg<"mnscratch", 0x740>; +def : SysReg<"mnepc", 0x741>; +def : SysReg<"mncause", 0x742>; +def : SysReg<"mnstatus", 0x744>; diff --git a/llvm/test/MC/RISCV/rv32-machine-csr-names.s b/llvm/test/MC/RISCV/rv32-machine-csr-names.s index e7a6d9ce718f..016f448d8dac 100644 --- a/llvm/test/MC/RISCV/rv32-machine-csr-names.s +++ b/llvm/test/MC/RISCV/rv32-machine-csr-names.s @@ -1149,3 +1149,59 @@ csrrs t2, 0x319, zero csrrs t1, miph, zero # uimm12 csrrs t2, 0x354, zero + +################################################ +# Resumable Non-Maskable Interrupts(Smrnmi) CSRs +################################################ + +# mnscratch +# name +# CHECK-INST: csrrs t1, mnscratch, zero +# CHECK-ENC: encoding: [0x73,0x23,0x00,0x74] +# CHECK-INST-ALIAS: csrr t1, mnscratch +# uimm12 +# CHECK-INST: csrrs t2, mnscratch, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x00,0x74] +# CHECK-INST-ALIAS: csrr t2, mnscratch +csrrs t1, mnscratch, zero +# uimm12 +csrrs t2, 0x740, zero + +# mnepc +# name +# CHECK-INST: csrrs t1, mnepc, zero +# CHECK-ENC: encoding: [0x73,0x23,0x10,0x74] +# CHECK-INST-ALIAS: csrr t1, mnepc +# uimm12 +# CHECK-INST: csrrs t2, mnepc, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x10,0x74] +# CHECK-INST-ALIAS: csrr t2, mnepc +csrrs t1, mnepc, zero +# uimm12 +csrrs t2, 0x741, zero + +# mncause +# name +# CHECK-INST: csrrs t1, mncause, zero +# CHECK-ENC: encoding: [0x73,0x23,0x20,0x74] +# CHECK-INST-ALIAS: csrr t1, mncause +# uimm12 +# CHECK-INST: csrrs t2, mncause, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x20,0x74] +# CHECK-INST-ALIAS: csrr t2, mncause +csrrs t1, mncause, zero +# uimm12 +csrrs t2, 0x742, zero + +# mnstatus +# name +# CHECK-INST: csrrs t1, mnstatus, zero +# CHECK-ENC: encoding: [0x73,0x23,0x40,0x74] +# CHECK-INST-ALIAS: csrr t1, mnstatus +# uimm12 +# CHECK-INST: csrrs t2, mnstatus, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x40,0x74] +# CHECK-INST-ALIAS: csrr t2, mnstatus +csrrs t1, mnstatus, zero +# uimm12 +csrrs t2, 0x744, zero -- GitLab From b2082a98175b0e5356f23bf21d3dc5b76edea390 Mon Sep 17 00:00:00 2001 From: Owen Pan <owenpiano@gmail.com> Date: Tue, 19 Mar 2024 20:58:49 -0700 Subject: [PATCH 181/307] Revert "[clang-format][NFC] Delete 100+ redundant #include lines in .cpp files" This reverts commit b92d6dd704d789240685a336ad8b25a9f381b4cc. See github.com/llvm/llvm-project/commit/b92d6dd704d7#commitcomment-139992444 We should use a tool like Visual Studio to clean up the headers. --- clang/lib/Format/AffectedRangeManager.cpp | 1 + clang/lib/Format/BreakableToken.cpp | 4 ++++ clang/lib/Format/ContinuationIndenter.cpp | 9 +++++++++ clang/lib/Format/DefinitionBlockSeparator.cpp | 1 + clang/lib/Format/FormatToken.cpp | 3 +++ clang/lib/Format/FormatTokenLexer.cpp | 4 ++++ clang/lib/Format/MacroCallReconstructor.cpp | 3 +++ clang/lib/Format/MacroExpander.cpp | 11 +++++++++++ clang/lib/Format/NamespaceEndCommentsFixer.cpp | 3 +++ .../Format/ObjCPropertyAttributeOrderFixer.cpp | 2 ++ clang/lib/Format/QualifierAlignmentFixer.cpp | 6 ++++++ clang/lib/Format/SortJavaScriptImports.cpp | 13 +++++++++++++ clang/lib/Format/TokenAnalyzer.cpp | 15 +++++++++++++++ clang/lib/Format/TokenAnnotator.cpp | 4 ++++ clang/lib/Format/UnwrappedLineFormatter.cpp | 2 ++ clang/lib/Format/UnwrappedLineParser.cpp | 11 +++++++++++ clang/lib/Format/UsingDeclarationsSorter.cpp | 5 +++++ clang/lib/Format/WhitespaceManager.cpp | 3 +++ clang/tools/clang-format/ClangFormat.cpp | 6 ++++++ 19 files changed, 106 insertions(+) diff --git a/clang/lib/Format/AffectedRangeManager.cpp b/clang/lib/Format/AffectedRangeManager.cpp index ae08965714b1..bf124d73e89e 100644 --- a/clang/lib/Format/AffectedRangeManager.cpp +++ b/clang/lib/Format/AffectedRangeManager.cpp @@ -13,6 +13,7 @@ #include "AffectedRangeManager.h" +#include "FormatToken.h" #include "TokenAnnotator.h" namespace clang { diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index c33b74eeb80b..75304908dc65 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -15,6 +15,10 @@ #include "BreakableToken.h" #include "ContinuationIndenter.h" #include "clang/Basic/CharInfo.h" +#include "clang/Format/Format.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Debug.h" +#include <algorithm> #define DEBUG_TYPE "format-token-breaker" diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 6ccc81909368..700bce35c868 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -14,6 +14,15 @@ #include "ContinuationIndenter.h" #include "BreakableToken.h" #include "FormatInternal.h" +#include "FormatToken.h" +#include "WhitespaceManager.h" +#include "clang/Basic/OperatorPrecedence.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TokenKinds.h" +#include "clang/Format/Format.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/Support/Debug.h" +#include <optional> #define DEBUG_TYPE "format-indenter" diff --git a/clang/lib/Format/DefinitionBlockSeparator.cpp b/clang/lib/Format/DefinitionBlockSeparator.cpp index 32fc77de4407..319236d3bd61 100644 --- a/clang/lib/Format/DefinitionBlockSeparator.cpp +++ b/clang/lib/Format/DefinitionBlockSeparator.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "DefinitionBlockSeparator.h" +#include "llvm/Support/Debug.h" #define DEBUG_TYPE "definition-block-separator" namespace clang { diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp index 99405fb9d08d..4fb70ffac706 100644 --- a/clang/lib/Format/FormatToken.cpp +++ b/clang/lib/Format/FormatToken.cpp @@ -14,6 +14,9 @@ #include "FormatToken.h" #include "ContinuationIndenter.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Debug.h" +#include <climits> namespace clang { namespace format { diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index 12db4def10fb..036f7e6a4efc 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -13,7 +13,11 @@ //===----------------------------------------------------------------------===// #include "FormatTokenLexer.h" +#include "FormatToken.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" +#include "clang/Format/Format.h" +#include "llvm/Support/Regex.h" namespace clang { namespace format { diff --git a/clang/lib/Format/MacroCallReconstructor.cpp b/clang/lib/Format/MacroCallReconstructor.cpp index 5ba4f2c99a6a..101acefdfe7a 100644 --- a/clang/lib/Format/MacroCallReconstructor.cpp +++ b/clang/lib/Format/MacroCallReconstructor.cpp @@ -16,7 +16,10 @@ #include "Macros.h" #include "UnwrappedLineParser.h" +#include "clang/Basic/TokenKinds.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/Support/Debug.h" +#include <cassert> #define DEBUG_TYPE "format-reconstruct" diff --git a/clang/lib/Format/MacroExpander.cpp b/clang/lib/Format/MacroExpander.cpp index 7668765764e8..5a1cdd884c5e 100644 --- a/clang/lib/Format/MacroExpander.cpp +++ b/clang/lib/Format/MacroExpander.cpp @@ -14,8 +14,19 @@ #include "Macros.h" +#include "Encoding.h" +#include "FormatToken.h" #include "FormatTokenLexer.h" +#include "clang/Basic/TokenKinds.h" +#include "clang/Format/Format.h" +#include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/HeaderSearchOptions.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/ModuleLoader.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PreprocessorOptions.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/Support/ErrorHandling.h" namespace clang { namespace format { diff --git a/clang/lib/Format/NamespaceEndCommentsFixer.cpp b/clang/lib/Format/NamespaceEndCommentsFixer.cpp index 010cc41f1768..08f8d6840fe0 100644 --- a/clang/lib/Format/NamespaceEndCommentsFixer.cpp +++ b/clang/lib/Format/NamespaceEndCommentsFixer.cpp @@ -13,6 +13,9 @@ //===----------------------------------------------------------------------===// #include "NamespaceEndCommentsFixer.h" +#include "clang/Basic/TokenKinds.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Regex.h" #define DEBUG_TYPE "namespace-end-comments-fixer" diff --git a/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp b/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp index 6339d346fd9c..c91d6251425e 100644 --- a/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp +++ b/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp @@ -15,6 +15,8 @@ #include "ObjCPropertyAttributeOrderFixer.h" +#include <algorithm> + namespace clang { namespace format { diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp index 4bc2698a1146..c26353045672 100644 --- a/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -13,6 +13,12 @@ //===----------------------------------------------------------------------===// #include "QualifierAlignmentFixer.h" +#include "FormatToken.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Regex.h" + +#include <algorithm> +#include <optional> #define DEBUG_TYPE "format-qualifier-alignment-fixer" diff --git a/clang/lib/Format/SortJavaScriptImports.cpp b/clang/lib/Format/SortJavaScriptImports.cpp index fda2ad8c311b..1a6a1b19e702 100644 --- a/clang/lib/Format/SortJavaScriptImports.cpp +++ b/clang/lib/Format/SortJavaScriptImports.cpp @@ -13,6 +13,19 @@ #include "SortJavaScriptImports.h" #include "TokenAnalyzer.h" +#include "TokenAnnotator.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TokenKinds.h" +#include "clang/Format/Format.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Debug.h" +#include <algorithm> +#include <string> #define DEBUG_TYPE "format-formatter" diff --git a/clang/lib/Format/TokenAnalyzer.cpp b/clang/lib/Format/TokenAnalyzer.cpp index 2fdc2460bf67..bd648c430f9b 100644 --- a/clang/lib/Format/TokenAnalyzer.cpp +++ b/clang/lib/Format/TokenAnalyzer.cpp @@ -14,6 +14,21 @@ //===----------------------------------------------------------------------===// #include "TokenAnalyzer.h" +#include "AffectedRangeManager.h" +#include "Encoding.h" +#include "FormatToken.h" +#include "FormatTokenLexer.h" +#include "TokenAnnotator.h" +#include "UnwrappedLineParser.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Format/Format.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Debug.h" +#include <type_traits> #define DEBUG_TYPE "format-formatter" diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 8dc8e13688ed..94d2266555f6 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -13,7 +13,11 @@ //===----------------------------------------------------------------------===// #include "TokenAnnotator.h" +#include "FormatToken.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TokenKinds.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Support/Debug.h" #define DEBUG_TYPE "format-token-annotator" diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index bb5841f4e926..fb31980ab9f4 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -7,8 +7,10 @@ //===----------------------------------------------------------------------===// #include "UnwrappedLineFormatter.h" +#include "FormatToken.h" #include "NamespaceEndCommentsFixer.h" #include "WhitespaceManager.h" +#include "llvm/Support/Debug.h" #include <queue> #define DEBUG_TYPE "format-formatter" diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index e89dfbdb2e0c..98ae1c8f62bb 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -13,9 +13,20 @@ //===----------------------------------------------------------------------===// #include "UnwrappedLineParser.h" +#include "FormatToken.h" +#include "FormatTokenLexer.h" #include "FormatTokenSource.h" +#include "Macros.h" #include "TokenAnnotator.h" +#include "clang/Basic/TokenKinds.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/raw_os_ostream.h" +#include "llvm/Support/raw_ostream.h" + +#include <algorithm> +#include <utility> #define DEBUG_TYPE "format-parser" diff --git a/clang/lib/Format/UsingDeclarationsSorter.cpp b/clang/lib/Format/UsingDeclarationsSorter.cpp index 3543f86b1a65..2f4b1e0e4627 100644 --- a/clang/lib/Format/UsingDeclarationsSorter.cpp +++ b/clang/lib/Format/UsingDeclarationsSorter.cpp @@ -13,6 +13,11 @@ //===----------------------------------------------------------------------===// #include "UsingDeclarationsSorter.h" +#include "clang/Format/Format.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Regex.h" + +#include <algorithm> #define DEBUG_TYPE "using-declarations-sorter" diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 6577c19cdf79..753be25bfd67 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -12,6 +12,9 @@ //===----------------------------------------------------------------------===// #include "WhitespaceManager.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include <algorithm> namespace clang { namespace format { diff --git a/clang/tools/clang-format/ClangFormat.cpp b/clang/tools/clang-format/ClangFormat.cpp index 60b0f5d1a0f4..e122cea50f72 100644 --- a/clang/tools/clang-format/ClangFormat.cpp +++ b/clang/tools/clang-format/ClangFormat.cpp @@ -13,12 +13,18 @@ //===----------------------------------------------------------------------===// #include "../../lib/Format/MatchFilePath.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Version.h" #include "clang/Format/Format.h" #include "clang/Rewrite/Core/Rewriter.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/InitLLVM.h" +#include "llvm/Support/Process.h" #include <fstream> using namespace llvm; -- GitLab From 3eb9ff30959a670559bcba03d149d4c51bf7c9c9 Mon Sep 17 00:00:00 2001 From: Yeoul Na <yeoul_na@apple.com> Date: Wed, 20 Mar 2024 13:36:56 +0900 Subject: [PATCH 182/307] Turn 'counted_by' into a type attribute and parse it into 'CountAttributedType' (#78000) In `-fbounds-safety`, bounds annotations are considered type attributes rather than declaration attributes. Constructing them as type attributes allows us to extend the attribute to apply nested pointers, which is essential to annotate functions that involve out parameters: `void foo(int *__counted_by(*out_count) *out_buf, int *out_count)`. We introduce a new sugar type to support bounds annotated types, `CountAttributedType`. In order to maintain extra data (the bounds expression and the dependent declaration information) that is not trackable in `AttributedType` we create a new type dedicate to this functionality. This patch also extends the parsing logic to parse the `counted_by` argument as an expression, which will allow us to extend the model to support arguments beyond an identifier, e.g., `__counted_by(n + m)` in the future as specified by `-fbounds-safety`. This also adjusts `__bdos` and array-bounds sanitizer code that already uses `CountedByAttr` to check `CountAttributedType` instead to get the field referred to by the attribute. --- clang/include/clang/AST/ASTContext.h | 7 + clang/include/clang/AST/PropertiesBase.td | 1 + clang/include/clang/AST/RecursiveASTVisitor.h | 9 + clang/include/clang/AST/Type.h | 156 +++++++++++++++ clang/include/clang/AST/TypeLoc.h | 26 +++ clang/include/clang/AST/TypeProperties.td | 19 ++ clang/include/clang/Basic/Attr.td | 27 +-- .../clang/Basic/DiagnosticSemaKinds.td | 14 +- clang/include/clang/Basic/TypeNodes.td | 2 + clang/include/clang/Parse/Parser.h | 5 + clang/include/clang/Sema/Sema.h | 11 +- .../clang/Serialization/ASTRecordReader.h | 2 + .../clang/Serialization/ASTRecordWriter.h | 5 + .../clang/Serialization/TypeBitCodes.def | 2 +- clang/lib/AST/ASTContext.cpp | 55 ++++++ clang/lib/AST/ASTImporter.cpp | 32 ++- clang/lib/AST/ASTStructuralEquivalence.cpp | 7 + clang/lib/AST/ItaniumMangle.cpp | 1 + clang/lib/AST/Type.cpp | 69 +++++++ clang/lib/AST/TypeLoc.cpp | 4 + clang/lib/AST/TypePrinter.cpp | 32 +++ clang/lib/CodeGen/CGBuiltin.cpp | 6 +- clang/lib/CodeGen/CGDebugInfo.cpp | 1 + clang/lib/CodeGen/CGExpr.cpp | 37 +--- clang/lib/CodeGen/CodeGenFunction.cpp | 1 + clang/lib/Parse/ParseDecl.cpp | 90 +++++++++ clang/lib/Sema/SemaDecl.cpp | 6 - clang/lib/Sema/SemaDeclAttr.cpp | 187 ++++++++---------- clang/lib/Sema/SemaExpr.cpp | 25 ++- clang/lib/Sema/SemaType.cpp | 23 +++ clang/lib/Sema/TreeTransform.h | 28 +++ clang/lib/Serialization/ASTReader.cpp | 8 + clang/lib/Serialization/ASTWriter.cpp | 4 + .../Modules/bounds-safety-attributed-type.c | 27 +++ .../Inputs/bounds-safety-attributed-type.h | 4 + .../test/PCH/bounds-safety-attributed-type.c | 17 ++ clang/test/Sema/attr-counted-by.c | 68 ++++++- clang/tools/libclang/CIndex.cpp | 4 + 38 files changed, 835 insertions(+), 187 deletions(-) create mode 100644 clang/test/Modules/bounds-safety-attributed-type.c create mode 100644 clang/test/PCH/Inputs/bounds-safety-attributed-type.h create mode 100644 clang/test/PCH/bounds-safety-attributed-type.c diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index ff6b64c7f72d..002f36ecbbaa 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -250,6 +250,8 @@ class ASTContext : public RefCountedBase<ASTContext> { DependentBitIntTypes; llvm::FoldingSet<BTFTagAttributedType> BTFTagAttributedTypes; + mutable llvm::FoldingSet<CountAttributedType> CountAttributedTypes; + mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames; mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames; mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage> @@ -1341,6 +1343,11 @@ public: return CanQualType::CreateUnsafe(getPointerType((QualType) T)); } + QualType + getCountAttributedType(QualType T, Expr *CountExpr, bool CountInBytes, + bool OrNull, + ArrayRef<TypeCoupledDeclRefInfo> DependentDecls) const; + /// Return the uniqued reference to a type adjusted from the original /// type to a new type. QualType getAdjustedType(QualType Orig, QualType New) const; diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td index 0270c086d06b..6df1d93a7ba2 100644 --- a/clang/include/clang/AST/PropertiesBase.td +++ b/clang/include/clang/AST/PropertiesBase.td @@ -143,6 +143,7 @@ def UInt32 : CountPropertyType<"uint32_t">; def UInt64 : CountPropertyType<"uint64_t">; def UnaryTypeTransformKind : EnumPropertyType<"UnaryTransformType::UTTKind">; def VectorKind : EnumPropertyType<"VectorKind">; +def TypeCoupledDeclRefInfo : PropertyType; def ExceptionSpecInfo : PropertyType<"FunctionProtoType::ExceptionSpecInfo"> { let BufferElementTypes = [ QualType ]; diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 5080551ada4f..4a1ff222ecad 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1110,6 +1110,12 @@ DEF_TRAVERSE_TYPE(InjectedClassNameType, {}) DEF_TRAVERSE_TYPE(AttributedType, { TRY_TO(TraverseType(T->getModifiedType())); }) +DEF_TRAVERSE_TYPE(CountAttributedType, { + if (T->getCountExpr()) + TRY_TO(TraverseStmt(T->getCountExpr())); + TRY_TO(TraverseType(T->desugar())); +}) + DEF_TRAVERSE_TYPE(BTFTagAttributedType, { TRY_TO(TraverseType(T->getWrappedType())); }) @@ -1401,6 +1407,9 @@ DEF_TRAVERSE_TYPELOC(MacroQualifiedType, DEF_TRAVERSE_TYPELOC(AttributedType, { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); }) +DEF_TRAVERSE_TYPELOC(CountAttributedType, + { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); }) + DEF_TRAVERSE_TYPELOC(BTFTagAttributedType, { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); }) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index be18535e3e4c..b3bf23227a47 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -61,6 +61,7 @@ class BTFTypeTagAttr; class ExtQuals; class QualType; class ConceptDecl; +class ValueDecl; class TagDecl; class TemplateParameterList; class Type; @@ -2000,6 +2001,21 @@ protected: unsigned NumExpansions; }; + class CountAttributedTypeBitfields { + friend class CountAttributedType; + + LLVM_PREFERRED_TYPE(TypeBitfields) + unsigned : NumTypeBits; + + static constexpr unsigned NumCoupledDeclsBits = 4; + unsigned NumCoupledDecls : NumCoupledDeclsBits; + LLVM_PREFERRED_TYPE(bool) + unsigned CountInBytes : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned OrNull : 1; + }; + static_assert(sizeof(CountAttributedTypeBitfields) <= sizeof(unsigned)); + union { TypeBitfields TypeBits; ArrayTypeBitfields ArrayTypeBits; @@ -2022,6 +2038,7 @@ protected: DependentTemplateSpecializationTypeBitfields DependentTemplateSpecializationTypeBits; PackExpansionTypeBitfields PackExpansionTypeBits; + CountAttributedTypeBitfields CountAttributedTypeBits; }; private: @@ -2264,6 +2281,7 @@ public: bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); } bool isPointerType() const; bool isAnyPointerType() const; // Any C pointer or ObjC object pointer + bool isCountAttributedType() const; bool isBlockPointerType() const; bool isVoidPointerType() const; bool isReferenceType() const; @@ -2724,6 +2742,14 @@ template <> const TemplateSpecializationType *Type::getAs() const; /// until it reaches an AttributedType or a non-sugared type. template <> const AttributedType *Type::getAs() const; +/// This will check for a BoundsAttributedType by removing any existing +/// sugar until it reaches an BoundsAttributedType or a non-sugared type. +template <> const BoundsAttributedType *Type::getAs() const; + +/// This will check for a CountAttributedType by removing any existing +/// sugar until it reaches an CountAttributedType or a non-sugared type. +template <> const CountAttributedType *Type::getAs() const; + // We can do canonical leaf types faster, because we don't have to // worry about preserving child type decoration. #define TYPE(Class, Base) @@ -2922,6 +2948,136 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } }; +/// [BoundsSafety] Represents information of declarations referenced by the +/// arguments of the `counted_by` attribute and the likes. +class TypeCoupledDeclRefInfo { +public: + using BaseTy = llvm::PointerIntPair<ValueDecl *, 1, unsigned>; + +private: + enum { + DerefShift = 0, + DerefMask = 1, + }; + BaseTy Data; + +public: + /// \p D is to a declaration referenced by the argument of attribute. \p Deref + /// indicates whether \p D is referenced as a dereferenced form, e.g., \p + /// Deref is true for `*n` in `int *__counted_by(*n)`. + TypeCoupledDeclRefInfo(ValueDecl *D = nullptr, bool Deref = false); + + bool isDeref() const; + ValueDecl *getDecl() const; + unsigned getInt() const; + void *getOpaqueValue() const; + bool operator==(const TypeCoupledDeclRefInfo &Other) const; + void setFromOpaqueValue(void *V); +}; + +/// [BoundsSafety] Represents a parent type class for CountAttributedType and +/// similar sugar types that will be introduced to represent a type with a +/// bounds attribute. +/// +/// Provides a common interface to navigate declarations referred to by the +/// bounds expression. + +class BoundsAttributedType : public Type, public llvm::FoldingSetNode { + QualType WrappedTy; + +protected: + ArrayRef<TypeCoupledDeclRefInfo> Decls; // stored in trailing objects + + BoundsAttributedType(TypeClass TC, QualType Wrapped, QualType Canon); + +public: + bool isSugared() const { return true; } + QualType desugar() const { return WrappedTy; } + + using decl_iterator = const TypeCoupledDeclRefInfo *; + using decl_range = llvm::iterator_range<decl_iterator>; + + decl_iterator dependent_decl_begin() const { return Decls.begin(); } + decl_iterator dependent_decl_end() const { return Decls.end(); } + + unsigned getNumCoupledDecls() const { return Decls.size(); } + + decl_range dependent_decls() const { + return decl_range(dependent_decl_begin(), dependent_decl_end()); + } + + ArrayRef<TypeCoupledDeclRefInfo> getCoupledDecls() const { + return {dependent_decl_begin(), dependent_decl_end()}; + } + + bool referencesFieldDecls() const; + + static bool classof(const Type *T) { + // Currently, only `class CountAttributedType` inherits + // `BoundsAttributedType` but the subclass will grow as we add more bounds + // annotations. + switch (T->getTypeClass()) { + case CountAttributed: + return true; + default: + return false; + } + } +}; + +/// Represents a sugar type with `__counted_by` or `__sized_by` annotations, +/// including their `_or_null` variants. +class CountAttributedType final + : public BoundsAttributedType, + public llvm::TrailingObjects<CountAttributedType, + TypeCoupledDeclRefInfo> { + friend class ASTContext; + + Expr *CountExpr; + /// \p CountExpr represents the argument of __counted_by or the likes. \p + /// CountInBytes indicates that \p CountExpr is a byte count (i.e., + /// __sized_by(_or_null)) \p OrNull means it's an or_null variant (i.e., + /// __counted_by_or_null or __sized_by_or_null) \p CoupledDecls contains the + /// list of declarations referenced by \p CountExpr, which the type depends on + /// for the bounds information. + CountAttributedType(QualType Wrapped, QualType Canon, Expr *CountExpr, + bool CountInBytes, bool OrNull, + ArrayRef<TypeCoupledDeclRefInfo> CoupledDecls); + + unsigned numTrailingObjects(OverloadToken<TypeCoupledDeclRefInfo>) const { + return CountAttributedTypeBits.NumCoupledDecls; + } + +public: + enum DynamicCountPointerKind { + CountedBy = 0, + SizedBy, + CountedByOrNull, + SizedByOrNull, + }; + + Expr *getCountExpr() const { return CountExpr; } + bool isCountInBytes() const { return CountAttributedTypeBits.CountInBytes; } + bool isOrNull() const { return CountAttributedTypeBits.OrNull; } + + DynamicCountPointerKind getKind() const { + if (isOrNull()) + return isCountInBytes() ? SizedByOrNull : CountedByOrNull; + return isCountInBytes() ? SizedBy : CountedBy; + } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, desugar(), CountExpr, isCountInBytes(), isOrNull()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, QualType WrappedTy, + Expr *CountExpr, bool CountInBytes, bool Nullable); + + static bool classof(const Type *T) { + return T->getTypeClass() == CountAttributed; + } +}; + /// Represents a type which was implicitly adjusted by the semantic /// engine for arbitrary reasons. For example, array and function types can /// decay, and function types can have their calling conventions adjusted. diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index 32028e877fc8..b09eb3539a4b 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -1120,6 +1120,32 @@ public: } }; +struct BoundsAttributedLocInfo {}; +class BoundsAttributedTypeLoc + : public ConcreteTypeLoc<UnqualTypeLoc, BoundsAttributedTypeLoc, + BoundsAttributedType, BoundsAttributedLocInfo> { +public: + TypeLoc getInnerLoc() const { return getInnerTypeLoc(); } + QualType getInnerType() const { return getTypePtr()->desugar(); } + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + // nothing to do + } + // LocalData is empty and TypeLocBuilder doesn't handle DataSize 1. + unsigned getLocalDataSize() const { return 0; } +}; + +class CountAttributedTypeLoc final + : public InheritingConcreteTypeLoc<BoundsAttributedTypeLoc, + CountAttributedTypeLoc, + CountAttributedType> { +public: + Expr *getCountExpr() const { return getTypePtr()->getCountExpr(); } + bool isCountInBytes() const { return getTypePtr()->isCountInBytes(); } + bool isOrNull() const { return getTypePtr()->isOrNull(); } + + SourceRange getLocalSourceRange() const; +}; + struct MacroQualifiedLocInfo { SourceLocation ExpansionLoc; }; diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index 0ba172a4035f..f3906cb7f86f 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -25,6 +25,25 @@ let Class = PointerType in { def : Creator<[{ return ctx.getPointerType(pointeeType); }]>; } +let Class = CountAttributedType in { + def : Property<"WrappedTy", QualType> { + let Read = [{ node->desugar() }]; + } + def : Property<"CountExpr", ExprRef> { + let Read = [{ node->getCountExpr() }]; + } + def : Property<"CountInBytes", Bool> { + let Read = [{ node->isCountInBytes() }]; + } + def : Property<"OrNull", Bool> { + let Read = [{ node->isOrNull() }]; + } + def : Property<"CoupledDecls", Array<TypeCoupledDeclRefInfo>> { + let Read = [{ node->getCoupledDecls() }]; + } + def : Creator<[{ return ctx.getCountAttributedType(WrappedTy, CountExpr, CountInBytes, OrNull, CoupledDecls); }]>; +} + let Class = AdjustedType in { def : Property<"originalType", QualType> { let Read = [{ node->getOriginalType() }]; diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 67d87eca16ed..3e03e5561264 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2193,6 +2193,15 @@ def TypeNullUnspecified : TypeAttr { let Documentation = [TypeNullUnspecifiedDocs]; } +def CountedBy : DeclOrTypeAttr { + let Spellings = [Clang<"counted_by">]; + let Subjects = SubjectList<[Field], ErrorDiag>; + let Args = [ExprArgument<"Count">, IntArgument<"NestedLevel">]; + let ParseArgumentsAsUnevaluated = 1; + let Documentation = [CountedByDocs]; + let LangOpts = [COnly]; +} + // This is a marker used to indicate that an __unsafe_unretained qualifier was // ignored because ARC is not enabled. The usual representation for this // qualifier is as an ObjCOwnership attribute with Kind == "none". @@ -4487,21 +4496,3 @@ def CodeAlign: StmtAttr { static constexpr int MaximumAlignment = 4096; }]; } - -def CountedBy : InheritableAttr { - let Spellings = [Clang<"counted_by">]; - let Subjects = SubjectList<[Field]>; - let Args = [IdentifierArgument<"CountedByField">]; - let Documentation = [CountedByDocs]; - let LangOpts = [COnly]; - // FIXME: This is ugly. Let using a DeclArgument would be nice, but a Decl - // isn't yet available due to the fact that we're still parsing the - // structure. Maybe that code could be changed sometime in the future. - code AdditionalMembers = [{ - private: - SourceRange CountedByFieldLoc; - public: - SourceRange getCountedByFieldLoc() const { return CountedByFieldLoc; } - void setCountedByFieldLoc(SourceRange Loc) { CountedByFieldLoc = Loc; } - }]; -} diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8e97902564af..2646942a53e3 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6519,12 +6519,18 @@ def err_flexible_array_count_not_in_same_struct : Error< "'counted_by' field %0 isn't within the same struct as the flexible array">; def err_counted_by_attr_not_on_flexible_array_member : Error< "'counted_by' only applies to C99 flexible array members">; -def err_counted_by_attr_refers_to_flexible_array : Error< - "'counted_by' cannot refer to the flexible array %0">; +def err_counted_by_attr_refer_to_itself : Error< + "'counted_by' cannot refer to the flexible array member %0">; def err_counted_by_must_be_in_structure : Error< "field %0 in 'counted_by' not inside structure">; -def err_flexible_array_counted_by_attr_field_not_integer : Error< - "field %0 in 'counted_by' must be a non-boolean integer type">; +def err_counted_by_attr_argument_not_integer : Error< + "'counted_by' requires a non-boolean integer type argument">; +def err_counted_by_attr_only_support_simple_decl_reference : Error< + "'counted_by' argument must be a simple declaration reference">; +def err_counted_by_attr_in_union : Error< + "'counted_by' cannot be applied to a union member">; +def err_counted_by_attr_refer_to_union : Error< + "'counted_by' argument cannot refer to a union member">; def note_flexible_array_counted_by_attr_field : Note< "field %0 declared here">; diff --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td index 641976241737..3625f0637589 100644 --- a/clang/include/clang/Basic/TypeNodes.td +++ b/clang/include/clang/Basic/TypeNodes.td @@ -108,6 +108,8 @@ def ObjCTypeParamType : TypeNode<Type>, NeverCanonical; def ObjCObjectType : TypeNode<Type>; def ObjCInterfaceType : TypeNode<ObjCObjectType>, LeafType; def ObjCObjectPointerType : TypeNode<Type>; +def BoundsAttributedType : TypeNode<Type, 1>; +def CountAttributedType : TypeNode<BoundsAttributedType>, NeverCanonical; def PipeType : TypeNode<Type>; def AtomicType : TypeNode<Type>; def BitIntType : TypeNode<Type>; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 64e031d5094c..bba8ef4ff017 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3073,6 +3073,11 @@ private: SourceLocation ScopeLoc, ParsedAttr::Form Form); + void ParseBoundsAttribute(IdentifierInfo &AttrName, + SourceLocation AttrNameLoc, ParsedAttributes &Attrs, + IdentifierInfo *ScopeName, SourceLocation ScopeLoc, + ParsedAttr::Form Form); + void ParseTypeofSpecifier(DeclSpec &DS); SourceLocation ParseDecltypeSpecifier(DeclSpec &DS); void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 95ea5ebc7f1a..5ecd2f9eb288 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3931,8 +3931,6 @@ public: bool BestCase, MSInheritanceModel Model); - bool CheckCountedByAttr(Scope *Scope, const FieldDecl *FD); - EnforceTCBAttr *mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL); EnforceTCBLeafAttr *mergeEnforceTCBLeafAttr(Decl *D, const EnforceTCBLeafAttr &AL); @@ -5245,6 +5243,7 @@ public: enum ExpressionKind { EK_Decltype, EK_TemplateArgument, + EK_BoundsAttrArgument, EK_Other } ExprContext; @@ -5362,6 +5361,12 @@ public: return ExprEvalContexts.back(); }; + bool isBoundsAttrContext() const { + return ExprEvalContexts.back().ExprContext == + ExpressionEvaluationContextRecord::ExpressionKind:: + EK_BoundsAttrArgument; + } + /// Increment when we find a reference; decrement when we find an ignored /// assignment. Ultimately the value is 0 if every reference is an ignored /// assignment. @@ -11747,6 +11752,8 @@ public: QualType BuildMatrixType(QualType T, Expr *NumRows, Expr *NumColumns, SourceLocation AttrLoc); + QualType BuildCountAttributedArrayType(QualType WrappedTy, Expr *CountExpr); + QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace, SourceLocation AttrLoc); diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h index 80a1359fd16a..5d3e95cb5d63 100644 --- a/clang/include/clang/Serialization/ASTRecordReader.h +++ b/clang/include/clang/Serialization/ASTRecordReader.h @@ -221,6 +221,8 @@ public: return Reader->ReadSelector(*F, Record, Idx); } + TypeCoupledDeclRefInfo readTypeCoupledDeclRefInfo(); + /// Read a declaration name, advancing Idx. // DeclarationName readDeclarationName(); (inherited) DeclarationNameLoc readDeclarationNameLoc(DeclarationName Name); diff --git a/clang/include/clang/Serialization/ASTRecordWriter.h b/clang/include/clang/Serialization/ASTRecordWriter.h index 9a64735c9fa5..e007d4a70843 100644 --- a/clang/include/clang/Serialization/ASTRecordWriter.h +++ b/clang/include/clang/Serialization/ASTRecordWriter.h @@ -141,6 +141,11 @@ public: AddSourceLocation(Loc); } + void writeTypeCoupledDeclRefInfo(TypeCoupledDeclRefInfo Info) { + writeDeclRef(Info.getDecl()); + writeBool(Info.isDeref()); + } + /// Emit a source range. void AddSourceRange(SourceRange Range, LocSeq *Seq = nullptr) { return Writer->AddSourceRange(Range, *Record, Seq); diff --git a/clang/include/clang/Serialization/TypeBitCodes.def b/clang/include/clang/Serialization/TypeBitCodes.def index adbd5ec5d4b5..3c82dfed9497 100644 --- a/clang/include/clang/Serialization/TypeBitCodes.def +++ b/clang/include/clang/Serialization/TypeBitCodes.def @@ -65,6 +65,6 @@ TYPE_BIT_CODE(DependentSizedMatrix, DEPENDENT_SIZE_MATRIX, 53) TYPE_BIT_CODE(Using, USING, 54) TYPE_BIT_CODE(BTFTagAttributed, BTFTAG_ATTRIBUTED, 55) TYPE_BIT_CODE(PackIndexing, PACK_INDEXING, 56) - +TYPE_BIT_CODE(CountAttributed, COUNT_ATTRIBUTED, 57) #undef TYPE_BIT_CODE diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 5a8fae76a43a..fcf801adeaf5 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2348,6 +2348,9 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { return getTypeInfo( cast<AttributedType>(T)->getEquivalentType().getTypePtr()); + case Type::CountAttributed: + return getTypeInfo(cast<CountAttributedType>(T)->desugar().getTypePtr()); + case Type::BTFTagAttributed: return getTypeInfo( cast<BTFTagAttributedType>(T)->getWrappedType().getTypePtr()); @@ -3122,6 +3125,32 @@ QualType ASTContext::removePtrSizeAddrSpace(QualType T) const { return T; } +QualType ASTContext::getCountAttributedType( + QualType WrappedTy, Expr *CountExpr, bool CountInBytes, bool OrNull, + ArrayRef<TypeCoupledDeclRefInfo> DependentDecls) const { + assert(WrappedTy->isPointerType() || WrappedTy->isArrayType()); + + llvm::FoldingSetNodeID ID; + CountAttributedType::Profile(ID, WrappedTy, CountExpr, CountInBytes, OrNull); + + void *InsertPos = nullptr; + CountAttributedType *CATy = + CountAttributedTypes.FindNodeOrInsertPos(ID, InsertPos); + if (CATy) + return QualType(CATy, 0); + + QualType CanonTy = getCanonicalType(WrappedTy); + size_t Size = CountAttributedType::totalSizeToAlloc<TypeCoupledDeclRefInfo>( + DependentDecls.size()); + CATy = (CountAttributedType *)Allocate(Size, TypeAlignment); + new (CATy) CountAttributedType(WrappedTy, CanonTy, CountExpr, CountInBytes, + OrNull, DependentDecls); + Types.push_back(CATy); + CountAttributedTypes.InsertNode(CATy, InsertPos); + + return QualType(CATy, 0); +} + const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T, FunctionType::ExtInfo Info) { if (T->getExtInfo() == Info) @@ -13234,6 +13263,32 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X, return QualType(); return Ctx.getUsingType(CD, Ctx.getQualifiedType(Underlying)); } + case Type::CountAttributed: { + const auto *DX = cast<CountAttributedType>(X), + *DY = cast<CountAttributedType>(Y); + if (DX->isCountInBytes() != DY->isCountInBytes()) + return QualType(); + if (DX->isOrNull() != DY->isOrNull()) + return QualType(); + Expr *CEX = DX->getCountExpr(); + Expr *CEY = DY->getCountExpr(); + llvm::ArrayRef<clang::TypeCoupledDeclRefInfo> CDX = DX->getCoupledDecls(); + if (Ctx.hasSameExpr(CEX, CEY)) + return Ctx.getCountAttributedType(Ctx.getQualifiedType(Underlying), CEX, + DX->isCountInBytes(), DX->isOrNull(), + CDX); + if (!CEX->isIntegerConstantExpr(Ctx) || !CEY->isIntegerConstantExpr(Ctx)) + return QualType(); + // Two declarations with the same integer constant may still differ in their + // expression pointers, so we need to evaluate them. + llvm::APSInt VX = *CEX->getIntegerConstantExpr(Ctx); + llvm::APSInt VY = *CEY->getIntegerConstantExpr(Ctx); + if (VX != VY) + return QualType(); + return Ctx.getCountAttributedType(Ctx.getQualifiedType(Underlying), CEX, + DX->isCountInBytes(), DX->isOrNull(), + CDX); + } } llvm_unreachable("Unhandled Type Class"); } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 023aaa7f0572..786695f00fad 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1527,6 +1527,28 @@ ExpectedType ASTNodeImporter::VisitAttributedType(const AttributedType *T) { *ToModifiedTypeOrErr, *ToEquivalentTypeOrErr); } +ExpectedType +ASTNodeImporter::VisitCountAttributedType(const CountAttributedType *T) { + ExpectedType ToWrappedTypeOrErr = import(T->desugar()); + if (!ToWrappedTypeOrErr) + return ToWrappedTypeOrErr.takeError(); + + Error Err = Error::success(); + Expr *CountExpr = importChecked(Err, T->getCountExpr()); + + SmallVector<TypeCoupledDeclRefInfo, 1> CoupledDecls; + for (auto TI : T->dependent_decls()) { + Expected<ValueDecl *> ToDeclOrErr = import(TI.getDecl()); + if (!ToDeclOrErr) + return ToDeclOrErr.takeError(); + CoupledDecls.emplace_back(*ToDeclOrErr, TI.isDeref()); + } + + return Importer.getToContext().getCountAttributedType( + *ToWrappedTypeOrErr, CountExpr, T->isCountInBytes(), T->isOrNull(), + ArrayRef(CoupledDecls.data(), CoupledDecls.size())); +} + ExpectedType ASTNodeImporter::VisitTemplateTypeParmType( const TemplateTypeParmType *T) { Expected<TemplateTypeParmDecl *> ToDeclOrErr = import(T->getDecl()); @@ -9305,16 +9327,6 @@ Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) { From->args_size()); break; } - case attr::CountedBy: { - AI.cloneAttr(FromAttr); - const auto *CBA = cast<CountedByAttr>(FromAttr); - Expected<SourceRange> SR = Import(CBA->getCountedByFieldLoc()).get(); - if (!SR) - return SR.takeError(); - AI.castAttrAs<CountedByAttr>()->setCountedByFieldLoc(SR.get()); - break; - } - default: { // The default branch works for attributes that have no arguments to import. // FIXME: Handle every attribute type that has arguments of type to import diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp index fe6e03ce174e..226e0aa38ece 100644 --- a/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -1069,6 +1069,13 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, return false; break; + case Type::CountAttributed: + if (!IsStructurallyEquivalent(Context, + cast<CountAttributedType>(T1)->desugar(), + cast<CountAttributedType>(T2)->desugar())) + return false; + break; + case Type::BTFTagAttributed: if (!IsStructurallyEquivalent( Context, cast<BTFTagAttributedType>(T1)->getWrappedType(), diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 1b6141580a81..f619d657ae9f 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2431,6 +2431,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, case Type::MacroQualified: case Type::BitInt: case Type::DependentBitInt: + case Type::CountAttributed: llvm_unreachable("type is illegal as a nested name specifier"); case Type::SubstTemplateTypeParmPack: diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 22666184c56c..c6fe90ba5e29 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -385,6 +385,26 @@ void DependentBitIntType::Profile(llvm::FoldingSetNodeID &ID, NumBitsExpr->Profile(ID, Context, true); } +bool BoundsAttributedType::referencesFieldDecls() const { + return llvm::any_of(dependent_decls(), + [](const TypeCoupledDeclRefInfo &Info) { + return isa<FieldDecl>(Info.getDecl()); + }); +} + +void CountAttributedType::Profile(llvm::FoldingSetNodeID &ID, + QualType WrappedTy, Expr *CountExpr, + bool CountInBytes, bool OrNull) { + ID.AddPointer(WrappedTy.getAsOpaquePtr()); + ID.AddBoolean(CountInBytes); + ID.AddBoolean(OrNull); + // We profile it as a pointer as the StmtProfiler considers parameter + // expressions on function declaration and function definition as the + // same, resulting in count expression being evaluated with ParamDecl + // not in the function scope. + ID.AddPointer(CountExpr); +} + /// getArrayElementTypeNoTypeQual - If this is an array type, return the /// element type of the array, potentially with type qualifiers missing. /// This method should never be used when type qualifiers are meaningful. @@ -559,6 +579,14 @@ template <> const AttributedType *Type::getAs() const { return getAsSugar<AttributedType>(this); } +template <> const BoundsAttributedType *Type::getAs() const { + return getAsSugar<BoundsAttributedType>(this); +} + +template <> const CountAttributedType *Type::getAs() const { + return getAsSugar<CountAttributedType>(this); +} + /// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic /// sugar off the given type. This should produce an object of the /// same dynamic type as the canonical type. @@ -641,6 +669,10 @@ bool Type::isScopedEnumeralType() const { return false; } +bool Type::isCountAttributedType() const { + return getAs<CountAttributedType>(); +} + const ComplexType *Type::getAsComplexIntegerType() const { if (const auto *Complex = getAs<ComplexType>()) if (Complex->getElementType()->isIntegerType()) @@ -3709,6 +3741,43 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, getExtProtoInfo(), Ctx, isCanonicalUnqualified()); } +TypeCoupledDeclRefInfo::TypeCoupledDeclRefInfo(ValueDecl *D, bool Deref) + : Data(D, Deref << DerefShift) {} + +bool TypeCoupledDeclRefInfo::isDeref() const { + return Data.getInt() & DerefMask; +} +ValueDecl *TypeCoupledDeclRefInfo::getDecl() const { return Data.getPointer(); } +unsigned TypeCoupledDeclRefInfo::getInt() const { return Data.getInt(); } +void *TypeCoupledDeclRefInfo::getOpaqueValue() const { + return Data.getOpaqueValue(); +} +bool TypeCoupledDeclRefInfo::operator==( + const TypeCoupledDeclRefInfo &Other) const { + return getOpaqueValue() == Other.getOpaqueValue(); +} +void TypeCoupledDeclRefInfo::setFromOpaqueValue(void *V) { + Data.setFromOpaqueValue(V); +} + +BoundsAttributedType::BoundsAttributedType(TypeClass TC, QualType Wrapped, + QualType Canon) + : Type(TC, Canon, Wrapped->getDependence()), WrappedTy(Wrapped) {} + +CountAttributedType::CountAttributedType( + QualType Wrapped, QualType Canon, Expr *CountExpr, bool CountInBytes, + bool OrNull, ArrayRef<TypeCoupledDeclRefInfo> CoupledDecls) + : BoundsAttributedType(CountAttributed, Wrapped, Canon), + CountExpr(CountExpr) { + CountAttributedTypeBits.NumCoupledDecls = CoupledDecls.size(); + CountAttributedTypeBits.CountInBytes = CountInBytes; + CountAttributedTypeBits.OrNull = OrNull; + auto *DeclSlot = getTrailingObjects<TypeCoupledDeclRefInfo>(); + Decls = llvm::ArrayRef(DeclSlot, CoupledDecls.size()); + for (unsigned i = 0; i != CoupledDecls.size(); ++i) + DeclSlot[i] = CoupledDecls[i]; +} + TypedefType::TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType Underlying, QualType can) : Type(tc, can, toSemanticDependence(can->getDependence())), diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index b0acb1823087..21e152f6aea8 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -516,6 +516,10 @@ SourceRange AttributedTypeLoc::getLocalSourceRange() const { return getAttr() ? getAttr()->getRange() : SourceRange(); } +SourceRange CountAttributedTypeLoc::getLocalSourceRange() const { + return getCountExpr() ? getCountExpr()->getSourceRange() : SourceRange(); +} + SourceRange BTFTagAttributedTypeLoc::getLocalSourceRange() const { return getAttr() ? getAttr()->getRange() : SourceRange(); } diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 2a3e32bc6995..7032ff2f1846 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -286,6 +286,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T, case Type::PackExpansion: case Type::SubstTemplateTypeParm: case Type::MacroQualified: + case Type::CountAttributed: CanPrefixQualifiers = false; break; @@ -1728,6 +1729,36 @@ void TypePrinter::printPackExpansionAfter(const PackExpansionType *T, OS << "..."; } +static void printCountAttributedImpl(const CountAttributedType *T, + raw_ostream &OS, + const PrintingPolicy &Policy) { + if (T->isCountInBytes() && T->isOrNull()) + OS << " __sized_by_or_null("; + else if (T->isCountInBytes()) + OS << " __sized_by("; + else if (T->isOrNull()) + OS << " __counted_by_or_null("; + else + OS << " __counted_by("; + if (T->getCountExpr()) + T->getCountExpr()->printPretty(OS, nullptr, Policy); + OS << ')'; +} + +void TypePrinter::printCountAttributedBefore(const CountAttributedType *T, + raw_ostream &OS) { + printBefore(T->desugar(), OS); + if (!T->desugar()->isArrayType()) + printCountAttributedImpl(T, OS, Policy); +} + +void TypePrinter::printCountAttributedAfter(const CountAttributedType *T, + raw_ostream &OS) { + printAfter(T->desugar(), OS); + if (T->desugar()->isArrayType()) + printCountAttributedImpl(T, OS, Policy); +} + void TypePrinter::printAttributedBefore(const AttributedType *T, raw_ostream &OS) { // FIXME: Generate this with TableGen. @@ -1858,6 +1889,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, // AttributedType nodes for them. break; + case attr::CountedBy: case attr::LifetimeBound: case attr::TypeNonNull: case attr::TypeNullable: diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index e89691ab7921..77cb269d43c5 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -858,7 +858,7 @@ static unsigned CountCountedByAttrs(const RecordDecl *RD) { for (const Decl *D : RD->decls()) { if (const auto *FD = dyn_cast<FieldDecl>(D); - FD && FD->hasAttr<CountedByAttr>()) { + FD && FD->getType()->isCountAttributedType()) { return ++Num; } @@ -956,7 +956,7 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, // }; // }; // - // We don't konw which 'count' to use in this scenario: + // We don't know which 'count' to use in this scenario: // // size_t get_size(struct union_of_fams *p) { // return __builtin_dynamic_object_size(p, 1); @@ -975,7 +975,7 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, FindFlexibleArrayMemberField(Ctx, OuterRD, FAMName, Offset); Offset = Ctx.toCharUnitsFromBits(Offset).getQuantity(); - if (!FAMDecl || !FAMDecl->hasAttr<CountedByAttr>()) + if (!FAMDecl || !FAMDecl->getType()->isCountAttributedType()) // No flexible array member found or it doesn't have the "counted_by" // attribute. return nullptr; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index c2c01439f2dc..07ecaa81c47d 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -3658,6 +3658,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) { case Type::TemplateSpecialization: return CreateType(cast<TemplateSpecializationType>(Ty), Unit); + case Type::CountAttributed: case Type::Auto: case Type::Attributed: case Type::BTFTagAttributed: diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 59a7fe892500..85f5d739cef4 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1136,38 +1136,19 @@ llvm::Value *CodeGenFunction::EmitCountedByFieldExpr( } const FieldDecl *CodeGenFunction::FindCountedByField(const FieldDecl *FD) { - if (!FD || !FD->hasAttr<CountedByAttr>()) + if (!FD) return nullptr; - const auto *CBA = FD->getAttr<CountedByAttr>(); - if (!CBA) + const auto *CAT = FD->getType()->getAs<CountAttributedType>(); + if (!CAT) return nullptr; - auto GetNonAnonStructOrUnion = - [](const RecordDecl *RD) -> const RecordDecl * { - while (RD && RD->isAnonymousStructOrUnion()) { - const auto *R = dyn_cast<RecordDecl>(RD->getDeclContext()); - if (!R) - return nullptr; - RD = R; - } - return RD; - }; - const RecordDecl *EnclosingRD = GetNonAnonStructOrUnion(FD->getParent()); - if (!EnclosingRD) - return nullptr; - - DeclarationName DName(CBA->getCountedByField()); - DeclContext::lookup_result Lookup = EnclosingRD->lookup(DName); - - if (Lookup.empty()) - return nullptr; - - const NamedDecl *ND = Lookup.front(); - if (const auto *IFD = dyn_cast<IndirectFieldDecl>(ND)) - ND = IFD->getAnonField(); + const auto *CountDRE = cast<DeclRefExpr>(CAT->getCountExpr()); + const auto *CountDecl = CountDRE->getDecl(); + if (const auto *IFD = dyn_cast<IndirectFieldDecl>(CountDecl)) + CountDecl = IFD->getAnonField(); - return dyn_cast<FieldDecl>(ND); + return dyn_cast<FieldDecl>(CountDecl); } void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base, @@ -4259,7 +4240,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, if (const auto *ME = dyn_cast<MemberExpr>(Array); ME && ME->isFlexibleArrayMemberLike(getContext(), StrictFlexArraysLevel) && - ME->getMemberDecl()->hasAttr<CountedByAttr>()) { + ME->getMemberDecl()->getType()->isCountAttributedType()) { const FieldDecl *FAMDecl = dyn_cast<FieldDecl>(ME->getMemberDecl()); if (const FieldDecl *CountFD = FindCountedByField(FAMDecl)) { if (std::optional<int64_t> Diff = diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 98bea8209cf3..fad26c43da3d 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2409,6 +2409,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { case Type::BTFTagAttributed: case Type::SubstTemplateTypeParm: case Type::MacroQualified: + case Type::CountAttributed: // Keep walking after single level desugaring. type = type.getSingleStepDesugaredType(getContext()); break; diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index dd179414a141..0aa14b051074 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -629,6 +629,10 @@ void Parser::ParseGNUAttributeArgs( ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc, Form); return; + } else if (AttrKind == ParsedAttr::AT_CountedBy) { + ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc, + Form); + return; } // These may refer to the function arguments, but need to be parsed early to @@ -3250,6 +3254,54 @@ void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs, } } +/// Bounds attributes (e.g., counted_by): +/// AttrName '(' expression ')' +void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName, + SourceLocation AttrNameLoc, + ParsedAttributes &Attrs, + IdentifierInfo *ScopeName, + SourceLocation ScopeLoc, + ParsedAttr::Form Form) { + assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); + + BalancedDelimiterTracker Parens(*this, tok::l_paren); + Parens.consumeOpen(); + + if (Tok.is(tok::r_paren)) { + Diag(Tok.getLocation(), diag::err_argument_required_after_attribute); + Parens.consumeClose(); + return; + } + + ArgsVector ArgExprs; + // Don't evaluate argument when the attribute is ignored. + using ExpressionKind = + Sema::ExpressionEvaluationContextRecord::ExpressionKind; + EnterExpressionEvaluationContext EC( + Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, nullptr, + ExpressionKind::EK_BoundsAttrArgument); + + ExprResult ArgExpr( + Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression())); + + if (ArgExpr.isInvalid()) { + Parens.skipToEnd(); + return; + } + + ArgExprs.push_back(ArgExpr.get()); + Parens.consumeClose(); + + ASTContext &Ctx = Actions.getASTContext(); + + ArgExprs.push_back(IntegerLiteral::Create( + Ctx, llvm::APInt(Ctx.getTypeSize(Ctx.getSizeType()), 0), + Ctx.getSizeType(), SourceLocation())); + + Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, Parens.getCloseLocation()), + ScopeName, ScopeLoc, ArgExprs.data(), ArgExprs.size(), Form); +} + ExprResult Parser::ParseExtIntegerArgument() { assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) && "Not an extended int type"); @@ -4679,6 +4731,39 @@ void Parser::ParseDeclarationSpecifiers( } } +static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, + Parser &P) { + + if (DS.getTypeSpecType() != DeclSpec::TST_struct) + return; + + auto *RD = dyn_cast<RecordDecl>(DS.getRepAsDecl()); + // We're only interested in unnamed, non-anonymous struct + if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion()) + return; + + for (auto *I : RD->decls()) { + auto *VD = dyn_cast<ValueDecl>(I); + if (!VD) + continue; + + auto *CAT = VD->getType()->getAs<CountAttributedType>(); + if (!CAT) + continue; + + for (const auto &DD : CAT->dependent_decls()) { + if (!RD->containsDecl(DD.getDecl())) { + P.Diag(VD->getBeginLoc(), + diag::err_flexible_array_count_not_in_same_struct) + << DD.getDecl(); + P.Diag(DD.getDecl()->getBeginLoc(), + diag::note_flexible_array_counted_by_attr_field) + << DD.getDecl(); + } + } + } +} + /// ParseStructDeclaration - Parse a struct declaration without the terminating /// semicolon. /// @@ -4759,6 +4844,11 @@ void Parser::ParseStructDeclaration( } else DeclaratorInfo.D.SetIdentifier(nullptr, Tok.getLocation()); + // Here, we now know that the unnamed struct is not an anonymous struct. + // Report an error if a counted_by attribute refers to a field in a + // different named struct. + DiagnoseCountAttributedTypeInUnnamedAnon(DS, *this); + if (TryConsumeToken(tok::colon)) { ExprResult Res(ParseConstantExpression()); if (Res.isInvalid()) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 5850cd0ab6b9..8ceb79555fb5 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2271,12 +2271,6 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { } ShadowingDecls.erase(ShadowI); } - - if (!getLangOpts().CPlusPlus && S->isClassScope()) { - if (auto *FD = dyn_cast<FieldDecl>(TmpD); - FD && FD->hasAttr<CountedByAttr>()) - CheckCountedByAttr(S, FD); - } } llvm::sort(DeclDiags, diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index ec00fdf3f88d..0a62c656d824 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -8556,133 +8556,114 @@ static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(ZeroCallUsedRegsAttr::Create(S.Context, Kind, AL)); } -static void handleCountedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!AL.isArgIdent(0)) { - S.Diag(AL.getLoc(), diag::err_attribute_argument_type) - << AL << AANT_ArgumentIdentifier; - return; +static const RecordDecl *GetEnclosingNamedOrTopAnonRecord(const FieldDecl *FD) { + const auto *RD = FD->getParent(); + // An unnamed struct is anonymous struct only if it's not instantiated. + // However, the struct may not be fully processed yet to determine + // whether it's anonymous or not. In that case, this function treats it as + // an anonymous struct and tries to find a named parent. + while (RD && (RD->isAnonymousStructOrUnion() || + (!RD->isCompleteDefinition() && RD->getName().empty()))) { + const auto *Parent = dyn_cast<RecordDecl>(RD->getParent()); + if (!Parent) + break; + RD = Parent; } - - IdentifierLoc *IL = AL.getArgAsIdent(0); - CountedByAttr *CBA = - ::new (S.Context) CountedByAttr(S.Context, AL, IL->Ident); - CBA->setCountedByFieldLoc(IL->Loc); - D->addAttr(CBA); + return RD; } -static const FieldDecl * -FindFieldInTopLevelOrAnonymousStruct(const RecordDecl *RD, - const IdentifierInfo *FieldName) { - for (const Decl *D : RD->decls()) { - if (const auto *FD = dyn_cast<FieldDecl>(D)) - if (FD->getName() == FieldName->getName()) - return FD; - - if (const auto *R = dyn_cast<RecordDecl>(D)) - if (const FieldDecl *FD = - FindFieldInTopLevelOrAnonymousStruct(R, FieldName)) - return FD; +static bool +CheckCountExpr(Sema &S, FieldDecl *FD, Expr *E, + llvm::SmallVectorImpl<TypeCoupledDeclRefInfo> &Decls) { + if (FD->getParent()->isUnion()) { + S.Diag(FD->getBeginLoc(), diag::err_counted_by_attr_in_union) + << FD->getSourceRange(); + return true; } - return nullptr; -} + if (!E->getType()->isIntegerType() || E->getType()->isBooleanType()) { + S.Diag(E->getBeginLoc(), diag::err_counted_by_attr_argument_not_integer) + << E->getSourceRange(); + return true; + } -bool Sema::CheckCountedByAttr(Scope *S, const FieldDecl *FD) { LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = LangOptions::StrictFlexArraysLevelKind::IncompleteOnly; - if (!Decl::isFlexibleArrayMemberLike(Context, FD, FD->getType(), + + if (!Decl::isFlexibleArrayMemberLike(S.getASTContext(), FD, FD->getType(), StrictFlexArraysLevel, true)) { // The "counted_by" attribute must be on a flexible array member. SourceRange SR = FD->getLocation(); - Diag(SR.getBegin(), diag::err_counted_by_attr_not_on_flexible_array_member) + S.Diag(SR.getBegin(), + diag::err_counted_by_attr_not_on_flexible_array_member) << SR; return true; } - const auto *CBA = FD->getAttr<CountedByAttr>(); - const IdentifierInfo *FieldName = CBA->getCountedByField(); - - auto GetNonAnonStructOrUnion = [](const RecordDecl *RD) { - while (RD && !RD->getDeclName()) - if (const auto *R = dyn_cast<RecordDecl>(RD->getDeclContext())) - RD = R; - else - break; - - return RD; - }; - - const RecordDecl *EnclosingRD = GetNonAnonStructOrUnion(FD->getParent()); - const FieldDecl *CountFD = - FindFieldInTopLevelOrAnonymousStruct(EnclosingRD, FieldName); + auto *DRE = dyn_cast<DeclRefExpr>(E); + if (!DRE) { + S.Diag(E->getBeginLoc(), + diag::err_counted_by_attr_only_support_simple_decl_reference) + << E->getSourceRange(); + return true; + } + auto *CountDecl = DRE->getDecl(); + FieldDecl *CountFD = dyn_cast<FieldDecl>(CountDecl); + if (auto *IFD = dyn_cast<IndirectFieldDecl>(CountDecl)) { + CountFD = IFD->getAnonField(); + } if (!CountFD) { - DeclarationNameInfo NameInfo(FieldName, - CBA->getCountedByFieldLoc().getBegin()); - LookupResult MemResult(*this, NameInfo, Sema::LookupMemberName); - LookupName(MemResult, S); - - if (!MemResult.empty()) { - SourceRange SR = CBA->getCountedByFieldLoc(); - Diag(SR.getBegin(), diag::err_flexible_array_count_not_in_same_struct) - << CBA->getCountedByField() << SR; - - if (auto *ND = MemResult.getAsSingle<NamedDecl>()) { - SR = ND->getLocation(); - Diag(SR.getBegin(), diag::note_flexible_array_counted_by_attr_field) - << ND << SR; - } + S.Diag(E->getBeginLoc(), diag::err_counted_by_must_be_in_structure) + << CountDecl << E->getSourceRange(); - return true; - } else { - // The "counted_by" field needs to exist in the struct. - LookupResult OrdResult(*this, NameInfo, Sema::LookupOrdinaryName); - LookupName(OrdResult, S); - - if (!OrdResult.empty()) { - SourceRange SR = FD->getLocation(); - Diag(SR.getBegin(), diag::err_counted_by_must_be_in_structure) - << FieldName << SR; - - if (auto *ND = OrdResult.getAsSingle<NamedDecl>()) { - SR = ND->getLocation(); - Diag(SR.getBegin(), diag::note_flexible_array_counted_by_attr_field) - << ND << SR; - } + S.Diag(CountDecl->getBeginLoc(), + diag::note_flexible_array_counted_by_attr_field) + << CountDecl << CountDecl->getSourceRange(); + return true; + } - return true; - } + if (FD->getParent() != CountFD->getParent()) { + if (CountFD->getParent()->isUnion()) { + S.Diag(CountFD->getBeginLoc(), diag::err_counted_by_attr_refer_to_union) + << CountFD->getSourceRange(); + return true; + } + // Whether CountRD is an anonymous struct is not determined at this + // point. Thus, an additional diagnostic in case it's not anonymous struct + // is done later in `Parser::ParseStructDeclaration`. + auto *RD = GetEnclosingNamedOrTopAnonRecord(FD); + auto *CountRD = GetEnclosingNamedOrTopAnonRecord(CountFD); + + if (RD != CountRD) { + S.Diag(E->getBeginLoc(), + diag::err_flexible_array_count_not_in_same_struct) + << CountFD << E->getSourceRange(); + S.Diag(CountFD->getBeginLoc(), + diag::note_flexible_array_counted_by_attr_field) + << CountFD << CountFD->getSourceRange(); + return true; } - - CXXScopeSpec SS; - DeclFilterCCC<FieldDecl> Filter(FieldName); - return DiagnoseEmptyLookup(S, SS, MemResult, Filter, nullptr, std::nullopt, - const_cast<DeclContext *>(FD->getDeclContext())); } - if (CountFD->hasAttr<CountedByAttr>()) { - // The "counted_by" field can't point to the flexible array member. - SourceRange SR = CBA->getCountedByFieldLoc(); - Diag(SR.getBegin(), diag::err_counted_by_attr_refers_to_flexible_array) - << CBA->getCountedByField() << SR; - return true; - } + Decls.push_back(TypeCoupledDeclRefInfo(CountFD, /*IsDref*/ false)); + return false; +} - if (!CountFD->getType()->isIntegerType() || - CountFD->getType()->isBooleanType()) { - // The "counted_by" field must have an integer type. - SourceRange SR = CBA->getCountedByFieldLoc(); - Diag(SR.getBegin(), - diag::err_flexible_array_counted_by_attr_field_not_integer) - << CBA->getCountedByField() << SR; +static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) { + auto *FD = dyn_cast<FieldDecl>(D); + assert(FD); - SR = CountFD->getLocation(); - Diag(SR.getBegin(), diag::note_flexible_array_counted_by_attr_field) - << CountFD << SR; - return true; - } + auto *CountExpr = AL.getArgAsExpr(0); + if (!CountExpr) + return; - return false; + llvm::SmallVector<TypeCoupledDeclRefInfo, 1> Decls; + if (CheckCountExpr(S, FD, CountExpr, Decls)) + return; + + QualType CAT = S.BuildCountAttributedArrayType(FD->getType(), CountExpr); + FD->setType(CAT); } static void handleFunctionReturnThunksAttr(Sema &S, Decl *D, @@ -9704,7 +9685,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, break; case ParsedAttr::AT_CountedBy: - handleCountedByAttr(S, D, AL); + handleCountedByAttrField(S, D, AL); break; // Microsoft attributes: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index db1bb70c2d69..5f03b9814282 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2737,6 +2737,24 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, IsAddressOfOperand, TemplateArgs); + // BoundsSafety: This specially handles arguments of bounds attributes + // appertains to a type of C struct field such that the name lookup + // within a struct finds the member name, which is not the case for other + // contexts in C. + if (isBoundsAttrContext() && !getLangOpts().CPlusPlus && S->isClassScope()) { + // See if this is reference to a field of struct. + LookupResult R(*this, NameInfo, LookupMemberName); + // LookupParsedName handles a name lookup from within anonymous struct. + if (LookupParsedName(R, S, &SS)) { + if (auto *VD = dyn_cast<ValueDecl>(R.getFoundDecl())) { + QualType type = VD->getType().getNonReferenceType(); + // This will eventually be translated into MemberExpr upon + // the use of instantiated struct fields. + return BuildDeclRefExpr(VD, type, VK_PRValue, NameLoc); + } + } + } + // Perform the required lookup. LookupResult R(*this, NameInfo, (Id.getKind() == UnqualifiedIdKind::IK_ImplicitSelfParam) @@ -2893,7 +2911,8 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, // to get this right here so that we don't end up making a // spuriously dependent expression if we're inside a dependent // instance method. - if (!R.empty() && (*R.begin())->isCXXClassMember()) { + if (getLangOpts().CPlusPlus && !R.empty() && + (*R.begin())->isCXXClassMember()) { bool MightBeImplicitMember; if (!IsAddressOfOperand) MightBeImplicitMember = true; @@ -3549,7 +3568,8 @@ ExprResult Sema::BuildDeclarationNameExpr( case Decl::Field: case Decl::IndirectField: case Decl::ObjCIvar: - assert(getLangOpts().CPlusPlus && "building reference to field in C?"); + assert((getLangOpts().CPlusPlus || isBoundsAttrContext()) && + "building reference to field in C?"); // These can't have reference type in well-formed programs, but // for internal consistency we do this anyway. @@ -4709,6 +4729,7 @@ static void captureVariablyModifiedType(ASTContext &Context, QualType T, case Type::BTFTagAttributed: case Type::SubstTemplateTypeParm: case Type::MacroQualified: + case Type::CountAttributed: // Keep walking after single level desugaring. T = T.getSingleStepDesugaredType(Context); break; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 9aaacaa0771f..7b14323b0674 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -6503,6 +6503,9 @@ namespace { void VisitAttributedTypeLoc(AttributedTypeLoc TL) { fillAttributedTypeLoc(TL, State); } + void VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) { + // nothing + } void VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { // nothing } @@ -9754,6 +9757,26 @@ QualType Sema::BuildTypeofExprType(Expr *E, TypeOfKind Kind) { return Context.getTypeOfExprType(E, Kind); } +static void +BuildTypeCoupledDecls(Expr *E, + llvm::SmallVectorImpl<TypeCoupledDeclRefInfo> &Decls) { + // Currently, 'counted_by' only allows direct DeclRefExpr to FieldDecl. + auto *CountDecl = cast<DeclRefExpr>(E)->getDecl(); + Decls.push_back(TypeCoupledDeclRefInfo(CountDecl, /*IsDref*/ false)); +} + +QualType Sema::BuildCountAttributedArrayType(QualType WrappedTy, + Expr *CountExpr) { + assert(WrappedTy->isIncompleteArrayType()); + + llvm::SmallVector<TypeCoupledDeclRefInfo, 1> Decls; + BuildTypeCoupledDecls(CountExpr, Decls); + /// When the resulting expression is invalid, we still create the AST using + /// the original count expression for the sake of AST dump. + return Context.getCountAttributedType( + WrappedTy, CountExpr, /*CountInBytes*/ false, /*OrNull*/ false, Decls); +} + /// getDecltypeForExpr - Given an expr, will return the decltype for /// that expression, according to the rules in C++11 /// [dcl.type.simple]p4 and C++11 [expr.lambda.prim]p18. diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index f2f7d7ab9c7c..80a10647ca5d 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7269,6 +7269,34 @@ QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB, }); } +template <typename Derived> +QualType TreeTransform<Derived>::TransformCountAttributedType( + TypeLocBuilder &TLB, CountAttributedTypeLoc TL) { + const CountAttributedType *OldTy = TL.getTypePtr(); + QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc()); + if (InnerTy.isNull()) + return QualType(); + + Expr *OldCount = TL.getCountExpr(); + Expr *NewCount = nullptr; + if (OldCount) { + ExprResult CountResult = getDerived().TransformExpr(OldCount); + if (CountResult.isInvalid()) + return QualType(); + NewCount = CountResult.get(); + } + + QualType Result = TL.getType(); + if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() || + OldCount != NewCount) { + // Currently, CountAttributedType can only wrap incomplete array types. + Result = SemaRef.BuildCountAttributedArrayType(InnerTy, NewCount); + } + + TLB.push<CountAttributedTypeLoc>(Result); + return Result; +} + template <typename Derived> QualType TreeTransform<Derived>::TransformBTFTagAttributedType( TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index ede9f6e93469..28e8d27fef08 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6995,6 +6995,10 @@ void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) { TL.setAttr(ReadAttr()); } +void TypeLocReader::VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) { + // Nothing to do +} + void TypeLocReader::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { // Nothing to do. } @@ -9116,6 +9120,10 @@ DeclarationNameInfo ASTRecordReader::readDeclarationNameInfo() { return NameInfo; } +TypeCoupledDeclRefInfo ASTRecordReader::readTypeCoupledDeclRefInfo() { + return TypeCoupledDeclRefInfo(readDeclAs<ValueDecl>(), readBool()); +} + void ASTRecordReader::readQualifierInfo(QualifierInfo &Info) { Info.QualifierLoc = readNestedNameSpecifierLoc(); unsigned NumTPLists = readInt(); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 3653d94c6e07..221409d011a3 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -514,6 +514,10 @@ void TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) { Record.AddAttr(TL.getAttr()); } +void TypeLocWriter::VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) { + // Nothing to do +} + void TypeLocWriter::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { // Nothing to do. } diff --git a/clang/test/Modules/bounds-safety-attributed-type.c b/clang/test/Modules/bounds-safety-attributed-type.c new file mode 100644 index 000000000000..0aa2f16b321c --- /dev/null +++ b/clang/test/Modules/bounds-safety-attributed-type.c @@ -0,0 +1,27 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -verify %s +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -ast-dump-all %s | FileCheck %s +// expected-no-diagnostics + +#pragma clang module build bounds_safety +module bounds_safety {} +#pragma clang module contents +#pragma clang module begin bounds_safety +struct Test { + int count; + int fam[] __attribute__((counted_by(count))); +}; +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module import bounds_safety + +struct Test *p; + +// CHECK: |-RecordDecl {{.*}}bounds_safety.map:4:1, line:7:1> line:4:8 imported in bounds_safety <undeserialized declarations> struct Test definition +// CHECK: | |-FieldDecl {{.*}} imported in bounds_safety referenced count 'int' +// CHECK: | `-FieldDecl {{.*}} imported in bounds_safety fam 'int[] __counted_by(count)':'int[]' + +// CHECK: |-ImportDecl {{.*}}bounds-safety-attributed-type.c:17:22> col:22 implicit bounds_safety +// CHECK: |-RecordDecl {{.*}} struct Test +// CHECK: `-VarDecl {{.*}} p 'struct Test *' diff --git a/clang/test/PCH/Inputs/bounds-safety-attributed-type.h b/clang/test/PCH/Inputs/bounds-safety-attributed-type.h new file mode 100644 index 000000000000..9bfd9615c2bf --- /dev/null +++ b/clang/test/PCH/Inputs/bounds-safety-attributed-type.h @@ -0,0 +1,4 @@ +struct Test { + int count; + int fam[] __attribute__((counted_by(count))); +}; diff --git a/clang/test/PCH/bounds-safety-attributed-type.c b/clang/test/PCH/bounds-safety-attributed-type.c new file mode 100644 index 000000000000..c2dc0272bbd6 --- /dev/null +++ b/clang/test/PCH/bounds-safety-attributed-type.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -include %S/Inputs/bounds-safety-attributed-type.h -fsyntax-only -verify %s + +// Test with pch. +// RUN: %clang_cc1 -emit-pch -o %t %S/Inputs/bounds-safety-attributed-type.h +// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s +// RUN: %clang_cc1 -include-pch %t -ast-print %s | FileCheck %s --check-prefix PRINT +// RUN: %clang_cc1 -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix DUMP +// expected-no-diagnostics + +// PRINT: struct Test { +// PRINT-NEXT: int count; +// PRINT-NEXT: int fam[] __counted_by(count); +// PRINT-NEXT: }; + +// DUMP: RecordDecl {{.*}} imported <undeserialized declarations> struct Test definition +// DUMP-NEXT: |-FieldDecl {{.*}} imported referenced count 'int' +// DUMP-NEXT: `-FieldDecl {{.*}} imported fam 'int[] __counted_by(count)':'int[]' diff --git a/clang/test/Sema/attr-counted-by.c b/clang/test/Sema/attr-counted-by.c index f14da9c77fa8..d5d4ebf55739 100644 --- a/clang/test/Sema/attr-counted-by.c +++ b/clang/test/Sema/attr-counted-by.c @@ -11,16 +11,64 @@ struct not_found { struct no_found_count_not_in_substruct { unsigned long flags; - unsigned char count; // expected-note {{field 'count' declared here}} + unsigned char count; // expected-note {{'count' declared here}} struct A { int dummy; int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the flexible array}} } a; }; +struct not_found_count_not_in_unnamed_substruct { + unsigned char count; // expected-note {{'count' declared here}} + struct { + int dummy; + int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the flexible array}} + } a; +}; + +struct not_found_count_not_in_unnamed_substruct_2 { + struct { + unsigned char count; // expected-note {{'count' declared here}} + }; + struct { + int dummy; + int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the flexible array}} + } a; +}; + +struct not_found_count_in_other_unnamed_substruct { + struct { + unsigned char count; + } a1; + + struct { + int dummy; + int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}} + }; +}; + +struct not_found_count_in_other_substruct { + struct _a1 { + unsigned char count; + } a1; + + struct { + int dummy; + int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}} + }; +}; + +struct not_found_count_in_other_substruct_2 { + struct _a2 { + unsigned char count; + } a2; + + int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}} +}; + struct not_found_suggest { - int bork; // expected-note {{'bork' declared here}} - struct bar *fam[] __counted_by(blork); // expected-error {{use of undeclared identifier 'blork'; did you mean 'bork'?}} + int bork; + struct bar *fam[] __counted_by(blork); // expected-error {{use of undeclared identifier 'blork'}} }; int global; // expected-note {{'global' declared here}} @@ -32,17 +80,17 @@ struct found_outside_of_struct { struct self_referrential { int bork; - struct bar *self[] __counted_by(self); // expected-error {{'counted_by' cannot refer to the flexible array 'self'}} + struct bar *self[] __counted_by(self); // expected-error {{use of undeclared identifier 'self'}} }; struct non_int_count { - double dbl_count; // expected-note {{field 'dbl_count' declared here}} - struct bar *fam[] __counted_by(dbl_count); // expected-error {{field 'dbl_count' in 'counted_by' must be a non-boolean integer type}} + double dbl_count; + struct bar *fam[] __counted_by(dbl_count); // expected-error {{'counted_by' requires a non-boolean integer type argument}} }; struct array_of_ints_count { - int integers[2]; // expected-note {{field 'integers' declared here}} - struct bar *fam[] __counted_by(integers); // expected-error {{field 'integers' in 'counted_by' must be a non-boolean integer type}} + int integers[2]; + struct bar *fam[] __counted_by(integers); // expected-error {{'counted_by' requires a non-boolean integer type argument}} }; struct not_a_fam { @@ -58,7 +106,7 @@ struct not_a_c99_fam { struct annotated_with_anon_struct { unsigned long flags; struct { - unsigned char count; // expected-note {{'count' declared here}} - int array[] __counted_by(crount); // expected-error {{use of undeclared identifier 'crount'; did you mean 'count'?}} + unsigned char count; + int array[] __counted_by(crount); // expected-error {{use of undeclared identifier 'crount'}} }; }; diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 418b152ba4a1..454ee1e42aed 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -1778,6 +1778,10 @@ bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) { return Visit(TL.getModifiedLoc()); } +bool CursorVisitor::VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) { + return Visit(TL.getInnerLoc()); +} + bool CursorVisitor::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { return Visit(TL.getWrappedLoc()); } -- GitLab From 4a026b5092d77426b70ab299447af4dbd5a012d9 Mon Sep 17 00:00:00 2001 From: Peter Rong <peterrong96@gmail.com> Date: Tue, 19 Mar 2024 21:44:08 -0700 Subject: [PATCH 183/307] [AMDGCN] Use ZExt when handling indices in insertment element (#85718) When i1 true is used as an index, SExt extends it to i32 -1. This would cause BitVector to overflow. The language manual have specified that the index shall be treated as an unsigned number, this patch fixes that. (https://llvm.org/docs/LangRef.html#insertelement-instruction) This patch fixes #85717 --------- Signed-off-by: Peter Rong <PeterRong96@gmail.com> --- .../Target/AMDGPU/AMDGPUCodeGenPrepare.cpp | 4 +- .../amdgpu-codegenprepare-break-large-phis.ll | 51 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp index f1cc4b524460..bddf3d958a1a 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp @@ -1749,7 +1749,7 @@ static bool isInterestingPHIIncomingValue(const Value *V) { // Non constant index/out of bounds index -> folding is unlikely. // The latter is more of a sanity check because canonical IR should just // have replaced those with poison. - if (!Idx || Idx->getSExtValue() >= FVT->getNumElements()) + if (!Idx || Idx->getZExtValue() >= FVT->getNumElements()) return false; const auto *VecSrc = IE->getOperand(0); @@ -1761,7 +1761,7 @@ static bool isInterestingPHIIncomingValue(const Value *V) { return false; CurVal = VecSrc; - EltsCovered.set(Idx->getSExtValue()); + EltsCovered.set(Idx->getZExtValue()); // All elements covered. if (EltsCovered.all()) diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-break-large-phis.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-break-large-phis.ll index 192bf7c24981..93b9aeac3cd3 100644 --- a/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-break-large-phis.ll +++ b/llvm/test/CodeGen/AMDGPU/amdgpu-codegenprepare-break-large-phis.ll @@ -1197,3 +1197,54 @@ reallyfinally: store <5 x double> %val, ptr %out, align 1 ret void } + +define amdgpu_kernel void @pr85718(i1 %Bool, ptr %Ptr, <4 x float> %Vec1, <4 x float> %Vec2) { +; OPT-LABEL: @pr85718( +; OPT-NEXT: BB0: +; OPT-NEXT: [[I:%.*]] = insertelement <4 x float> [[VEC1:%.*]], float 4.200000e+01, i1 true +; OPT-NEXT: br label [[BB1:%.*]] +; OPT: BB1: +; OPT-NEXT: [[TMP0:%.*]] = phi float [ [[LARGEPHI_EXTRACTSLICE0:%.*]], [[BB2:%.*]] ], [ [[LARGEPHI_EXTRACTSLICE1:%.*]], [[BB1]] ], [ 0.000000e+00, [[BB0:%.*]] ] +; OPT-NEXT: [[TMP1:%.*]] = phi float [ [[LARGEPHI_EXTRACTSLICE3:%.*]], [[BB2]] ], [ [[LARGEPHI_EXTRACTSLICE4:%.*]], [[BB1]] ], [ 0.000000e+00, [[BB0]] ] +; OPT-NEXT: [[TMP2:%.*]] = phi float [ [[LARGEPHI_EXTRACTSLICE6:%.*]], [[BB2]] ], [ [[LARGEPHI_EXTRACTSLICE7:%.*]], [[BB1]] ], [ 0.000000e+00, [[BB0]] ] +; OPT-NEXT: [[TMP3:%.*]] = phi float [ [[LARGEPHI_EXTRACTSLICE9:%.*]], [[BB2]] ], [ [[LARGEPHI_EXTRACTSLICE10:%.*]], [[BB1]] ], [ 0.000000e+00, [[BB0]] ] +; OPT-NEXT: [[LARGEPHI_INSERTSLICE0:%.*]] = insertelement <4 x float> poison, float [[TMP0]], i64 0 +; OPT-NEXT: [[LARGEPHI_INSERTSLICE1:%.*]] = insertelement <4 x float> [[LARGEPHI_INSERTSLICE0]], float [[TMP1]], i64 1 +; OPT-NEXT: [[LARGEPHI_INSERTSLICE2:%.*]] = insertelement <4 x float> [[LARGEPHI_INSERTSLICE1]], float [[TMP2]], i64 2 +; OPT-NEXT: [[LARGEPHI_INSERTSLICE3:%.*]] = insertelement <4 x float> [[LARGEPHI_INSERTSLICE2]], float [[TMP3]], i64 3 +; OPT-NEXT: store <4 x float> [[LARGEPHI_INSERTSLICE3]], ptr [[PTR:%.*]], align 128 +; OPT-NEXT: [[LARGEPHI_EXTRACTSLICE1]] = extractelement <4 x float> [[VEC2:%.*]], i64 0 +; OPT-NEXT: [[LARGEPHI_EXTRACTSLICE4]] = extractelement <4 x float> [[VEC2]], i64 1 +; OPT-NEXT: [[LARGEPHI_EXTRACTSLICE7]] = extractelement <4 x float> [[VEC2]], i64 2 +; OPT-NEXT: [[LARGEPHI_EXTRACTSLICE10]] = extractelement <4 x float> [[VEC2]], i64 3 +; OPT-NEXT: br i1 [[BOOL:%.*]], label [[BB1]], label [[BB2]] +; OPT: BB2: +; OPT-NEXT: [[LARGEPHI_EXTRACTSLICE0]] = extractelement <4 x float> [[I]], i64 0 +; OPT-NEXT: [[LARGEPHI_EXTRACTSLICE3]] = extractelement <4 x float> [[I]], i64 1 +; OPT-NEXT: [[LARGEPHI_EXTRACTSLICE6]] = extractelement <4 x float> [[I]], i64 2 +; OPT-NEXT: [[LARGEPHI_EXTRACTSLICE9]] = extractelement <4 x float> [[I]], i64 3 +; OPT-NEXT: br label [[BB1]] +; +; NOOPT-LABEL: @pr85718( +; NOOPT-NEXT: BB0: +; NOOPT-NEXT: [[I:%.*]] = insertelement <4 x float> [[VEC1:%.*]], float 4.200000e+01, i1 true +; NOOPT-NEXT: br label [[BB1:%.*]] +; NOOPT: BB1: +; NOOPT-NEXT: [[PHI:%.*]] = phi <4 x float> [ [[I]], [[BB2:%.*]] ], [ [[VEC2:%.*]], [[BB1]] ], [ zeroinitializer, [[BB0:%.*]] ] +; NOOPT-NEXT: store <4 x float> [[PHI]], ptr [[PTR:%.*]], align 128 +; NOOPT-NEXT: br i1 [[BOOL:%.*]], label [[BB1]], label [[BB2]] +; NOOPT: BB2: +; NOOPT-NEXT: br label [[BB1]] +; +BB0: + %I = insertelement <4 x float> %Vec1, float 4.200000e+01, i1 true + br label %BB1 + +BB1: ; preds = %BB0, %BB1, %BB2 + %PHI = phi <4 x float> [ %I, %BB2 ], [ %Vec2, %BB1 ], [ zeroinitializer, %BB0 ] + store <4 x float> %PHI, ptr %Ptr, align 128 + br i1 %Bool, label %BB1, label %BB2 + +BB2: ; preds = %BB1 + br label %BB1 +} -- GitLab From c2423024923bae9176eda6cd958217c83955150d Mon Sep 17 00:00:00 2001 From: Billy Zhu <billyzhu@modular.com> Date: Tue, 19 Mar 2024 22:49:50 -0700 Subject: [PATCH 184/307] [MLIR][LLVM] DI Recursive Type fix for recursion via scope of composites (#85850) Fixes this bug for the previous recursive DI type PR: https://github.com/llvm/llvm-project/pull/80251#issuecomment-2007254788. Drawing inspiration from how clang uses DIBuilder to build forward decls, this PR changes how placeholders are created & updated. Instead of requiring each recursive DIType to do in-place mutation, we simply ask for a temporary node as the placeholder, and run RAUW at the end when the concrete node is translated. This has the side effect of simplifying what's needed to add recursion support for a type. Now only one additional method needs to be created for exporting. Concretely, for this PR, `translateImpl` for DICompositeType is back to the state it was before the previous PR, and the only net addition for DICompositeType is `translateTemporaryImpl`. --------- Co-authored-by: Tobias Gysi <tobias.gysi@nextsilicon.com> --- mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 50 +++++++++++---------- mlir/lib/Target/LLVMIR/DebugTranslation.h | 24 ++++------ mlir/test/Target/LLVMIR/llvmir-debug.mlir | 20 +++++++++ 3 files changed, 54 insertions(+), 40 deletions(-) diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp index 1248de3db070..126a671a58e8 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -116,8 +116,20 @@ static DINodeT *getDistinctOrUnique(bool isDistinct, Ts &&...args) { return DINodeT::get(std::forward<Ts>(args)...); } +llvm::TempDICompositeType +DebugTranslation::translateTemporaryImpl(DICompositeTypeAttr attr) { + return llvm::DICompositeType::getTemporary( + llvmCtx, attr.getTag(), getMDStringOrNull(attr.getName()), nullptr, + attr.getLine(), nullptr, nullptr, attr.getSizeInBits(), + attr.getAlignInBits(), + /*OffsetInBits=*/0, + /*Flags=*/static_cast<llvm::DINode::DIFlags>(attr.getFlags()), + /*Elements=*/nullptr, /*RuntimeLang=*/0, + /*VTableHolder=*/nullptr); +} + llvm::DICompositeType * -DebugTranslation::translateImplGetPlaceholder(DICompositeTypeAttr attr) { +DebugTranslation::translateImpl(DICompositeTypeAttr attr) { // TODO: Use distinct attributes to model this, once they have landed. // Depending on the tag, composite types must be distinct. bool isDistinct = false; @@ -129,8 +141,10 @@ DebugTranslation::translateImplGetPlaceholder(DICompositeTypeAttr attr) { isDistinct = true; } - llvm::TempMDTuple placeholderElements = - llvm::MDNode::getTemporary(llvmCtx, std::nullopt); + SmallVector<llvm::Metadata *> elements; + for (DINodeAttr member : attr.getElements()) + elements.push_back(translate(member)); + return getDistinctOrUnique<llvm::DICompositeType>( isDistinct, llvmCtx, attr.getTag(), getMDStringOrNull(attr.getName()), translate(attr.getFile()), attr.getLine(), translate(attr.getScope()), @@ -138,23 +152,8 @@ DebugTranslation::translateImplGetPlaceholder(DICompositeTypeAttr attr) { attr.getAlignInBits(), /*OffsetInBits=*/0, /*Flags=*/static_cast<llvm::DINode::DIFlags>(attr.getFlags()), - /*Elements=*/placeholderElements.get(), /*RuntimeLang=*/0, - /*VTableHolder=*/nullptr); -} - -void DebugTranslation::translateImplFillPlaceholder( - DICompositeTypeAttr attr, llvm::DICompositeType *placeholder) { - SmallVector<llvm::Metadata *> elements; - for (DINodeAttr member : attr.getElements()) - elements.push_back(translate(member)); - placeholder->replaceElements(llvm::MDNode::get(llvmCtx, elements)); -} - -llvm::DICompositeType * -DebugTranslation::translateImpl(DICompositeTypeAttr attr) { - llvm::DICompositeType *placeholder = translateImplGetPlaceholder(attr); - translateImplFillPlaceholder(attr, placeholder); - return placeholder; + llvm::MDNode::get(llvmCtx, elements), + /*RuntimeLang=*/0, /*VTableHolder=*/nullptr); } llvm::DIDerivedType *DebugTranslation::translateImpl(DIDerivedTypeAttr attr) { @@ -234,10 +233,13 @@ DebugTranslation::translateRecursive(DIRecursiveTypeAttrInterface attr) { llvm::DIType *result = TypeSwitch<DIRecursiveTypeAttrInterface, llvm::DIType *>(attr) .Case<DICompositeTypeAttr>([&](auto attr) { - auto *placeholder = translateImplGetPlaceholder(attr); - setRecursivePlaceholder(placeholder); - translateImplFillPlaceholder(attr, placeholder); - return placeholder; + auto temporary = translateTemporaryImpl(attr); + setRecursivePlaceholder(temporary.get()); + // Must call `translateImpl` directly instead of `translate` to + // avoid handling the recursive interface again. + auto *concrete = translateImpl(attr); + temporary->replaceAllUsesWith(concrete); + return concrete; }); assert(recursiveTypeMap.back().first == recursiveId && diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h index d2171fed8c59..c7a5228cbf5e 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.h +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h @@ -88,23 +88,16 @@ private: llvm::DISubroutineType *translateImpl(DISubroutineTypeAttr attr); llvm::DIType *translateImpl(DITypeAttr attr); - /// Attributes that support self recursion need to implement two methods and - /// hook into the `translateImpl` overload for `DIRecursiveTypeAttr`. - /// - `<llvm type> translateImplGetPlaceholder(<mlir type>)`: - /// Translate the DI attr without translating any potentially recursive - /// nested DI attrs. - /// - `void translateImplFillPlaceholder(<mlir type>, <llvm type>)`: - /// Given the placeholder returned by `translateImplGetPlaceholder`, fill - /// any holes by recursively translating nested DI attrs. This method must - /// mutate the placeholder that is passed in, instead of creating a new one. + /// Attributes that support self recursion need to implement an additional + /// method to hook into `translateRecursive`. + /// - `<temp llvm type> translateTemporaryImpl(<mlir type>)`: + /// Create a temporary translation of the DI attr without recursively + /// translating any nested DI attrs. llvm::DIType *translateRecursive(DIRecursiveTypeAttrInterface attr); - /// Get a placeholder DICompositeType without recursing into the elements. - llvm::DICompositeType *translateImplGetPlaceholder(DICompositeTypeAttr attr); - /// Completes the DICompositeType `placeholder` by recursively translating the - /// elements. - void translateImplFillPlaceholder(DICompositeTypeAttr attr, - llvm::DICompositeType *placeholder); + /// Translate the given attribute to a temporary llvm debug metadata of the + /// corresponding type. + llvm::TempDICompositeType translateTemporaryImpl(DICompositeTypeAttr attr); /// Constructs a string metadata node from the string attribute. Returns /// nullptr if `stringAttr` is null or contains and empty string. @@ -121,7 +114,6 @@ private: DenseMap<Attribute, llvm::DINode *> attrToNode; /// A mapping between recursive ID and the translated DIType. - /// DIType. llvm::MapVector<DistinctAttr, llvm::DIType *> recursiveTypeMap; /// A mapping between a distinct ID and the translated LLVM metadata node. diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir index 5d70bff52bb2..c042628334d4 100644 --- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir @@ -402,3 +402,23 @@ llvm.func @func_debug_directives() { llvm.func @class_method() { llvm.return loc(#loc3) } loc(#loc3) + +// ----- + +// Ensures composite types with a recursive scope work. + +#di_composite_type_self = #llvm.di_composite_type<tag = DW_TAG_null, recId = distinct[0]<>> +#di_file = #llvm.di_file<"test.mlir" in "/"> +#di_subroutine_type = #llvm.di_subroutine_type<types = #di_composite_type_self> +#di_subprogram = #llvm.di_subprogram<scope = #di_file, file = #di_file, subprogramFlags = Optimized, type = #di_subroutine_type> +#di_composite_type = #llvm.di_composite_type<tag = DW_TAG_class_type, recId = distinct[0]<>, scope = #di_subprogram> +#di_global_variable = #llvm.di_global_variable<file = #di_file, line = 1, type = #di_composite_type> +#di_global_variable_expression = #llvm.di_global_variable_expression<var = #di_global_variable> + +llvm.mlir.global @global_variable() {dbg_expr = #di_global_variable_expression} : !llvm.struct<()> + +// CHECK: distinct !DIGlobalVariable({{.*}}type: ![[COMP:[0-9]+]], +// CHECK: ![[COMP]] = distinct !DICompositeType({{.*}}scope: ![[SCOPE:[0-9]+]], +// CHECK: ![[SCOPE]] = !DISubprogram({{.*}}type: ![[SUBROUTINE:[0-9]+]], +// CHECK: ![[SUBROUTINE]] = !DISubroutineType(types: ![[SR_TYPES:[0-9]+]]) +// CHECK: ![[SR_TYPES]] = !{![[COMP]]} -- GitLab From 6960ace534c4021301dd5a9933ca06ba96edea23 Mon Sep 17 00:00:00 2001 From: Noah Goldstein <goldstein.w.n@gmail.com> Date: Tue, 19 Mar 2024 23:26:51 -0500 Subject: [PATCH 185/307] Revert "[InstCombine] Canonicalize `(sitofp x)` -> `(uitofp x)` if `x >= 0`" This reverts commit d80d5b923c6f611590a12543bdb33e0c16044d44. It wasn't a particularly important transform to begin with and caused some codegen regressions on targets that prefer `sitofp` so dropping. Might re-visit along with adding `nneg` flag to `uitofp` so its easily reversable for the backend. --- clang/test/Headers/__clang_hip_math.hip | 24 ++++---- .../InstCombine/InstCombineCasts.cpp | 6 +- .../test/Transforms/InstCombine/add-sitofp.ll | 10 ++-- .../Transforms/InstCombine/binop-itofp.ll | 28 +++++----- .../Transforms/InstCombine/clamp-to-minmax.ll | 6 +- llvm/test/Transforms/InstCombine/fpcast.ll | 12 ++-- .../Transforms/InstCombine/minmax-fold.ll | 10 ++-- llvm/test/Transforms/InstCombine/minmax-fp.ll | 2 +- llvm/test/Transforms/InstCombine/pr27236.ll | 2 +- .../LoopVectorize/X86/float-induction-x86.ll | 6 +- .../LoopVectorize/float-induction.ll | 56 +++++++++---------- 11 files changed, 79 insertions(+), 83 deletions(-) diff --git a/clang/test/Headers/__clang_hip_math.hip b/clang/test/Headers/__clang_hip_math.hip index 701f93853ab9..37099de74fb8 100644 --- a/clang/test/Headers/__clang_hip_math.hip +++ b/clang/test/Headers/__clang_hip_math.hip @@ -1685,7 +1685,7 @@ extern "C" __device__ double test_j1(double x) { // DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float +// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float // DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]] // DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]] // DEFAULT-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]] @@ -1718,7 +1718,7 @@ extern "C" __device__ double test_j1(double x) { // FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float +// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float // FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract float [[CONV_I]], [[Y]] // FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract float [[__X1_0_I3]], [[DIV_I]] // FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract float [[MUL8_I]], [[__X0_0_I2]] @@ -1751,7 +1751,7 @@ extern "C" __device__ double test_j1(double x) { // APPROX-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// APPROX-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float +// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float // APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]] // APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]] // APPROX-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]] @@ -1788,7 +1788,7 @@ extern "C" __device__ float test_jnf(int x, float y) { // DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double +// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double // DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]] // DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]] // DEFAULT-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]] @@ -1821,7 +1821,7 @@ extern "C" __device__ float test_jnf(int x, float y) { // FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double +// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double // FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract double [[CONV_I]], [[Y]] // FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract double [[__X1_0_I3]], [[DIV_I]] // FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract double [[MUL8_I]], [[__X0_0_I2]] @@ -1854,7 +1854,7 @@ extern "C" __device__ float test_jnf(int x, float y) { // APPROX-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// APPROX-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double +// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double // APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]] // APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]] // APPROX-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]] @@ -4222,7 +4222,7 @@ extern "C" __device__ double test_y1(double x) { // DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float +// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float // DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]] // DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]] // DEFAULT-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]] @@ -4255,7 +4255,7 @@ extern "C" __device__ double test_y1(double x) { // FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float +// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float // FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract float [[CONV_I]], [[Y]] // FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract float [[__X1_0_I3]], [[DIV_I]] // FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract float [[MUL8_I]], [[__X0_0_I2]] @@ -4288,7 +4288,7 @@ extern "C" __device__ double test_y1(double x) { // APPROX-NEXT: [[__X1_0_I3:%.*]] = phi float [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[__X0_0_I2:%.*]] = phi float [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// APPROX-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to float +// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to float // APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract float [[CONV_I]], [[Y]] // APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract float [[__X1_0_I3]], [[DIV_I]] // APPROX-NEXT: [[SUB_I]] = fsub contract float [[MUL8_I]], [[__X0_0_I2]] @@ -4325,7 +4325,7 @@ extern "C" __device__ float test_ynf(int x, float y) { // DEFAULT-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // DEFAULT-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// DEFAULT-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double +// DEFAULT-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double // DEFAULT-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]] // DEFAULT-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]] // DEFAULT-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]] @@ -4358,7 +4358,7 @@ extern "C" __device__ float test_ynf(int x, float y) { // FINITEONLY-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // FINITEONLY-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// FINITEONLY-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double +// FINITEONLY-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double // FINITEONLY-NEXT: [[DIV_I:%.*]] = fdiv nnan ninf contract double [[CONV_I]], [[Y]] // FINITEONLY-NEXT: [[MUL8_I:%.*]] = fmul nnan ninf contract double [[__X1_0_I3]], [[DIV_I]] // FINITEONLY-NEXT: [[SUB_I]] = fsub nnan ninf contract double [[MUL8_I]], [[__X0_0_I2]] @@ -4391,7 +4391,7 @@ extern "C" __device__ float test_ynf(int x, float y) { // APPROX-NEXT: [[__X1_0_I3:%.*]] = phi double [ [[SUB_I:%.*]], [[FOR_BODY_I]] ], [ [[CALL_I21_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[__X0_0_I2:%.*]] = phi double [ [[__X1_0_I3]], [[FOR_BODY_I]] ], [ [[CALL_I_I]], [[IF_END4_I]] ] // APPROX-NEXT: [[MUL_I:%.*]] = shl nuw nsw i32 [[__I_0_I4]], 1 -// APPROX-NEXT: [[CONV_I:%.*]] = uitofp i32 [[MUL_I]] to double +// APPROX-NEXT: [[CONV_I:%.*]] = sitofp i32 [[MUL_I]] to double // APPROX-NEXT: [[DIV_I:%.*]] = fdiv contract double [[CONV_I]], [[Y]] // APPROX-NEXT: [[MUL8_I:%.*]] = fmul contract double [[__X1_0_I3]], [[DIV_I]] // APPROX-NEXT: [[SUB_I]] = fsub contract double [[MUL8_I]], [[__X0_0_I2]] diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index b19da1e07581..089a70c6e6cc 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1961,11 +1961,7 @@ Instruction *InstCombinerImpl::visitUIToFP(CastInst &CI) { } Instruction *InstCombinerImpl::visitSIToFP(CastInst &CI) { - if (Instruction *R = commonCastTransforms(CI)) - return R; - if (isKnownNonNegative(CI.getOperand(0), SQ)) - return new UIToFPInst(CI.getOperand(0), CI.getType()); - return nullptr; + return commonCastTransforms(CI); } Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) { diff --git a/llvm/test/Transforms/InstCombine/add-sitofp.ll b/llvm/test/Transforms/InstCombine/add-sitofp.ll index 861525f424fb..2bdc808d9771 100644 --- a/llvm/test/Transforms/InstCombine/add-sitofp.ll +++ b/llvm/test/Transforms/InstCombine/add-sitofp.ll @@ -33,7 +33,7 @@ define double @test(i32 %a) { define float @test_neg(i32 %a) { ; CHECK-LABEL: @test_neg( ; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823 -; CHECK-NEXT: [[A_AND_FP:%.*]] = uitofp i32 [[A_AND]] to float +; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp i32 [[A_AND]] to float ; CHECK-NEXT: [[RES:%.*]] = fadd float [[A_AND_FP]], 1.000000e+00 ; CHECK-NEXT: ret float [[RES]] ; @@ -67,8 +67,8 @@ define float @test_2_neg(i32 %a, i32 %b) { ; CHECK-LABEL: @test_2_neg( ; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823 ; CHECK-NEXT: [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823 -; CHECK-NEXT: [[A_AND_FP:%.*]] = uitofp i32 [[A_AND]] to float -; CHECK-NEXT: [[B_AND_FP:%.*]] = uitofp i32 [[B_AND]] to float +; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp i32 [[A_AND]] to float +; CHECK-NEXT: [[B_AND_FP:%.*]] = sitofp i32 [[B_AND]] to float ; CHECK-NEXT: [[RES:%.*]] = fadd float [[A_AND_FP]], [[B_AND_FP]] ; CHECK-NEXT: ret float [[RES]] ; @@ -122,8 +122,8 @@ define <4 x float> @test_4_neg(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: @test_4_neg( ; CHECK-NEXT: [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823> ; CHECK-NEXT: [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823> -; CHECK-NEXT: [[A_AND_FP:%.*]] = uitofp <4 x i32> [[A_AND]] to <4 x float> -; CHECK-NEXT: [[B_AND_FP:%.*]] = uitofp <4 x i32> [[B_AND]] to <4 x float> +; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp <4 x i32> [[A_AND]] to <4 x float> +; CHECK-NEXT: [[B_AND_FP:%.*]] = sitofp <4 x i32> [[B_AND]] to <4 x float> ; CHECK-NEXT: [[RES:%.*]] = fadd <4 x float> [[A_AND_FP]], [[B_AND_FP]] ; CHECK-NEXT: ret <4 x float> [[RES]] ; diff --git a/llvm/test/Transforms/InstCombine/binop-itofp.ll b/llvm/test/Transforms/InstCombine/binop-itofp.ll index c72e4ac413a3..82cdb3ce6bee 100644 --- a/llvm/test/Transforms/InstCombine/binop-itofp.ll +++ b/llvm/test/Transforms/InstCombine/binop-itofp.ll @@ -166,7 +166,7 @@ define half @test_si_si_i8_sub(i8 noundef %x_in, i8 noundef %y_in) { ; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63 ; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -64 ; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i8 [[X]], [[Y]] -; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half +; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[TMP1]] to half ; CHECK-NEXT: ret half [[R]] ; %x = and i8 %x_in, 63 @@ -181,7 +181,7 @@ define half @test_si_si_i8_sub_fail_overflow(i8 noundef %x_in, i8 noundef %y_in) ; CHECK-LABEL: @test_si_si_i8_sub_fail_overflow( ; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63 ; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -65 -; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half +; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half ; CHECK-NEXT: [[YF:%.*]] = sitofp i8 [[Y]] to half ; CHECK-NEXT: [[R:%.*]] = fsub half [[XF]], [[YF]] ; CHECK-NEXT: ret half [[R]] @@ -198,7 +198,7 @@ define half @test_si_si_i8_sub_C(i8 noundef %x_in) { ; CHECK-LABEL: @test_si_si_i8_sub_C( ; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63 ; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[X]], 64 -; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half +; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[TMP1]] to half ; CHECK-NEXT: ret half [[R]] ; %x = and i8 %x_in, 63 @@ -315,7 +315,7 @@ define half @test_si_si_i8_mul_fail_maybe_zero(i8 noundef %x_in, i8 noundef %y_i ; CHECK-LABEL: @test_si_si_i8_mul_fail_maybe_zero( ; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 7 ; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -8 -; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half +; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half ; CHECK-NEXT: [[YF:%.*]] = sitofp i8 [[Y]] to half ; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]] ; CHECK-NEXT: ret half [[R]] @@ -332,7 +332,7 @@ define half @test_si_si_i8_mul_C_fail_no_repr(i8 noundef %x_in) { ; CHECK-LABEL: @test_si_si_i8_mul_C_fail_no_repr( ; CHECK-NEXT: [[XX:%.*]] = and i8 [[X_IN:%.*]], 6 ; CHECK-NEXT: [[X:%.*]] = or disjoint i8 [[XX]], 1 -; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half +; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half ; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], 0xHC780 ; CHECK-NEXT: ret half [[R]] ; @@ -347,7 +347,7 @@ define half @test_si_si_i8_mul_C_fail_overflow(i8 noundef %x_in) { ; CHECK-LABEL: @test_si_si_i8_mul_C_fail_overflow( ; CHECK-NEXT: [[XX:%.*]] = and i8 [[X_IN:%.*]], 6 ; CHECK-NEXT: [[X:%.*]] = or disjoint i8 [[XX]], 1 -; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half +; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half ; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], 0xHCCC0 ; CHECK-NEXT: ret half [[R]] ; @@ -401,7 +401,7 @@ define half @test_ui_si_i8_mul_fail_signed(i8 noundef %x_in, i8 noundef %y_in) { ; CHECK-NEXT: [[XX:%.*]] = and i8 [[X_IN:%.*]], 7 ; CHECK-NEXT: [[X:%.*]] = add nuw nsw i8 [[XX]], 1 ; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -4 -; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half +; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half ; CHECK-NEXT: [[YF:%.*]] = uitofp i8 [[Y]] to half ; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]] ; CHECK-NEXT: ret half [[R]] @@ -541,7 +541,7 @@ define half @test_si_si_i16_sub_fail_no_promotion(i16 noundef %x_in, i16 noundef ; CHECK-LABEL: @test_si_si_i16_sub_fail_no_promotion( ; CHECK-NEXT: [[X:%.*]] = and i16 [[X_IN:%.*]], 2047 ; CHECK-NEXT: [[Y:%.*]] = or i16 [[Y_IN:%.*]], -2049 -; CHECK-NEXT: [[XF:%.*]] = uitofp i16 [[X]] to half +; CHECK-NEXT: [[XF:%.*]] = sitofp i16 [[X]] to half ; CHECK-NEXT: [[YF:%.*]] = sitofp i16 [[Y]] to half ; CHECK-NEXT: [[R:%.*]] = fsub half [[XF]], [[YF]] ; CHECK-NEXT: ret half [[R]] @@ -575,7 +575,7 @@ define half @test_ui_si_i16_sub_fail_maybe_signed(i16 noundef %x_in, i16 noundef ; CHECK-NEXT: [[X:%.*]] = or i16 [[X_IN:%.*]], -2048 ; CHECK-NEXT: [[Y:%.*]] = and i16 [[Y_IN:%.*]], 2047 ; CHECK-NEXT: [[XF:%.*]] = uitofp i16 [[X]] to half -; CHECK-NEXT: [[YF:%.*]] = uitofp i16 [[Y]] to half +; CHECK-NEXT: [[YF:%.*]] = sitofp i16 [[Y]] to half ; CHECK-NEXT: [[R:%.*]] = fsub half [[XF]], [[YF]] ; CHECK-NEXT: ret half [[R]] ; @@ -643,7 +643,7 @@ define half @test_si_si_i16_mul_fail_overflow(i16 noundef %x_in, i16 noundef %y_ ; CHECK-NEXT: [[XX:%.*]] = and i16 [[X_IN:%.*]], 126 ; CHECK-NEXT: [[X:%.*]] = or disjoint i16 [[XX]], 1 ; CHECK-NEXT: [[Y:%.*]] = or i16 [[Y_IN:%.*]], -257 -; CHECK-NEXT: [[XF:%.*]] = uitofp i16 [[X]] to half +; CHECK-NEXT: [[XF:%.*]] = sitofp i16 [[X]] to half ; CHECK-NEXT: [[YF:%.*]] = sitofp i16 [[Y]] to half ; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]] ; CHECK-NEXT: ret half [[R]] @@ -821,7 +821,7 @@ define half @test_si_si_i12_sub(i12 noundef %x_in, i12 noundef %y_in) { ; CHECK-NEXT: [[X:%.*]] = and i12 [[X_IN:%.*]], 1023 ; CHECK-NEXT: [[Y:%.*]] = or i12 [[Y_IN:%.*]], -1024 ; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i12 [[X]], [[Y]] -; CHECK-NEXT: [[R:%.*]] = uitofp i12 [[TMP1]] to half +; CHECK-NEXT: [[R:%.*]] = sitofp i12 [[TMP1]] to half ; CHECK-NEXT: ret half [[R]] ; %x = and i12 %x_in, 1023 @@ -915,7 +915,7 @@ define half @test_si_si_i12_mul_fail_overflow(i12 noundef %x_in, i12 noundef %y_ ; CHECK-NEXT: [[XX:%.*]] = and i12 [[X_IN:%.*]], 30 ; CHECK-NEXT: [[X:%.*]] = or disjoint i12 [[XX]], 1 ; CHECK-NEXT: [[Y:%.*]] = or i12 [[Y_IN:%.*]], -128 -; CHECK-NEXT: [[XF:%.*]] = uitofp i12 [[X]] to half +; CHECK-NEXT: [[XF:%.*]] = sitofp i12 [[X]] to half ; CHECK-NEXT: [[YF:%.*]] = sitofp i12 [[Y]] to half ; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]] ; CHECK-NEXT: ret half [[R]] @@ -933,7 +933,7 @@ define half @test_si_si_i12_mul_fail_maybe_non_zero(i12 noundef %x_in, i12 nound ; CHECK-LABEL: @test_si_si_i12_mul_fail_maybe_non_zero( ; CHECK-NEXT: [[X:%.*]] = and i12 [[X_IN:%.*]], 30 ; CHECK-NEXT: [[Y:%.*]] = or i12 [[Y_IN:%.*]], -128 -; CHECK-NEXT: [[XF:%.*]] = uitofp i12 [[X]] to half +; CHECK-NEXT: [[XF:%.*]] = sitofp i12 [[X]] to half ; CHECK-NEXT: [[YF:%.*]] = sitofp i12 [[Y]] to half ; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]] ; CHECK-NEXT: ret half [[R]] @@ -950,7 +950,7 @@ define half @test_si_si_i12_mul_C(i12 noundef %x_in) { ; CHECK-LABEL: @test_si_si_i12_mul_C( ; CHECK-NEXT: [[X:%.*]] = or i12 [[X_IN:%.*]], -64 ; CHECK-NEXT: [[TMP1:%.*]] = mul nsw i12 [[X]], -16 -; CHECK-NEXT: [[R:%.*]] = uitofp i12 [[TMP1]] to half +; CHECK-NEXT: [[R:%.*]] = sitofp i12 [[TMP1]] to half ; CHECK-NEXT: ret half [[R]] ; %x = or i12 %x_in, -64 diff --git a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll index 3f3939ea73bd..9da9eb36d381 100644 --- a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll +++ b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll @@ -504,7 +504,7 @@ define float @mixed_clamp_to_float_1(i32 %x) { ; CHECK-LABEL: @mixed_clamp_to_float_1( ; CHECK-NEXT: [[SI_MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255) ; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[SI_MIN]], i32 1) -; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[R1]] to float +; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[R1]] to float ; CHECK-NEXT: ret float [[R]] ; %si_min_cmp = icmp sgt i32 %x, 255 @@ -539,7 +539,7 @@ define float @mixed_clamp_to_float_2(i32 %x) { ; CHECK-LABEL: @mixed_clamp_to_float_2( ; CHECK-NEXT: [[SI_MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255) ; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[SI_MIN]], i32 1) -; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[R1]] to float +; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[R1]] to float ; CHECK-NEXT: ret float [[R]] ; %si_min_cmp = icmp sgt i32 %x, 255 @@ -572,7 +572,7 @@ define <2 x float> @mixed_clamp_to_float_vec(<2 x i32> %x) { ; CHECK-LABEL: @mixed_clamp_to_float_vec( ; CHECK-NEXT: [[SI_MIN:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 255, i32 255>) ; CHECK-NEXT: [[R1:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[SI_MIN]], <2 x i32> <i32 1, i32 1>) -; CHECK-NEXT: [[R:%.*]] = uitofp <2 x i32> [[R1]] to <2 x float> +; CHECK-NEXT: [[R:%.*]] = sitofp <2 x i32> [[R1]] to <2 x float> ; CHECK-NEXT: ret <2 x float> [[R]] ; %si_min_cmp = icmp sgt <2 x i32> %x, <i32 255, i32 255> diff --git a/llvm/test/Transforms/InstCombine/fpcast.ll b/llvm/test/Transforms/InstCombine/fpcast.ll index 1f0bfbc40ac1..32bfdb52bb5f 100644 --- a/llvm/test/Transforms/InstCombine/fpcast.ll +++ b/llvm/test/Transforms/InstCombine/fpcast.ll @@ -170,7 +170,7 @@ define half @sint_to_fptrunc(i32 %x) { define half @masked_sint_to_fptrunc1(i32 %x) { ; CHECK-LABEL: @masked_sint_to_fptrunc1( ; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215 -; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to half +; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to half ; CHECK-NEXT: ret half [[R]] ; %m = and i32 %x, 16777215 @@ -182,7 +182,7 @@ define half @masked_sint_to_fptrunc1(i32 %x) { define half @masked_sint_to_fptrunc2(i32 %x) { ; CHECK-LABEL: @masked_sint_to_fptrunc2( ; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8 -; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to half +; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to half ; CHECK-NEXT: ret half [[R]] ; %m = lshr i32 %x, 8 @@ -194,7 +194,7 @@ define half @masked_sint_to_fptrunc2(i32 %x) { define half @masked_sint_to_fptrunc3(i32 %x) { ; CHECK-LABEL: @masked_sint_to_fptrunc3( ; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7 -; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[M]] to float +; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[M]] to float ; CHECK-NEXT: [[R:%.*]] = fptrunc float [[F]] to half ; CHECK-NEXT: ret half [[R]] ; @@ -218,7 +218,7 @@ define double @sint_to_fpext(i32 %x) { define double @masked_sint_to_fpext1(i32 %x) { ; CHECK-LABEL: @masked_sint_to_fpext1( ; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215 -; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to double +; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to double ; CHECK-NEXT: ret double [[R]] ; %m = and i32 %x, 16777215 @@ -230,7 +230,7 @@ define double @masked_sint_to_fpext1(i32 %x) { define double @masked_sint_to_fpext2(i32 %x) { ; CHECK-LABEL: @masked_sint_to_fpext2( ; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8 -; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to double +; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to double ; CHECK-NEXT: ret double [[R]] ; %m = lshr i32 %x, 8 @@ -242,7 +242,7 @@ define double @masked_sint_to_fpext2(i32 %x) { define double @masked_sint_to_fpext3(i32 %x) { ; CHECK-LABEL: @masked_sint_to_fpext3( ; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7 -; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[M]] to float +; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[M]] to float ; CHECK-NEXT: [[R:%.*]] = fpext float [[F]] to double ; CHECK-NEXT: ret double [[R]] ; diff --git a/llvm/test/Transforms/InstCombine/minmax-fold.ll b/llvm/test/Transforms/InstCombine/minmax-fold.ll index fff4bc5943da..8391fe33eb9b 100644 --- a/llvm/test/Transforms/InstCombine/minmax-fold.ll +++ b/llvm/test/Transforms/InstCombine/minmax-fold.ll @@ -131,7 +131,7 @@ define i64 @t9(i32 %a) { define float @t10(i32 %x) { ; CHECK-LABEL: @t10( ; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 255) -; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[R1]] to float +; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[R1]] to float ; CHECK-NEXT: ret float [[R]] ; %f_x = sitofp i32 %x to float @@ -143,7 +143,7 @@ define float @t10(i32 %x) { define float @t11(i64 %x) { ; CHECK-LABEL: @t11( ; CHECK-NEXT: [[R1:%.*]] = call i64 @llvm.smax.i64(i64 [[X:%.*]], i64 255) -; CHECK-NEXT: [[R:%.*]] = uitofp i64 [[R1]] to float +; CHECK-NEXT: [[R:%.*]] = sitofp i64 [[R1]] to float ; CHECK-NEXT: ret float [[R]] ; %f_x = sitofp i64 %x to float @@ -526,7 +526,7 @@ falselabel: define double @PR31751_umin1(i32 %x) { ; CHECK-LABEL: @PR31751_umin1( ; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647) -; CHECK-NEXT: [[CONV:%.*]] = uitofp i32 [[SEL]] to double +; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double ; CHECK-NEXT: ret double [[CONV]] ; %cmp = icmp slt i32 %x, 0 @@ -538,7 +538,7 @@ define double @PR31751_umin1(i32 %x) { define double @PR31751_umin2(i32 %x) { ; CHECK-LABEL: @PR31751_umin2( ; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647) -; CHECK-NEXT: [[CONV:%.*]] = uitofp i32 [[SEL]] to double +; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double ; CHECK-NEXT: ret double [[CONV]] ; %cmp = icmp ult i32 %x, 2147483647 @@ -550,7 +550,7 @@ define double @PR31751_umin2(i32 %x) { define double @PR31751_umin3(i32 %x) { ; CHECK-LABEL: @PR31751_umin3( ; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647) -; CHECK-NEXT: [[CONV:%.*]] = uitofp i32 [[SEL]] to double +; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double ; CHECK-NEXT: ret double [[CONV]] ; %cmp = icmp ugt i32 %x, 2147483647 diff --git a/llvm/test/Transforms/InstCombine/minmax-fp.ll b/llvm/test/Transforms/InstCombine/minmax-fp.ll index 728950ddb40c..f89e8a18e634 100644 --- a/llvm/test/Transforms/InstCombine/minmax-fp.ll +++ b/llvm/test/Transforms/InstCombine/minmax-fp.ll @@ -257,7 +257,7 @@ define double @t16(i32 %x) { define double @t17(i32 %x) { ; CHECK-LABEL: @t17( ; CHECK-NEXT: [[SEL1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 2) -; CHECK-NEXT: [[SEL:%.*]] = uitofp i32 [[SEL1]] to double +; CHECK-NEXT: [[SEL:%.*]] = sitofp i32 [[SEL1]] to double ; CHECK-NEXT: ret double [[SEL]] ; %cmp = icmp sgt i32 %x, 2 diff --git a/llvm/test/Transforms/InstCombine/pr27236.ll b/llvm/test/Transforms/InstCombine/pr27236.ll index 7aad0a90281a..61ea344b1bdb 100644 --- a/llvm/test/Transforms/InstCombine/pr27236.ll +++ b/llvm/test/Transforms/InstCombine/pr27236.ll @@ -4,7 +4,7 @@ define float @test1(i32 %scale) { ; CHECK-LABEL: @test1( ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[SCALE:%.*]], i32 1) -; CHECK-NEXT: [[TMP2:%.*]] = uitofp i32 [[TMP1]] to float +; CHECK-NEXT: [[TMP2:%.*]] = sitofp i32 [[TMP1]] to float ; CHECK-NEXT: ret float [[TMP2]] ; %1 = icmp sgt i32 1, %scale diff --git a/llvm/test/Transforms/LoopVectorize/X86/float-induction-x86.ll b/llvm/test/Transforms/LoopVectorize/X86/float-induction-x86.ll index c81ca46039f8..c55e732c9014 100644 --- a/llvm/test/Transforms/LoopVectorize/X86/float-induction-x86.ll +++ b/llvm/test/Transforms/LoopVectorize/X86/float-induction-x86.ll @@ -25,7 +25,7 @@ define void @fp_iv_loop1(ptr noalias nocapture %A, i32 %N) #0 { ; AUTO_VEC-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]] ; AUTO_VEC: vector.ph: ; AUTO_VEC-NEXT: [[N_VEC:%.*]] = and i64 [[ZEXT]], 2147483616 -; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; AUTO_VEC-NEXT: [[TMP0:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01 ; AUTO_VEC-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP0]], 1.000000e+00 ; AUTO_VEC-NEXT: br label [[VECTOR_BODY:%.*]] @@ -201,7 +201,7 @@ define double @external_use_with_fast_math(ptr %a, i64 %n) { ; AUTO_VEC-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]] ; AUTO_VEC: vector.ph: ; AUTO_VEC-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775792 -; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to double +; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to double ; AUTO_VEC-NEXT: [[TMP0:%.*]] = fmul fast double [[DOTCAST]], 3.000000e+00 ; AUTO_VEC-NEXT: br label [[VECTOR_BODY:%.*]] ; AUTO_VEC: vector.body: @@ -366,7 +366,7 @@ define void @fadd_reassoc_FMF(ptr nocapture %p, i32 %N) { ; AUTO_VEC-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]] ; AUTO_VEC: vector.ph: ; AUTO_VEC-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 4294967264 -; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; AUTO_VEC-NEXT: [[TMP1:%.*]] = fmul reassoc float [[DOTCAST]], 4.200000e+01 ; AUTO_VEC-NEXT: [[IND_END:%.*]] = fadd reassoc float [[TMP1]], 1.000000e+00 ; AUTO_VEC-NEXT: br label [[VECTOR_BODY:%.*]] diff --git a/llvm/test/Transforms/LoopVectorize/float-induction.ll b/llvm/test/Transforms/LoopVectorize/float-induction.ll index 4dba183a44b9..caea114e3d44 100644 --- a/llvm/test/Transforms/LoopVectorize/float-induction.ll +++ b/llvm/test/Transforms/LoopVectorize/float-induction.ll @@ -29,7 +29,7 @@ define void @fp_iv_loop1_fast_FMF(float %init, ptr noalias nocapture %A, i32 %N) ; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL1: vector.ph: ; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483644 -; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL1-NEXT: [[TMP1:%.*]] = fmul fast float [[FPINC]], [[DOTCAST]] ; VEC4_INTERL1-NEXT: [[IND_END:%.*]] = fsub fast float [[INIT:%.*]], [[TMP1]] ; VEC4_INTERL1-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0 @@ -84,7 +84,7 @@ define void @fp_iv_loop1_fast_FMF(float %init, ptr noalias nocapture %A, i32 %N) ; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL2: vector.ph: ; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483640 -; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[FPINC]], [[DOTCAST]] ; VEC4_INTERL2-NEXT: [[IND_END:%.*]] = fsub fast float [[INIT:%.*]], [[TMP1]] ; VEC4_INTERL2-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0 @@ -142,7 +142,7 @@ define void @fp_iv_loop1_fast_FMF(float %init, ptr noalias nocapture %A, i32 %N) ; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC1_INTERL2: vector.ph: ; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646 -; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC1_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[FPINC]], [[DOTCAST]] ; VEC1_INTERL2-NEXT: [[IND_END:%.*]] = fsub fast float [[INIT:%.*]], [[TMP1]] ; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]] @@ -193,7 +193,7 @@ define void @fp_iv_loop1_fast_FMF(float %init, ptr noalias nocapture %A, i32 %N) ; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]] ; VEC2_INTERL1_PRED_STORE: vector.ph: ; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646 -; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP1:%.*]] = fmul fast float [[FPINC]], [[DOTCAST]] ; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END:%.*]] = fsub fast float [[INIT:%.*]], [[TMP1]] ; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x float> poison, float [[INIT]], i64 0 @@ -276,7 +276,7 @@ define void @fp_iv_loop1_reassoc_FMF(float %init, ptr noalias nocapture %A, i32 ; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL1: vector.ph: ; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483644 -; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL1-NEXT: [[TMP1:%.*]] = fmul reassoc float [[FPINC]], [[DOTCAST]] ; VEC4_INTERL1-NEXT: [[IND_END:%.*]] = fsub reassoc float [[INIT:%.*]], [[TMP1]] ; VEC4_INTERL1-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0 @@ -331,7 +331,7 @@ define void @fp_iv_loop1_reassoc_FMF(float %init, ptr noalias nocapture %A, i32 ; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL2: vector.ph: ; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483640 -; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL2-NEXT: [[TMP1:%.*]] = fmul reassoc float [[FPINC]], [[DOTCAST]] ; VEC4_INTERL2-NEXT: [[IND_END:%.*]] = fsub reassoc float [[INIT:%.*]], [[TMP1]] ; VEC4_INTERL2-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0 @@ -389,7 +389,7 @@ define void @fp_iv_loop1_reassoc_FMF(float %init, ptr noalias nocapture %A, i32 ; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC1_INTERL2: vector.ph: ; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646 -; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC1_INTERL2-NEXT: [[TMP1:%.*]] = fmul reassoc float [[FPINC]], [[DOTCAST]] ; VEC1_INTERL2-NEXT: [[IND_END:%.*]] = fsub reassoc float [[INIT:%.*]], [[TMP1]] ; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]] @@ -442,7 +442,7 @@ define void @fp_iv_loop1_reassoc_FMF(float %init, ptr noalias nocapture %A, i32 ; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]] ; VEC2_INTERL1_PRED_STORE: vector.ph: ; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646 -; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP1:%.*]] = fmul reassoc float [[FPINC]], [[DOTCAST]] ; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END:%.*]] = fsub reassoc float [[INIT:%.*]], [[TMP1]] ; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x float> poison, float [[INIT]], i64 0 @@ -526,7 +526,7 @@ define void @fp_iv_loop2(float %init, ptr noalias nocapture %A, i32 %N) #0 { ; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL1: vector.ph: ; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483644 -; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL1-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01 ; VEC4_INTERL1-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], [[INIT:%.*]] ; VEC4_INTERL1-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0 @@ -574,7 +574,7 @@ define void @fp_iv_loop2(float %init, ptr noalias nocapture %A, i32 %N) #0 { ; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL2: vector.ph: ; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483640 -; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01 ; VEC4_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], [[INIT:%.*]] ; VEC4_INTERL2-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0 @@ -625,7 +625,7 @@ define void @fp_iv_loop2(float %init, ptr noalias nocapture %A, i32 %N) #0 { ; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC1_INTERL2: vector.ph: ; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646 -; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC1_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01 ; VEC1_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], [[INIT:%.*]] ; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]] @@ -675,7 +675,7 @@ define void @fp_iv_loop2(float %init, ptr noalias nocapture %A, i32 %N) #0 { ; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]] ; VEC2_INTERL1_PRED_STORE: vector.ph: ; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646 -; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01 ; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], [[INIT:%.*]] ; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x float> poison, float [[INIT]], i64 0 @@ -758,10 +758,10 @@ define void @fp_iv_loop3(float %init, ptr noalias nocapture %A, ptr noalias noca ; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL1: vector.ph: ; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[TMP1]], 2147483644 -; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL1-NEXT: [[TMP2:%.*]] = fmul fast float [[DOTCAST]], -5.000000e-01 ; VEC4_INTERL1-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP2]], 0x3FB99999A0000000 -; VEC4_INTERL1-NEXT: [[DOTCAST2:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL1-NEXT: [[DOTCAST2:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL1-NEXT: [[TMP3:%.*]] = fmul fast float [[TMP0]], [[DOTCAST2]] ; VEC4_INTERL1-NEXT: [[IND_END3:%.*]] = fadd fast float [[TMP3]], [[INIT:%.*]] ; VEC4_INTERL1-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0 @@ -835,10 +835,10 @@ define void @fp_iv_loop3(float %init, ptr noalias nocapture %A, ptr noalias noca ; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL2: vector.ph: ; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP1]], 2147483640 -; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL2-NEXT: [[TMP2:%.*]] = fmul fast float [[DOTCAST]], -5.000000e-01 ; VEC4_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP2]], 0x3FB99999A0000000 -; VEC4_INTERL2-NEXT: [[DOTCAST2:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL2-NEXT: [[DOTCAST2:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL2-NEXT: [[TMP3:%.*]] = fmul fast float [[TMP0]], [[DOTCAST2]] ; VEC4_INTERL2-NEXT: [[IND_END3:%.*]] = fadd fast float [[TMP3]], [[INIT:%.*]] ; VEC4_INTERL2-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[INIT]], i64 0 @@ -922,10 +922,10 @@ define void @fp_iv_loop3(float %init, ptr noalias nocapture %A, ptr noalias noca ; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC1_INTERL2: vector.ph: ; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP1]], 2147483646 -; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC1_INTERL2-NEXT: [[TMP2:%.*]] = fmul fast float [[DOTCAST]], -5.000000e-01 ; VEC1_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP2]], 0x3FB99999A0000000 -; VEC1_INTERL2-NEXT: [[DOTCAST2:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC1_INTERL2-NEXT: [[DOTCAST2:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC1_INTERL2-NEXT: [[TMP3:%.*]] = fmul fast float [[TMP0]], [[DOTCAST2]] ; VEC1_INTERL2-NEXT: [[IND_END3:%.*]] = fadd fast float [[TMP3]], [[INIT:%.*]] ; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]] @@ -1000,10 +1000,10 @@ define void @fp_iv_loop3(float %init, ptr noalias nocapture %A, ptr noalias noca ; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]] ; VEC2_INTERL1_PRED_STORE: vector.ph: ; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[TMP1]], 2147483646 -; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP2:%.*]] = fmul fast float [[DOTCAST]], -5.000000e-01 ; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP2]], 0x3FB99999A0000000 -; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST2:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST2:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP3:%.*]] = fmul fast float [[TMP0]], [[DOTCAST2]] ; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END3:%.*]] = fadd fast float [[TMP3]], [[INIT:%.*]] ; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x float> poison, float [[INIT]], i64 0 @@ -1113,7 +1113,7 @@ define void @fp_iv_loop4(ptr noalias nocapture %A, i32 %N) { ; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL1: vector.ph: ; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483644 -; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL1-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01 ; VEC4_INTERL1-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], 1.000000e+00 ; VEC4_INTERL1-NEXT: br label [[VECTOR_BODY:%.*]] @@ -1158,7 +1158,7 @@ define void @fp_iv_loop4(ptr noalias nocapture %A, i32 %N) { ; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL2: vector.ph: ; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483640 -; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01 ; VEC4_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], 1.000000e+00 ; VEC4_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]] @@ -1206,7 +1206,7 @@ define void @fp_iv_loop4(ptr noalias nocapture %A, i32 %N) { ; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC1_INTERL2: vector.ph: ; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646 -; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC1_INTERL2-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01 ; VEC1_INTERL2-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], 1.000000e+00 ; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]] @@ -1256,7 +1256,7 @@ define void @fp_iv_loop4(ptr noalias nocapture %A, i32 %N) { ; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]] ; VEC2_INTERL1_PRED_STORE: vector.ph: ; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 2147483646 -; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC2_INTERL1_PRED_STORE-NEXT: [[TMP1:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01 ; VEC2_INTERL1_PRED_STORE-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP1]], 1.000000e+00 ; VEC2_INTERL1_PRED_STORE-NEXT: br label [[VECTOR_BODY:%.*]] @@ -1319,7 +1319,7 @@ define void @non_primary_iv_float_scalar(ptr %A, i64 %N) { ; VEC4_INTERL1-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL1: vector.ph: ; VEC4_INTERL1-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775804 -; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL1-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL1-NEXT: br label [[VECTOR_BODY:%.*]] ; VEC4_INTERL1: vector.body: ; VEC4_INTERL1-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE8:%.*]] ] @@ -1396,7 +1396,7 @@ define void @non_primary_iv_float_scalar(ptr %A, i64 %N) { ; VEC4_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC4_INTERL2: vector.ph: ; VEC4_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775800 -; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC4_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC4_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]] ; VEC4_INTERL2: vector.body: ; VEC4_INTERL2-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE17:%.*]] ] @@ -1512,7 +1512,7 @@ define void @non_primary_iv_float_scalar(ptr %A, i64 %N) { ; VEC1_INTERL2-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] ; VEC1_INTERL2: vector.ph: ; VEC1_INTERL2-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775806 -; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC1_INTERL2-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC1_INTERL2-NEXT: br label [[VECTOR_BODY:%.*]] ; VEC1_INTERL2: vector.body: ; VEC1_INTERL2-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE4:%.*]] ] @@ -1570,7 +1570,7 @@ define void @non_primary_iv_float_scalar(ptr %A, i64 %N) { ; VEC2_INTERL1_PRED_STORE-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]] ; VEC2_INTERL1_PRED_STORE: vector.ph: ; VEC2_INTERL1_PRED_STORE-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775806 -; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = uitofp i64 [[N_VEC]] to float +; VEC2_INTERL1_PRED_STORE-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float ; VEC2_INTERL1_PRED_STORE-NEXT: br label [[VECTOR_BODY:%.*]] ; VEC2_INTERL1_PRED_STORE: vector.body: ; VEC2_INTERL1_PRED_STORE-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE4:%.*]] ] -- GitLab From d7e28cd82bd3141093f96f7ce2e7b36f1b115fad Mon Sep 17 00:00:00 2001 From: YunQiang Su <syq@debian.org> Date: Wed, 20 Mar 2024 14:18:24 +0800 Subject: [PATCH 186/307] MIPS: Support -m(no-)unaligned-access for r6 (#85174) MIPSr6 ISA requires normal load/store instructions support misunaligned memory access, while it is not always do so by hardware. On some microarchitectures or some corner cases it may need support by OS. Don't confuse with pre-R6's lwl/lwr famlily: MIPSr6 doesn't support them, instead, r6 requires lw instruction support misunaligned memory access. So, if -mstrict-align is used for pre-R6, lwl/lwr won't be disabled. If -mstrict-align is used for r6 and the access is not well aligned, some lb/lh instructions will be used to replace lw. This is useful for OS kernels. To be back-compatible with GCC, -m(no-)unaligned-access are also added as Neg-Alias of -m(no-)strict-align. --- clang/include/clang/Driver/Options.td | 4 +- clang/lib/Driver/ToolChains/Arch/Mips.cpp | 9 +++ clang/test/Driver/mips-features.c | 26 +++++++ llvm/lib/Target/Mips/Mips.td | 4 ++ llvm/lib/Target/Mips/MipsISelLowering.cpp | 16 ++++- llvm/lib/Target/Mips/MipsSEISelLowering.cpp | 11 ++- llvm/lib/Target/Mips/MipsSubtarget.cpp | 2 +- llvm/lib/Target/Mips/MipsSubtarget.h | 7 +- llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll | 10 +-- .../CodeGen/Mips/no-unaligned-access-r6.ll | 69 +++++++++++++++++++ 10 files changed, 145 insertions(+), 13 deletions(-) create mode 100644 llvm/test/CodeGen/Mips/no-unaligned-access-r6.ll diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 29c226f4bd8d..9b5125ecfed8 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4704,9 +4704,9 @@ def mrvv_vector_bits_EQ : Joined<["-"], "mrvv-vector-bits=">, Group<m_Group>, " (RISC-V only)")>; def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_Group>, - HelpText<"Allow memory accesses to be unaligned (AArch32 only)">; + HelpText<"Allow memory accesses to be unaligned (AArch32/MIPSr6 only)">; def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group<m_Group>, - HelpText<"Force all memory accesses to be aligned (AArch32 only)">; + HelpText<"Force all memory accesses to be aligned (AArch32/MIPSr6 only)">; def munaligned_symbols : Flag<["-"], "munaligned-symbols">, Group<m_Group>, HelpText<"Expect external char-aligned symbols to be without ABI alignment (SystemZ only)">; def mno_unaligned_symbols : Flag<["-"], "mno-unaligned-symbols">, Group<m_Group>, diff --git a/clang/lib/Driver/ToolChains/Arch/Mips.cpp b/clang/lib/Driver/ToolChains/Arch/Mips.cpp index fe9d112b8800..74a8874a3ea2 100644 --- a/clang/lib/Driver/ToolChains/Arch/Mips.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Mips.cpp @@ -341,6 +341,15 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, "dspr2"); AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa, "msa"); + if (Arg *A = Args.getLastArg( + options::OPT_mstrict_align, options::OPT_mno_strict_align, + options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) { + if (A->getOption().matches(options::OPT_mstrict_align) || + A->getOption().matches(options::OPT_mno_unaligned_access)) + Features.push_back(Args.MakeArgString("+strict-align")); + else + Features.push_back(Args.MakeArgString("-strict-align")); + } // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32 // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and diff --git a/clang/test/Driver/mips-features.c b/clang/test/Driver/mips-features.c index fd06b1400c31..5e92dccaa02a 100644 --- a/clang/test/Driver/mips-features.c +++ b/clang/test/Driver/mips-features.c @@ -462,3 +462,29 @@ // RUN: -mrelax-pic-calls -mno-relax-pic-calls 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NO-RELAX-PIC-CALLS %s // CHECK-NO-RELAX-PIC-CALLS: "-mllvm" "-mips-jalr-reloc=0" +// +// -mno-unaligned-access +// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \ +// RUN: -munaligned-access -mno-strict-align \ +// RUN: -mno-unaligned-access 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-STRICT-ALIGN %s +// CHECK-STRICT-ALIGN: "-target-feature" "+strict-align" +// +// -munaligned-access +// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \ +// RUN: -mno-unaligned-access -mstrict-align \ +// RUN: -munaligned-access 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NO-STRICT-ALIGN %s +// CHECK-NO-STRICT-ALIGN: "-target-feature" "-strict-align" +// +// -mstrict-align +// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \ +// RUN: -munaligned-access -mno-strict-align \ +// RUN: -mstrict-align 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-STRICT-ALIGN %s +// +// -mno-strict-align +// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \ +// RUN: -mno-unaligned-access -mstrict-align \ +// RUN: -mno-strict-align 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NO-STRICT-ALIGN %s diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td index dbff25dfa0f3..923e0c9cdde7 100644 --- a/llvm/lib/Target/Mips/Mips.td +++ b/llvm/lib/Target/Mips/Mips.td @@ -208,6 +208,10 @@ def FeatureUseIndirectJumpsHazard : SubtargetFeature<"use-indirect-jump-hazard", "true", "Use indirect jump" " guards to prevent certain speculation based attacks">; +def FeatureStrictAlign + : SubtargetFeature<"strict-align", "StrictAlign", "true", + "Disable unaligned load store for r6">; + //===----------------------------------------------------------------------===// // Register File, Calling Conv, Instruction Descriptions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index 7e5f148e7bf4..0a0d40751fcf 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -365,8 +365,13 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM, setOperationAction(ISD::JumpTable, MVT::i64, Custom); setOperationAction(ISD::ConstantPool, MVT::i64, Custom); setOperationAction(ISD::SELECT, MVT::i64, Custom); - setOperationAction(ISD::LOAD, MVT::i64, Custom); - setOperationAction(ISD::STORE, MVT::i64, Custom); + if (Subtarget.hasMips64r6()) { + setOperationAction(ISD::LOAD, MVT::i64, Legal); + setOperationAction(ISD::STORE, MVT::i64, Legal); + } else { + setOperationAction(ISD::LOAD, MVT::i64, Custom); + setOperationAction(ISD::STORE, MVT::i64, Custom); + } setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); setOperationAction(ISD::SHL_PARTS, MVT::i64, Custom); setOperationAction(ISD::SRA_PARTS, MVT::i64, Custom); @@ -481,7 +486,12 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM, if (!Subtarget.hasMips64r2()) setOperationAction(ISD::BSWAP, MVT::i64, Expand); - if (Subtarget.isGP64bit()) { + if (Subtarget.isGP64bit() && Subtarget.hasMips64r6()) { + setLoadExtAction(ISD::SEXTLOAD, MVT::i64, MVT::i32, Legal); + setLoadExtAction(ISD::ZEXTLOAD, MVT::i64, MVT::i32, Legal); + setLoadExtAction(ISD::EXTLOAD, MVT::i64, MVT::i32, Legal); + setTruncStoreAction(MVT::i64, MVT::i32, Legal); + } else if (Subtarget.isGP64bit()) { setLoadExtAction(ISD::SEXTLOAD, MVT::i64, MVT::i32, Custom); setLoadExtAction(ISD::ZEXTLOAD, MVT::i64, MVT::i32, Custom); setLoadExtAction(ISD::EXTLOAD, MVT::i64, MVT::i32, Custom); diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp index b87d13cea787..5c8d64e3b6e3 100644 --- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp @@ -197,8 +197,13 @@ MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM, setOperationAction(ISD::SDIVREM, MVT::i32, Custom); setOperationAction(ISD::UDIVREM, MVT::i32, Custom); setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); - setOperationAction(ISD::LOAD, MVT::i32, Custom); - setOperationAction(ISD::STORE, MVT::i32, Custom); + if (Subtarget.hasMips32r6()) { + setOperationAction(ISD::LOAD, MVT::i32, Legal); + setOperationAction(ISD::STORE, MVT::i32, Legal); + } else { + setOperationAction(ISD::LOAD, MVT::i32, Custom); + setOperationAction(ISD::STORE, MVT::i32, Custom); + } setTargetDAGCombine(ISD::MUL); @@ -425,6 +430,8 @@ bool MipsSETargetLowering::allowsMisalignedMemoryAccesses( if (Fast) *Fast = 1; return true; + } else if (Subtarget.hasMips32r6()) { + return false; } switch (SVT) { diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp index 0134fcb341f1..1bd35ca4a419 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.cpp +++ b/llvm/lib/Target/Mips/MipsSubtarget.cpp @@ -82,7 +82,7 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 || Mips_Os16), Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), HasSym32(false), HasEVA(false), DisableMadd4(false), HasMT(false), HasCRC(false), - HasVirt(false), HasGINV(false), UseIndirectJumpsHazard(false), + HasVirt(false), HasGINV(false), UseIndirectJumpsHazard(false), StrictAlign(false), StackAlignOverride(StackAlignOverride), TM(TM), TargetTriple(TT), TSInfo(), InstrInfo(MipsInstrInfo::create( initializeSubtargetDependencies(CPU, FS, TM))), diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h index 225ee139d036..fea7f11fd070 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.h +++ b/llvm/lib/Target/Mips/MipsSubtarget.h @@ -200,6 +200,9 @@ class MipsSubtarget : public MipsGenSubtargetInfo { // Assume 32-bit GOT. bool UseXGOT = false; + // Disable unaligned load store for r6. + bool StrictAlign; + /// The minimum alignment known to hold of the stack frame on /// entry to the function and which must be maintained by every function. Align stackAlignment; @@ -372,7 +375,9 @@ public: /// MIPS32r6/MIPS64r6 require full unaligned access support but does not /// specify which component of the system provides it. Hardware, software, and /// hybrid implementations are all valid. - bool systemSupportsUnalignedAccess() const { return hasMips32r6(); } + bool systemSupportsUnalignedAccess() const { + return hasMips32r6() && !StrictAlign; + } // Set helper classes void setHelperClassesMips16(); diff --git a/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll b/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll index 6a27c9f5dac9..45c7ab980edd 100644 --- a/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll +++ b/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll @@ -405,8 +405,9 @@ define void @uitofp(i32 %a) { ; MIPS64-N32-NEXT: addiu $1, $1, %lo(%neg(%gp_rel(uitofp))) ; MIPS64-N32-NEXT: lui $2, 17200 ; MIPS64-N32-NEXT: sw $2, 12($sp) -; MIPS64-N32-NEXT: sll $2, $4, 0 -; MIPS64-N32-NEXT: sw $2, 8($sp) +; MIPS64R5-N32-NEXT: sll $2, $4, 0 +; MIPS64R5-N32-NEXT: sw $2, 8($sp) +; MIPSR6-N32-NEXT: sw $4, 8($sp) ; MIPS64-N32-NEXT: lw $2, %got_page(.LCPI5_0)($1) ; MIPS64-N32-NEXT: ldc1 $f0, %got_ofst(.LCPI5_0)($2) ; MIPS64-N32-NEXT: ldc1 $f1, 8($sp) @@ -430,8 +431,9 @@ define void @uitofp(i32 %a) { ; MIPS64-N64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(uitofp))) ; MIPS64-N64-NEXT: lui $2, 17200 ; MIPS64-N64-NEXT: sw $2, 12($sp) -; MIPS64-N64-NEXT: sll $2, $4, 0 -; MIPS64-N64-NEXT: sw $2, 8($sp) +; MIPS64R5-N64-NEXT: sll $2, $4, 0 +; MIPS64R5-N64-NEXT: sw $2, 8($sp) +; MIPSR6-N64-NEXT: sw $4, 8($sp) ; MIPS64-N64-NEXT: ld $2, %got_page(.LCPI5_0)($1) ; MIPS64-N64-NEXT: ldc1 $f0, %got_ofst(.LCPI5_0)($2) ; MIPS64-N64-NEXT: ldc1 $f1, 8($sp) diff --git a/llvm/test/CodeGen/Mips/no-unaligned-access-r6.ll b/llvm/test/CodeGen/Mips/no-unaligned-access-r6.ll new file mode 100644 index 000000000000..0695868f9c80 --- /dev/null +++ b/llvm/test/CodeGen/Mips/no-unaligned-access-r6.ll @@ -0,0 +1,69 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +;; Test the strict-align feature which is similar to AArch64/arm64-strict-align.ll. + +; RUN: llc --mtriple=mipsisa32r6 < %s | FileCheck %s --check-prefix=MIPS32R6-UNALIGNED +; RUN: llc --mtriple=mipsisa32r6 --mattr=-strict-align < %s | FileCheck %s --check-prefix=MIPS32R6-UNALIGNED +; RUN: llc --mtriple=mipsisa32r6 --mattr=+strict-align < %s | FileCheck %s --check-prefix=MIPS32R6-ALIGNED + +; RUN: llc --mtriple=mipsisa64r6 < %s | FileCheck %s --check-prefix=MIPS64R6-UNALIGNED +; RUN: llc --mtriple=mipsisa64r6 --mattr=-strict-align < %s | FileCheck %s --check-prefix=MIPS64R6-UNALIGNED +; RUN: llc --mtriple=mipsisa64r6 --mattr=+strict-align < %s | FileCheck %s --check-prefix=MIPS64R6-ALIGNED + +define i32 @f0(ptr %p) nounwind { +; MIPS32R6-UNALIGNED-LABEL: f0: +; MIPS32R6-UNALIGNED: # %bb.0: +; MIPS32R6-UNALIGNED-NEXT: lw $2, 0($4) +; MIPS32R6-UNALIGNED-NEXT: jrc $ra +; +; MIPS32R6-ALIGNED-LABEL: f0: +; MIPS32R6-ALIGNED: # %bb.0: +; MIPS32R6-ALIGNED-NEXT: lhu $1, 2($4) +; MIPS32R6-ALIGNED-NEXT: lhu $2, 0($4) +; MIPS32R6-ALIGNED-NEXT: sll $2, $2, 16 +; MIPS32R6-ALIGNED-NEXT: jr $ra +; MIPS32R6-ALIGNED-NEXT: or $2, $2, $1 +; +; MIPS64R6-UNALIGNED-LABEL: f0: +; MIPS64R6-UNALIGNED: # %bb.0: +; MIPS64R6-UNALIGNED-NEXT: lw $2, 0($4) +; MIPS64R6-UNALIGNED-NEXT: jrc $ra +; +; MIPS64R6-ALIGNED-LABEL: f0: +; MIPS64R6-ALIGNED: # %bb.0: +; MIPS64R6-ALIGNED-NEXT: lhu $1, 2($4) +; MIPS64R6-ALIGNED-NEXT: lhu $2, 0($4) +; MIPS64R6-ALIGNED-NEXT: sll $2, $2, 16 +; MIPS64R6-ALIGNED-NEXT: jr $ra +; MIPS64R6-ALIGNED-NEXT: or $2, $2, $1 + %tmp = load i32, ptr %p, align 2 + ret i32 %tmp +} + +define i64 @f1(ptr %p) nounwind { +; MIPS32R6-UNALIGNED-LABEL: f1: +; MIPS32R6-UNALIGNED: # %bb.0: +; MIPS32R6-UNALIGNED-NEXT: lw $2, 0($4) +; MIPS32R6-UNALIGNED-NEXT: lw $3, 4($4) +; MIPS32R6-UNALIGNED-NEXT: jrc $ra +; +; MIPS32R6-ALIGNED-LABEL: f1: +; MIPS32R6-ALIGNED: # %bb.0: +; MIPS32R6-ALIGNED-NEXT: lw $2, 0($4) +; MIPS32R6-ALIGNED-NEXT: lw $3, 4($4) +; MIPS32R6-ALIGNED-NEXT: jrc $ra +; +; MIPS64R6-UNALIGNED-LABEL: f1: +; MIPS64R6-UNALIGNED: # %bb.0: +; MIPS64R6-UNALIGNED-NEXT: ld $2, 0($4) +; MIPS64R6-UNALIGNED-NEXT: jrc $ra +; +; MIPS64R6-ALIGNED-LABEL: f1: +; MIPS64R6-ALIGNED: # %bb.0: +; MIPS64R6-ALIGNED-NEXT: lwu $1, 4($4) +; MIPS64R6-ALIGNED-NEXT: lwu $2, 0($4) +; MIPS64R6-ALIGNED-NEXT: dsll $2, $2, 32 +; MIPS64R6-ALIGNED-NEXT: jr $ra +; MIPS64R6-ALIGNED-NEXT: or $2, $2, $1 + %tmp = load i64, ptr %p, align 4 + ret i64 %tmp +} -- GitLab From d538c5616f4d25c6f50a1285984aba806252ce17 Mon Sep 17 00:00:00 2001 From: Matteo Franciolini <mfranciolini@tesla.com> Date: Tue, 19 Mar 2024 23:28:20 -0700 Subject: [PATCH 187/307] [mlir][bufferize] Fix broken implementation of denyDialect (#85881) The current implementation is not functional and does not compile. The patch allows to correctly mark a dialect as denied for the purpose of bufferization. --- .../Dialect/Bufferization/IR/BufferizableOpInterface.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h index 94d5c08dfe45..3a61a4b34765 100644 --- a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h +++ b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h @@ -147,6 +147,16 @@ public: entries.push_back(Entry{filterFn, Entry::FilterType::ALLOW}); } + /// Deny the given dialect. + /// + /// This function adds a DENY entry. + void denyDialect(StringRef dialectNamespace) { + Entry::FilterFn filterFn = [=](Operation *op) { + return op->getDialect()->getNamespace() == dialectNamespace; + }; + entries.push_back(Entry{filterFn, Entry::FilterType::DENY}); + } + /// Allow the given ops. /// /// This function adds one or multiple ALLOW entries. -- GitLab From 807fd07646646d7f96bd3561e79435b5d7bb4a64 Mon Sep 17 00:00:00 2001 From: Nathan Ridge <zeratul976@hotmail.com> Date: Wed, 20 Mar 2024 02:44:04 -0400 Subject: [PATCH 188/307] [clangd] Handle variable templates consistently with class templates in code completion (#85740) The option --function-arg-placeholders=0 results in placeholders being omitted for class template argument lists. This patch extends the same treatment to variable template argument lists. Fixes https://github.com/clangd/clangd/issues/1976 --- clang-tools-extra/clangd/CodeComplete.cpp | 3 ++- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index 036eb9808ea0..9e321dce4c50 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -619,7 +619,8 @@ private: } // 'CompletionItemKind::Interface' matches template type aliases. if (Completion.Kind == CompletionItemKind::Interface || - Completion.Kind == CompletionItemKind::Class) { + Completion.Kind == CompletionItemKind::Class || + Completion.Kind == CompletionItemKind::Variable) { if (Snippet->front() != '<') return *Snippet; // Not an arg snippet? diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 5721feecd58e..49337bddf98d 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -2648,12 +2648,15 @@ TEST(CompletionTest, CompletionFunctionArgsDisabled) { class foo_class{}; template <class T> using foo_alias = T**; + template <class T> + T foo_var = T{}; void f() { foo_^ })cpp", {}, Opts); EXPECT_THAT( Results.Completions, UnorderedElementsAre(AllOf(named("foo_class"), snippetSuffix("<$0>")), - AllOf(named("foo_alias"), snippetSuffix("<$0>")))); + AllOf(named("foo_alias"), snippetSuffix("<$0>")), + AllOf(named("foo_var"), snippetSuffix("<$0>")))); } { auto Results = completions( -- GitLab From 5e78417db5acbcbfb33e6503e97be0734fca0631 Mon Sep 17 00:00:00 2001 From: Justin Holewinski <jholewinski@nvidia.com> Date: Wed, 20 Mar 2024 03:32:19 -0400 Subject: [PATCH 189/307] [MLIR][CUDA] Use _alloca instead of alloca on Windows (#85853) MSVC/Windows does not support `alloca()`; instead it defines `_alloca()` in `malloc.h`. --- mlir/lib/ExecutionEngine/CudaRuntimeWrappers.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mlir/lib/ExecutionEngine/CudaRuntimeWrappers.cpp b/mlir/lib/ExecutionEngine/CudaRuntimeWrappers.cpp index 9d406bdfc7cc..09dc30365e37 100644 --- a/mlir/lib/ExecutionEngine/CudaRuntimeWrappers.cpp +++ b/mlir/lib/ExecutionEngine/CudaRuntimeWrappers.cpp @@ -28,6 +28,7 @@ #endif // MLIR_ENABLE_CUDA_CUSPARSE #ifdef _WIN32 +#include <malloc.h> #define MLIR_CUDA_WRAPPERS_EXPORT __declspec(dllexport) #else #define MLIR_CUDA_WRAPPERS_EXPORT __attribute__((visibility("default"))) @@ -287,7 +288,11 @@ extern "C" MLIR_CUDA_WRAPPERS_EXPORT void mgpuMemHostRegisterMemRef(int64_t rank, StridedMemRefType<char, 1> *descriptor, int64_t elementSizeBytes) { // Only densely packed tensors are currently supported. +#ifdef _WIN32 + int64_t *denseStrides = (int64_t *)_alloca(rank * sizeof(int64_t)); +#else int64_t *denseStrides = (int64_t *)alloca(rank * sizeof(int64_t)); +#endif // _WIN32 int64_t *sizes = descriptor->sizes; for (int64_t i = rank - 1, runningStride = 1; i >= 0; i--) { denseStrides[i] = runningStride; -- GitLab From 9848fa4aa2a83b0fc3a93e5f905ef09c8dd85226 Mon Sep 17 00:00:00 2001 From: Krishna Narayanan <84722531+Krishna-13-cyber@users.noreply.github.com> Date: Wed, 20 Mar 2024 13:03:49 +0530 Subject: [PATCH 190/307] Enable exp10 libcall on linux (#68736) --- llvm/lib/Analysis/TargetLibraryInfo.cpp | 19 ++++--- .../InstCombine/double-float-shrink-1.ll | 19 +++++-- llvm/test/Transforms/InstCombine/pow-1.ll | 53 ++++++++++++++++--- llvm/test/Transforms/InstCombine/pow-exp.ll | 39 +++++++------- 4 files changed, 88 insertions(+), 42 deletions(-) diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index c8195584ade3..a0f6fa8f1ae9 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -560,16 +560,12 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, break; case Triple::Linux: // exp10, exp10f, exp10l is available on Linux (GLIBC) but are extremely - // buggy prior to glibc version 2.18. Until this version is widely deployed - // or we have a reasonable detection strategy, we cannot use exp10 reliably - // on Linux. - // - // Fall through to disable all of them. - [[fallthrough]]; - default: - TLI.setUnavailable(LibFunc_exp10); - TLI.setUnavailable(LibFunc_exp10f); - TLI.setUnavailable(LibFunc_exp10l); + // buggy prior to glibc version 2.18. As this version is so old, we + // don't really need to worry about using exp10 on Linux. + TLI.setAvailableWithName(LibFunc_exp10, "__exp10"); + TLI.setAvailableWithName(LibFunc_exp10f, "__exp10f"); + TLI.setAvailableWithName(LibFunc_exp10l, "__exp10l"); + break; } // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and @@ -841,6 +837,9 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, TLI.setUnavailable(LibFunc_strndup); TLI.setUnavailable(LibFunc_strnlen); TLI.setUnavailable(LibFunc_toascii); + TLI.setUnavailable(LibFunc_exp10); + TLI.setUnavailable(LibFunc_exp10f); + TLI.setUnavailable(LibFunc_exp10l); } // As currently implemented in clang, NVPTX code has no standard library to diff --git a/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll b/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll index 85c9a01e5fab..693730256b6b 100644 --- a/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll +++ b/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll @@ -224,11 +224,20 @@ define double @expm1_test2(float %f) { ; exp10f() doesn't exist for this triple, so it doesn't shrink. define float @exp10_test1(float %f) { -; CHECK-LABEL: @exp10_test1( -; CHECK-NEXT: [[CONV:%.*]] = fpext float [[F:%.*]] to double -; CHECK-NEXT: [[CALL:%.*]] = call fast double @exp10(double [[CONV]]) -; CHECK-NEXT: [[CONV1:%.*]] = fptrunc double [[CALL]] to float -; CHECK-NEXT: ret float [[CONV1]] +; LINUX-LABEL: define float @exp10_test1( +; LINUX-SAME: float [[F:%.*]]) { +; LINUX-NEXT: [[EXP10F:%.*]] = call fast float @__exp10f(float [[F]]) +; LINUX-NEXT: ret float [[EXP10F]] +; +; MS64-LABEL: define float @exp10_test1( +; MS64-SAME: float [[F:%.*]]) { +; MS64-NEXT: [[EXP10F:%.*]] = call fast float @exp10f(float [[F]]) +; MS64-NEXT: ret float [[EXP10F]] +; +; MS32-LABEL: define float @exp10_test1( +; MS32-SAME: float [[F:%.*]]) { +; MS32-NEXT: [[EXP10F:%.*]] = call fast float @exp10f(float [[F]]) +; MS32-NEXT: ret float [[EXP10F]] ; %conv = fpext float %f to double %call = call fast double @exp10(double %conv) diff --git a/llvm/test/Transforms/InstCombine/pow-1.ll b/llvm/test/Transforms/InstCombine/pow-1.ll index 7a72902126f8..5024d152bddf 100644 --- a/llvm/test/Transforms/InstCombine/pow-1.ll +++ b/llvm/test/Transforms/InstCombine/pow-1.ll @@ -870,10 +870,30 @@ define float @test_simplify18(float %x) { ; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @__exp10f(float [[X]]) ; CHECK-EXP10-NEXT: ret float [[__EXP10F]] ; -; CHECK-NO-EXP10-LABEL: define float @test_simplify18( -; CHECK-NO-EXP10-SAME: float [[X:%.*]]) { -; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) -; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]] +; VC32-LABEL: define float @test_simplify18( +; VC32-SAME: float [[X:%.*]]) { +; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) +; VC32-NEXT: ret float [[RETVAL]] +; +; VC51-LABEL: define float @test_simplify18( +; VC51-SAME: float [[X:%.*]]) { +; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) +; VC51-NEXT: ret float [[RETVAL]] +; +; VC64-LABEL: define float @test_simplify18( +; VC64-SAME: float [[X:%.*]]) { +; VC64-NEXT: [[EXP10F:%.*]] = call float @exp10f(float [[X]]) +; VC64-NEXT: ret float [[EXP10F]] +; +; VC83-LABEL: define float @test_simplify18( +; VC83-SAME: float [[X:%.*]]) { +; VC83-NEXT: [[EXP10F:%.*]] = call float @exp10f(float [[X]]) +; VC83-NEXT: ret float [[EXP10F]] +; +; NOLIB-LABEL: define float @test_simplify18( +; NOLIB-SAME: float [[X:%.*]]) { +; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) +; NOLIB-NEXT: ret float [[RETVAL]] ; %retval = call float @powf(float 10.0, float %x) ret float %retval @@ -885,11 +905,28 @@ define double @test_simplify19(double %x) { ; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @__exp10(double [[X]]) ; CHECK-EXP10-NEXT: ret double [[__EXP10]] ; -; CHECK-NO-EXP10-LABEL: define double @test_simplify19( -; CHECK-NO-EXP10-SAME: double [[X:%.*]]) { -; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) -; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]] +; VC32-LABEL: define double @test_simplify19( +; VC32-SAME: double [[X:%.*]]) { +; VC32-NEXT: [[EXP10:%.*]] = call double @exp10(double [[X]]) +; VC32-NEXT: ret double [[EXP10]] +; +; VC19-LABEL: define double @test_simplify19( +; VC19-SAME: double [[X:%.*]]) { +; VC19-NEXT: [[EXP10:%.*]] = call double @exp10(double [[X]]) +; VC19-NEXT: ret double [[EXP10]] +; +; VC64-LABEL: define double @test_simplify19( +; VC64-SAME: double [[X:%.*]]) { +; VC64-NEXT: [[EXP10:%.*]] = call double @exp10(double [[X]]) +; VC64-NEXT: ret double [[EXP10]] +; +; NOLIB-LABEL: define double @test_simplify19( +; NOLIB-SAME: double [[X:%.*]]) { +; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) +; NOLIB-NEXT: ret double [[RETVAL]] ; %retval = call double @pow(double 10.0, double %x) ret double %retval } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; CHECK-NO-EXP10: {{.*}} diff --git a/llvm/test/Transforms/InstCombine/pow-exp.ll b/llvm/test/Transforms/InstCombine/pow-exp.ll index 9d91ad2402eb..177dd9885827 100644 --- a/llvm/test/Transforms/InstCombine/pow-exp.ll +++ b/llvm/test/Transforms/InstCombine/pow-exp.ll @@ -136,12 +136,11 @@ define fp128 @powl_exp2l_not_fast(fp128 %x, fp128 %y) { ret fp128 %pow } -; TODO: exp10() is not widely enabled by many targets yet. - define float @powf_exp10f(float %x, float %y) { -; CHECK-LABEL: @powf_exp10f( -; CHECK-NEXT: [[CALL:%.*]] = call fast float @exp10f(float [[X:%.*]]) #[[ATTR1:[0-9]+]] -; CHECK-NEXT: [[POW:%.*]] = call fast float @llvm.pow.f32(float [[CALL]], float [[Y:%.*]]) +; CHECK-LABEL: define float @powf_exp10f( +; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = call fast float @exp10f(float [[X]]) #[[ATTR1:[0-9]+]] +; CHECK-NEXT: [[POW:%.*]] = call fast float @llvm.pow.f32(float [[CALL]], float [[Y]]) ; CHECK-NEXT: ret float [[POW]] ; %call = call fast float @exp10f(float %x) nounwind readnone @@ -150,9 +149,10 @@ define float @powf_exp10f(float %x, float %y) { } define double @pow_exp10(double %x, double %y) { -; CHECK-LABEL: @pow_exp10( -; CHECK-NEXT: [[CALL:%.*]] = call fast double @exp10(double [[X:%.*]]) #[[ATTR1]] -; CHECK-NEXT: [[POW:%.*]] = call fast double @llvm.pow.f64(double [[CALL]], double [[Y:%.*]]) +; CHECK-LABEL: define double @pow_exp10( +; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = call fast double @exp10(double [[X]]) #[[ATTR1]] +; CHECK-NEXT: [[POW:%.*]] = call fast double @llvm.pow.f64(double [[CALL]], double [[Y]]) ; CHECK-NEXT: ret double [[POW]] ; %call = call fast double @exp10(double %x) nounwind readnone @@ -161,9 +161,10 @@ define double @pow_exp10(double %x, double %y) { } define fp128 @pow_exp10l(fp128 %x, fp128 %y) { -; CHECK-LABEL: @pow_exp10l( -; CHECK-NEXT: [[CALL:%.*]] = call fast fp128 @exp10l(fp128 [[X:%.*]]) #[[ATTR1]] -; CHECK-NEXT: [[POW:%.*]] = call fast fp128 @llvm.pow.f128(fp128 [[CALL]], fp128 [[Y:%.*]]) +; CHECK-LABEL: define fp128 @pow_exp10l( +; CHECK-SAME: fp128 [[X:%.*]], fp128 [[Y:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = call fast fp128 @exp10l(fp128 [[X]]) #[[ATTR1]] +; CHECK-NEXT: [[POW:%.*]] = call fast fp128 @llvm.pow.f128(fp128 [[CALL]], fp128 [[Y]]) ; CHECK-NEXT: ret fp128 [[POW]] ; %call = call fast fp128 @exp10l(fp128 %x) nounwind readnone @@ -255,10 +256,10 @@ define double @pow_ok_base3(double %e) { } define double @pow_ok_ten_base(double %e) { -; CHECK-LABEL: @pow_ok_ten_base( -; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn double [[E:%.*]], 0x400A934F{{.*}} -; CHECK-NEXT: [[EXP2:%.*]] = tail call nnan ninf afn double @exp2(double [[MUL]]) -; CHECK-NEXT: ret double [[EXP2]] +; CHECK-LABEL: define double @pow_ok_ten_base( +; CHECK-SAME: double [[E:%.*]]) { +; CHECK-NEXT: [[EXP10:%.*]] = tail call nnan ninf afn double @exp10(double [[E]]) +; CHECK-NEXT: ret double [[EXP10]] ; %call = tail call afn nnan ninf double @pow(double 1.000000e+01, double %e) ret double %call @@ -305,10 +306,10 @@ define float @powf_ok_base3(float %e) { } define float @powf_ok_ten_base(float %e) { -; CHECK-LABEL: @powf_ok_ten_base( -; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn float [[E:%.*]], 0x400A934{{.*}} -; CHECK-NEXT: [[EXP2F:%.*]] = tail call nnan ninf afn float @exp2f(float [[MUL]]) -; CHECK-NEXT: ret float [[EXP2F]] +; CHECK-LABEL: define float @powf_ok_ten_base( +; CHECK-SAME: float [[E:%.*]]) { +; CHECK-NEXT: [[EXP10F:%.*]] = tail call nnan ninf afn float @exp10f(float [[E]]) +; CHECK-NEXT: ret float [[EXP10F]] ; %call = tail call afn nnan ninf float @powf(float 1.000000e+01, float %e) ret float %call -- GitLab From 756c20561efa1e58bd7d2a6df1499997b6b52e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kadir=20=C3=A7etinkaya?= <kadircet@google.com> Date: Wed, 20 Mar 2024 08:48:06 +0100 Subject: [PATCH 191/307] [clang][Tooling] Add special symbol mappings for C, starting with size_t (#85784) --- .../Inclusions/Stdlib/CSpecialSymbolMap.inc | 14 ++++++++++++++ .../Tooling/Inclusions/Stdlib/StandardLibrary.cpp | 4 +++- clang/unittests/Tooling/StandardLibraryTest.cpp | 13 +++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 clang/lib/Tooling/Inclusions/Stdlib/CSpecialSymbolMap.inc diff --git a/clang/lib/Tooling/Inclusions/Stdlib/CSpecialSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/CSpecialSymbolMap.inc new file mode 100644 index 000000000000..a515f69ea6a8 --- /dev/null +++ b/clang/lib/Tooling/Inclusions/Stdlib/CSpecialSymbolMap.inc @@ -0,0 +1,14 @@ +//===-- StdSpecialSymbolMap.inc -----------------------------------*- C -*-===// +// +// This is a hand-curated list for C symbols that cannot be parsed/extracted +// via the include-mapping tool (gen_std.py). +// +//===----------------------------------------------------------------------===// + +SYMBOL(size_t, None, <stddef.h>) +SYMBOL(size_t, None, <stdio.h>) +SYMBOL(size_t, None, <stdlib.h>) +SYMBOL(size_t, None, <string.h>) +SYMBOL(size_t, None, <time.h>) +SYMBOL(size_t, None, <uchar.h>) +SYMBOL(size_t, None, <wchar.h>) diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp b/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp index adf1b230ff03..0832bcf66145 100644 --- a/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp +++ b/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp @@ -55,11 +55,12 @@ static const SymbolHeaderMapping *getMappingPerLang(Lang L) { } static int countSymbols(Lang Language) { - ArrayRef<const char*> Symbols; + ArrayRef<const char *> Symbols; #define SYMBOL(Name, NS, Header) #NS #Name, switch (Language) { case Lang::C: { static constexpr const char *CSymbols[] = { +#include "CSpecialSymbolMap.inc" #include "CSymbolMap.inc" }; Symbols = CSymbols; @@ -147,6 +148,7 @@ static int initialize(Lang Language) { switch (Language) { case Lang::C: { static constexpr Symbol CSymbols[] = { +#include "CSpecialSymbolMap.inc" #include "CSymbolMap.inc" }; for (const Symbol &S : CSymbols) diff --git a/clang/unittests/Tooling/StandardLibraryTest.cpp b/clang/unittests/Tooling/StandardLibraryTest.cpp index edca31649acc..e4c109f3d580 100644 --- a/clang/unittests/Tooling/StandardLibraryTest.cpp +++ b/clang/unittests/Tooling/StandardLibraryTest.cpp @@ -185,6 +185,19 @@ TEST(StdlibTest, RecognizerForC99) { stdlib::Symbol::named("", "uint8_t", stdlib::Lang::C)); } +TEST(StdlibTest, SpecialCMappings) { + TestInputs Input("typedef char size_t;"); + Input.Language = TestLanguage::Lang_C99; + TestAST AST(Input); + + auto &SizeT = lookup(AST, "size_t"); + stdlib::Recognizer Recognizer; + auto ActualSym = Recognizer(&SizeT); + assert(ActualSym); + EXPECT_EQ(ActualSym, stdlib::Symbol::named("", "size_t", stdlib::Lang::C)); + EXPECT_EQ(ActualSym->header()->name(), "<stddef.h>"); +} + } // namespace } // namespace tooling } // namespace clang -- GitLab From f0420c7bc67339e080cb2a13b6f3eb824faf9288 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng <dtcxzyw2333@gmail.com> Date: Wed, 20 Mar 2024 16:16:42 +0800 Subject: [PATCH 192/307] [ValueTracking] Handle `not` in `isImpliedCondition` (#85397) This patch handles `not` in `isImpliedCondition` to enable more fold in some multi-use cases. --- llvm/lib/Analysis/ValueTracking.cpp | 31 ++++++--- .../InstCombine/and-or-implied-cond-not.ll | 69 +++++++++++++++++++ .../LoopVectorize/reduction-inloop.ll | 3 +- 3 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/and-or-implied-cond-not.ll diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 8be17b506af5..58bc68b576b0 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8606,6 +8606,10 @@ llvm::isImpliedCondition(const Value *LHS, CmpInst::Predicate RHSPred, assert(LHS->getType()->isIntOrIntVectorTy(1) && "Expected integer type only!"); + // Match not + if (match(LHS, m_Not(m_Value(LHS)))) + LHSIsTrue = !LHSIsTrue; + // Both LHS and RHS are icmps. const ICmpInst *LHSCmp = dyn_cast<ICmpInst>(LHS); if (LHSCmp) @@ -8632,10 +8636,21 @@ std::optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS, if (LHS == RHS) return LHSIsTrue; - if (const ICmpInst *RHSCmp = dyn_cast<ICmpInst>(RHS)) - return isImpliedCondition(LHS, RHSCmp->getPredicate(), - RHSCmp->getOperand(0), RHSCmp->getOperand(1), DL, - LHSIsTrue, Depth); + // Match not + bool InvertRHS = false; + if (match(RHS, m_Not(m_Value(RHS)))) { + if (LHS == RHS) + return !LHSIsTrue; + InvertRHS = true; + } + + if (const ICmpInst *RHSCmp = dyn_cast<ICmpInst>(RHS)) { + if (auto Implied = isImpliedCondition( + LHS, RHSCmp->getPredicate(), RHSCmp->getOperand(0), + RHSCmp->getOperand(1), DL, LHSIsTrue, Depth)) + return InvertRHS ? !*Implied : *Implied; + return std::nullopt; + } if (Depth == MaxAnalysisRecursionDepth) return std::nullopt; @@ -8647,21 +8662,21 @@ std::optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS, if (std::optional<bool> Imp = isImpliedCondition(LHS, RHS1, DL, LHSIsTrue, Depth + 1)) if (*Imp == true) - return true; + return !InvertRHS; if (std::optional<bool> Imp = isImpliedCondition(LHS, RHS2, DL, LHSIsTrue, Depth + 1)) if (*Imp == true) - return true; + return !InvertRHS; } if (match(RHS, m_LogicalAnd(m_Value(RHS1), m_Value(RHS2)))) { if (std::optional<bool> Imp = isImpliedCondition(LHS, RHS1, DL, LHSIsTrue, Depth + 1)) if (*Imp == false) - return false; + return InvertRHS; if (std::optional<bool> Imp = isImpliedCondition(LHS, RHS2, DL, LHSIsTrue, Depth + 1)) if (*Imp == false) - return false; + return InvertRHS; } return std::nullopt; diff --git a/llvm/test/Transforms/InstCombine/and-or-implied-cond-not.ll b/llvm/test/Transforms/InstCombine/and-or-implied-cond-not.ll new file mode 100644 index 000000000000..89b3164018ac --- /dev/null +++ b/llvm/test/Transforms/InstCombine/and-or-implied-cond-not.ll @@ -0,0 +1,69 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +define i1 @test_imply_not1(i32 %depth) { +; CHECK-LABEL: define i1 @test_imply_not1( +; CHECK-SAME: i32 [[DEPTH:%.*]]) { +; CHECK-NEXT: [[CMP1_NOT1:%.*]] = icmp eq i32 [[DEPTH]], 16 +; CHECK-NEXT: call void @use(i1 [[CMP1_NOT1]]) +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[DEPTH]], 8 +; CHECK-NEXT: call void @use(i1 [[CMP2]]) +; CHECK-NEXT: br i1 [[CMP1_NOT1]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: call void @func1() +; CHECK-NEXT: unreachable +; CHECK: if.else: +; CHECK-NEXT: call void @func2() +; CHECK-NEXT: unreachable +; + %cmp1 = icmp eq i32 %depth, 16 + call void @use(i1 %cmp1) + %cmp2 = icmp slt i32 %depth, 8 + call void @use(i1 %cmp2) + %cmp.not = xor i1 %cmp1, true + %brmerge = or i1 %cmp2, %cmp.not + br i1 %brmerge, label %if.then, label %if.else +if.then: + call void @func1() + unreachable + +if.else: + call void @func2() + unreachable +} + +define i1 @test_imply_not2(i32 %a, i1 %cmp2) { +; CHECK-LABEL: define i1 @test_imply_not2( +; CHECK-SAME: i32 [[A:%.*]], i1 [[CMP2:%.*]]) { +; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], 0 +; CHECK-NEXT: [[BRMERGE:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]] +; CHECK-NEXT: ret i1 [[BRMERGE]] +; + %cmp1 = icmp eq i32 %a, 0 + %or.cond = select i1 %cmp1, i1 %cmp2, i1 false + %cmp.not = xor i1 %cmp1, true + %brmerge = or i1 %or.cond, %cmp.not + ret i1 %brmerge +} + +define i1 @test_imply_not3(i32 %a, i32 %b, i1 %cond) { +; CHECK-LABEL: define i1 @test_imply_not3( +; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i1 [[COND:%.*]]) { +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], [[B]] +; CHECK-NEXT: call void @use(i1 [[CMP1]]) +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] +; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP2]], i1 [[COND]], i1 false +; CHECK-NEXT: ret i1 [[AND]] +; + %cmp1 = icmp eq i32 %a, %b + call void @use(i1 %cmp1) + %cmp2 = icmp slt i32 %a, %b + %cmp.not = xor i1 %cmp1, true + %sel = select i1 %cmp.not, i1 %cond, i1 false + %and = and i1 %cmp2, %sel + ret i1 %and +} + +declare void @func1() +declare void @func2() +declare void @use(i1) diff --git a/llvm/test/Transforms/LoopVectorize/reduction-inloop.ll b/llvm/test/Transforms/LoopVectorize/reduction-inloop.ll index e8d57c935144..204d021f0657 100644 --- a/llvm/test/Transforms/LoopVectorize/reduction-inloop.ll +++ b/llvm/test/Transforms/LoopVectorize/reduction-inloop.ll @@ -1354,9 +1354,8 @@ define i32 @predicated_or_dominates_reduction(ptr %b) { ; CHECK: pred.load.continue6: ; CHECK-NEXT: [[TMP43:%.*]] = phi <4 x i32> [ [[TMP37]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP42]], [[PRED_LOAD_IF5]] ] ; CHECK-NEXT: [[TMP44:%.*]] = icmp ne <4 x i32> [[TMP43]], zeroinitializer -; CHECK-NEXT: [[TMP45:%.*]] = select <4 x i1> [[TMP19]], <4 x i1> [[TMP44]], <4 x i1> zeroinitializer ; CHECK-NEXT: [[TMP46:%.*]] = xor <4 x i1> [[TMP19]], <i1 true, i1 true, i1 true, i1 true> -; CHECK-NEXT: [[TMP47:%.*]] = or <4 x i1> [[TMP45]], [[TMP46]] +; CHECK-NEXT: [[TMP47:%.*]] = select <4 x i1> [[TMP46]], <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i1> [[TMP44]] ; CHECK-NEXT: [[TMP48:%.*]] = bitcast <4 x i1> [[TMP47]] to i4 ; CHECK-NEXT: [[TMP49:%.*]] = call i4 @llvm.ctpop.i4(i4 [[TMP48]]), !range [[RNG42:![0-9]+]] ; CHECK-NEXT: [[TMP50:%.*]] = zext nneg i4 [[TMP49]] to i32 -- GitLab From 27df1b23e07009b1450ebb2072abac97e2958b07 Mon Sep 17 00:00:00 2001 From: Nikita Popov <npopov@redhat.com> Date: Wed, 20 Mar 2024 09:18:45 +0100 Subject: [PATCH 193/307] [SLPVectorizer] Use TargetFolder (#85800) Use IRBuilder with TargetFolder in SLPVectorizer to avoid the custom constant folding code. This fixes the remaining part of https://github.com/llvm/llvm-project/issues/61240. --- .../Transforms/Vectorize/SLPVectorizer.cpp | 40 ++++++------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 4738c60e5dfa..ac16fcf76745 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -1001,8 +1001,9 @@ public: TargetLibraryInfo *TLi, AAResults *Aa, LoopInfo *Li, DominatorTree *Dt, AssumptionCache *AC, DemandedBits *DB, const DataLayout *DL, OptimizationRemarkEmitter *ORE) - : BatchAA(*Aa), F(Func), SE(Se), TTI(Tti), TLI(TLi), LI(Li), - DT(Dt), AC(AC), DB(DB), DL(DL), ORE(ORE), Builder(Se->getContext()) { + : BatchAA(*Aa), F(Func), SE(Se), TTI(Tti), TLI(TLi), LI(Li), DT(Dt), + AC(AC), DB(DB), DL(DL), ORE(ORE), + Builder(Se->getContext(), TargetFolder(*DL)) { CodeMetrics::collectEphemeralValues(F, AC, EphValues); // Use the vector register size specified by the target unless overridden // by a command-line option. @@ -3642,7 +3643,7 @@ private: unsigned MinVecRegSize; // Set by cl::opt (default: 128). /// Instruction builder to construct the vectorized tree. - IRBuilder<> Builder; + IRBuilder<TargetFolder> Builder; /// A map of scalar integer values to the smallest bit width with which they /// can legally be represented. The values map to (width, signed) pairs, @@ -15031,7 +15032,6 @@ class HorizontalReduction { static Value *createOp(IRBuilderBase &Builder, RecurKind Kind, Value *LHS, Value *RHS, const Twine &Name, bool UseSelect) { unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(Kind); - bool IsConstant = isConstant(LHS) && isConstant(RHS); switch (Kind) { case RecurKind::Or: if (UseSelect && @@ -15053,49 +15053,33 @@ class HorizontalReduction { return Builder.CreateBinOp((Instruction::BinaryOps)RdxOpcode, LHS, RHS, Name); case RecurKind::FMax: - if (IsConstant) - return ConstantFP::get(LHS->getType(), - maxnum(cast<ConstantFP>(LHS)->getValueAPF(), - cast<ConstantFP>(RHS)->getValueAPF())); return Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, LHS, RHS); case RecurKind::FMin: - if (IsConstant) - return ConstantFP::get(LHS->getType(), - minnum(cast<ConstantFP>(LHS)->getValueAPF(), - cast<ConstantFP>(RHS)->getValueAPF())); return Builder.CreateBinaryIntrinsic(Intrinsic::minnum, LHS, RHS); case RecurKind::FMaximum: - if (IsConstant) - return ConstantFP::get(LHS->getType(), - maximum(cast<ConstantFP>(LHS)->getValueAPF(), - cast<ConstantFP>(RHS)->getValueAPF())); return Builder.CreateBinaryIntrinsic(Intrinsic::maximum, LHS, RHS); case RecurKind::FMinimum: - if (IsConstant) - return ConstantFP::get(LHS->getType(), - minimum(cast<ConstantFP>(LHS)->getValueAPF(), - cast<ConstantFP>(RHS)->getValueAPF())); return Builder.CreateBinaryIntrinsic(Intrinsic::minimum, LHS, RHS); case RecurKind::SMax: - if (IsConstant || UseSelect) { + if (UseSelect) { Value *Cmp = Builder.CreateICmpSGT(LHS, RHS, Name); return Builder.CreateSelect(Cmp, LHS, RHS, Name); } return Builder.CreateBinaryIntrinsic(Intrinsic::smax, LHS, RHS); case RecurKind::SMin: - if (IsConstant || UseSelect) { + if (UseSelect) { Value *Cmp = Builder.CreateICmpSLT(LHS, RHS, Name); return Builder.CreateSelect(Cmp, LHS, RHS, Name); } return Builder.CreateBinaryIntrinsic(Intrinsic::smin, LHS, RHS); case RecurKind::UMax: - if (IsConstant || UseSelect) { + if (UseSelect) { Value *Cmp = Builder.CreateICmpUGT(LHS, RHS, Name); return Builder.CreateSelect(Cmp, LHS, RHS, Name); } return Builder.CreateBinaryIntrinsic(Intrinsic::umax, LHS, RHS); case RecurKind::UMin: - if (IsConstant || UseSelect) { + if (UseSelect) { Value *Cmp = Builder.CreateICmpULT(LHS, RHS, Name); return Builder.CreateSelect(Cmp, LHS, RHS, Name); } @@ -15489,7 +15473,7 @@ public: } /// Attempt to vectorize the tree found by matchAssociativeReduction. - Value *tryToReduce(BoUpSLP &V, TargetTransformInfo *TTI, + Value *tryToReduce(BoUpSLP &V, const DataLayout &DL, TargetTransformInfo *TTI, const TargetLibraryInfo &TLI) { constexpr int ReductionLimit = 4; constexpr unsigned RegMaxNumber = 4; @@ -15515,7 +15499,9 @@ public: return nullptr; } - IRBuilder<> Builder(cast<Instruction>(ReductionRoot)); + IRBuilder<TargetFolder> Builder(ReductionRoot->getContext(), + TargetFolder(DL)); + Builder.SetInsertPoint(cast<Instruction>(ReductionRoot)); // Track the reduced values in case if they are replaced by extractelement // because of the vectorization. @@ -16611,7 +16597,7 @@ bool SLPVectorizerPass::vectorizeHorReduction( HorizontalReduction HorRdx; if (!HorRdx.matchAssociativeReduction(R, Inst, *SE, *DL, *TLI)) return nullptr; - return HorRdx.tryToReduce(R, TTI, *TLI); + return HorRdx.tryToReduce(R, *DL, TTI, *TLI); }; auto TryAppendToPostponedInsts = [&](Instruction *FutureSeed) { if (TryOperandsAsNewSeeds && FutureSeed == Root) { -- GitLab From 4462bb58be7d68274fb9b443b7bf4803306df87d Mon Sep 17 00:00:00 2001 From: Christian Sigg <chsigg@users.noreply.github.com> Date: Wed, 20 Mar 2024 09:37:35 +0100 Subject: [PATCH 194/307] [InstallAPI][bazel] Update BUILD after 936519f25cb4fabc19f1241e838e938926801156 --- utils/bazel/llvm-project-overlay/clang/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel index f02ccdce3907..865cafbf50c6 100644 --- a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel @@ -2407,6 +2407,7 @@ cc_binary( stamp = 0, deps = [ ":basic", + ":diagnostic_defs_gen", ":frontend", ":lex", ":sema", -- GitLab From 11dd881b9cca5f70720ead353169603589e6c494 Mon Sep 17 00:00:00 2001 From: Mark de Wever <koraq@xs4all.nl> Date: Wed, 20 Mar 2024 09:45:12 +0100 Subject: [PATCH 195/307] [libc++][format] Fixes nested concept evaluation. (#85548) Before the __formattable concept depended on itself in a contrieved example. By using the underlying concept directly the cycle is broken. Fixes https://github.com/llvm/llvm-project/issues/81590 --- libcxx/include/__format/format_arg_store.h | 3 +- .../bug_81590.compile.pass.cpp | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 libcxx/test/std/utilities/format/format.functions/bug_81590.compile.pass.cpp diff --git a/libcxx/include/__format/format_arg_store.h b/libcxx/include/__format/format_arg_store.h index 066cd369eb89..23a599e99575 100644 --- a/libcxx/include/__format/format_arg_store.h +++ b/libcxx/include/__format/format_arg_store.h @@ -151,7 +151,7 @@ consteval __arg_t __determine_arg_t() { // The overload for not formattable types allows triggering the static // assertion below. template <class _Context, class _Tp> - requires(!__formattable<_Tp, typename _Context::char_type>) + requires(!__formattable_with<_Tp, _Context>) consteval __arg_t __determine_arg_t() { return __arg_t::__none; } @@ -165,7 +165,6 @@ _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp& __valu using _Dp = remove_const_t<_Tp>; constexpr __arg_t __arg = __determine_arg_t<_Context, _Dp>(); static_assert(__arg != __arg_t::__none, "the supplied type is not formattable"); - static_assert(__formattable_with<_Tp, _Context>); // Not all types can be used to directly initialize the diff --git a/libcxx/test/std/utilities/format/format.functions/bug_81590.compile.pass.cpp b/libcxx/test/std/utilities/format/format.functions/bug_81590.compile.pass.cpp new file mode 100644 index 000000000000..127f6546ccbe --- /dev/null +++ b/libcxx/test/std/utilities/format/format.functions/bug_81590.compile.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// XFAIL: availability-fp_to_chars-missing + +// The sample code is based on the bug report +// https://github.com/llvm/llvm-project/issues/81590 +// +// Tests whether this formatter does not fail to compile due to nested concept +// evaluation. + +#include <format> +#include <variant> + +struct X : std::variant<X*> { + X* p = nullptr; + constexpr const std::variant<X*>& decay() const noexcept { return *this; } +}; + +template <> +struct std::formatter<X, char> : std::formatter<std::string, char> { + static constexpr auto format(const X& x, auto ctx) { + if (!x.p) + return ctx.out(); + auto m = [&](const X* t) { return std::format_to(ctx.out(), "{}", *t); }; + return std::visit(m, x.decay()); + } +}; + +void bug_81590() { (void)std::format("{}", X{}); } -- GitLab From 272d1b44efdedb68c194970a610f0ca1b7b769c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st> Date: Wed, 20 Mar 2024 10:45:43 +0200 Subject: [PATCH 196/307] [libcxx] [modules] Fix relative paths with absolute LIBCXX_INSTALL_MODULES_DIR (#85756) In other contexts, install directories such as LIBCXX_INSTALL_LIBRARY_DIR and LIBCXX_INSTALL_MODULES_DIR can be specified either as a relative path, relative to CMAKE_INSTALL_PREFIX, or as an absolute path. When calculating the relative path between the two, account for the fact that LIBCXX_INSTALL_MODULES_DIR and LIBCXX_INSTALL_LIBRARY_DIR can be absolute paths too. --- libcxx/modules/CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libcxx/modules/CMakeLists.txt b/libcxx/modules/CMakeLists.txt index 0dea8cfca94a..8dd1b51aac2f 100644 --- a/libcxx/modules/CMakeLists.txt +++ b/libcxx/modules/CMakeLists.txt @@ -206,9 +206,15 @@ add_custom_target(generate-cxx-modules # Configure the modules manifest. # Use the relative path between the installation and the module in the json # file. This allows moving the entire installation to a different location. +cmake_path(ABSOLUTE_PATH LIBCXX_INSTALL_LIBRARY_DIR + BASE_DIRECTORY ${CMAKE_INSTALL_PREFIX} + OUTPUT_VARIABLE ABS_LIBRARY_DIR) +cmake_path(ABSOLUTE_PATH LIBCXX_INSTALL_MODULES_DIR + BASE_DIRECTORY ${CMAKE_INSTALL_PREFIX} + OUTPUT_VARIABLE ABS_MODULES_DIR) file(RELATIVE_PATH LIBCXX_MODULE_RELATIVE_PATH - ${CMAKE_INSTALL_PREFIX}/${LIBCXX_INSTALL_LIBRARY_DIR} - ${CMAKE_INSTALL_PREFIX}/${LIBCXX_INSTALL_MODULES_DIR}) + ${ABS_LIBRARY_DIR} + ${ABS_MODULES_DIR}) configure_file( "modules.json.in" "${LIBCXX_LIBRARY_DIR}/libc++.modules.json" -- GitLab From cf09b7dec463178fbdefc72dc262d209d865c1c9 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu <siujoeng.lau@gmail.com> Date: Wed, 20 Mar 2024 01:47:40 -0700 Subject: [PATCH 197/307] [libc++][ranges] LWG3715: `view_interface::empty` is overconstrained (#85004) ## Abstract This pull request implements LWG3715: `view_interface::empty` is overconstrained. Here is an example similar to those described in the report, which compiles with `-stdlib=libstdc++` but failed to compile with `-stdlib=libc++`: ```cpp // https://godbolt.org/z/EWEoTzah3 std::istringstream input("1 2 3 4 5"); auto i = std::views::istream<int>(input); auto r = std::views::counted(i.begin(), 4) | std::views::take(2); assert(!r.empty()); ``` ## Reference - [Draft C++ Standard: [view.interface.general]](https://eel.is/c++draft/view.interface.general) - [LWG3715](https://wg21.link/LWG3715) --- libcxx/docs/Status/Cxx23Issues.csv | 2 +- libcxx/include/__ranges/view_interface.h | 17 +++++++++++---- .../view.interface/view.interface.pass.cpp | 21 +++++++++++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv index 659770cd58d1..a10319235006 100644 --- a/libcxx/docs/Status/Cxx23Issues.csv +++ b/libcxx/docs/Status/Cxx23Issues.csv @@ -181,7 +181,7 @@ "`3711 <https://wg21.link/LWG3711>`__","Missing preconditions for slide_view constructor","July 2022","","","|ranges|" "`3712 <https://wg21.link/LWG3712>`__","``chunk_view`` and ``slide_view`` should not be ``default_initializable``","July 2022","","","|ranges|" "`3713 <https://wg21.link/LWG3713>`__","Sorted with respect to comparator (only)","July 2022","","" -"`3715 <https://wg21.link/LWG3715>`__","``view_interface::empty`` is overconstrained","July 2022","","","|ranges|" +"`3715 <https://wg21.link/LWG3715>`__","``view_interface::empty`` is overconstrained","July 2022","|Complete|","19.0","|ranges|" "`3719 <https://wg21.link/LWG3719>`__","Directory iterators should be usable with default sentinel","July 2022","|Complete|","17.0","|ranges|" "`3721 <https://wg21.link/LWG3721>`__","Allow an ``arg-id`` with a value of zero for ``width`` in ``std-format-spec``","July 2022","|Complete|","16.0","|format|" "`3724 <https://wg21.link/LWG3724>`__","``decay-copy`` should be constrained","July 2022","|Complete|","14.0" diff --git a/libcxx/include/__ranges/view_interface.h b/libcxx/include/__ranges/view_interface.h index 84dd1c316de3..3bcfbaf3a2f9 100644 --- a/libcxx/include/__ranges/view_interface.h +++ b/libcxx/include/__ranges/view_interface.h @@ -21,6 +21,7 @@ #include <__ranges/access.h> #include <__ranges/concepts.h> #include <__ranges/empty.h> +#include <__ranges/size.h> #include <__type_traits/is_class.h> #include <__type_traits/make_unsigned.h> #include <__type_traits/remove_cv.h> @@ -51,16 +52,24 @@ class view_interface { public: template <class _D2 = _Derived> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() - requires forward_range<_D2> + requires sized_range<_D2> || forward_range<_D2> { - return ranges::begin(__derived()) == ranges::end(__derived()); + if constexpr (sized_range<_D2>) { + return ranges::size(__derived()) == 0; + } else { + return ranges::begin(__derived()) == ranges::end(__derived()); + } } template <class _D2 = _Derived> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const - requires forward_range<const _D2> + requires sized_range<const _D2> || forward_range<const _D2> { - return ranges::begin(__derived()) == ranges::end(__derived()); + if constexpr (sized_range<const _D2>) { + return ranges::size(__derived()) == 0; + } else { + return ranges::begin(__derived()) == ranges::end(__derived()); + } } template <class _D2 = _Derived> diff --git a/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp b/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp index 2fc2fa857999..3f7c174d3fe4 100644 --- a/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp +++ b/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp @@ -39,6 +39,14 @@ struct InputRange : std::ranges::view_interface<InputRange> { constexpr InputIter end() const { return InputIter(buff + 8); } }; +struct SizedInputRange : std::ranges::view_interface<SizedInputRange> { + int buff[8] = {0, 1, 2, 3, 4, 5, 6, 7}; + constexpr InputIter begin() const { return InputIter(buff); } + constexpr sentinel_wrapper<InputIter> end() const { return sentinel_wrapper(InputIter(buff + 8)); } + constexpr std::size_t size() const { return 8; } +}; +static_assert(std::ranges::sized_range<SizedInputRange>); + struct NotSizedSentinel { using value_type = int; using difference_type = std::ptrdiff_t; @@ -155,11 +163,24 @@ concept BoolOpInvocable = requires (T const& obj) { bool(obj); }; constexpr bool testEmpty() { static_assert(!EmptyInvocable<InputRange>); + // LWG 3715: `view_interface::empty` is overconstrained + static_assert(EmptyInvocable<SizedInputRange>); static_assert( EmptyInvocable<ForwardRange>); static_assert(!BoolOpInvocable<InputRange>); + static_assert(BoolOpInvocable<SizedInputRange>); static_assert( BoolOpInvocable<ForwardRange>); + SizedInputRange sizedInputRange; + assert(!sizedInputRange.empty()); + assert(!static_cast<SizedInputRange const&>(sizedInputRange).empty()); + + assert(sizedInputRange); + assert(static_cast<SizedInputRange const&>(sizedInputRange)); + + assert(!std::ranges::empty(sizedInputRange)); + assert(!std::ranges::empty(static_cast<SizedInputRange const&>(sizedInputRange))); + ForwardRange forwardRange; assert(!forwardRange.empty()); assert(!static_cast<ForwardRange const&>(forwardRange).empty()); -- GitLab From 211eebf44fb7076d59c2d683d9211f9d44e50cce Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu <siujoeng.lau@gmail.com> Date: Wed, 20 Mar 2024 01:49:31 -0700 Subject: [PATCH 198/307] [libc++][ranges] remove `__workaround_52970` (#85683) ## Abstract This pull request removes the `__workaround_52970` concept. This concept is a workaround for a bug described in #52970, which causes the compiler to trigger ADL on a pointer to an incomplete type in an SFINAE context. This bug is fixed in Clang 14. ## Reference - [[clang] Don't typo-fix an expression in a SFINAE context](https://reviews.llvm.org/D117603) - [[libc++] [ranges] ADL-proof the [range.access] CPOs.](https://reviews.llvm.org/D116239) --- libcxx/include/__concepts/class_or_enum.h | 5 ----- libcxx/include/__ranges/access.h | 4 ++-- libcxx/include/__ranges/data.h | 2 +- libcxx/include/__ranges/empty.h | 2 +- libcxx/include/__ranges/rbegin.h | 2 +- libcxx/include/__ranges/rend.h | 2 +- libcxx/include/__ranges/size.h | 2 +- 7 files changed, 7 insertions(+), 12 deletions(-) diff --git a/libcxx/include/__concepts/class_or_enum.h b/libcxx/include/__concepts/class_or_enum.h index c1b4a8c258f3..2739e31e14ba 100644 --- a/libcxx/include/__concepts/class_or_enum.h +++ b/libcxx/include/__concepts/class_or_enum.h @@ -28,11 +28,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Tp> concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; -// Work around Clang bug https://llvm.org/PR52970 -// TODO: remove this workaround once libc++ no longer has to support Clang 13 (it was fixed in Clang 14). -template <class _Tp> -concept __workaround_52970 = is_class_v<__remove_cvref_t<_Tp>> || is_union_v<__remove_cvref_t<_Tp>>; - #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__ranges/access.h b/libcxx/include/__ranges/access.h index 218b3928ecdc..3db4f11b40f2 100644 --- a/libcxx/include/__ranges/access.h +++ b/libcxx/include/__ranges/access.h @@ -41,7 +41,7 @@ concept __can_borrow = is_lvalue_reference_v<_Tp> || enable_borrowed_range<remov namespace ranges { namespace __begin { template <class _Tp> -concept __member_begin = __can_borrow<_Tp> && __workaround_52970<_Tp> && requires(_Tp&& __t) { +concept __member_begin = __can_borrow<_Tp> && requires(_Tp&& __t) { { _LIBCPP_AUTO_CAST(__t.begin()) } -> input_or_output_iterator; }; @@ -103,7 +103,7 @@ using iterator_t = decltype(ranges::begin(std::declval<_Tp&>())); namespace ranges { namespace __end { template <class _Tp> -concept __member_end = __can_borrow<_Tp> && __workaround_52970<_Tp> && requires(_Tp&& __t) { +concept __member_end = __can_borrow<_Tp> && requires(_Tp&& __t) { typename iterator_t<_Tp>; { _LIBCPP_AUTO_CAST(__t.end()) } -> sentinel_for<iterator_t<_Tp>>; }; diff --git a/libcxx/include/__ranges/data.h b/libcxx/include/__ranges/data.h index 18002bb52cc8..131f6cdad8f2 100644 --- a/libcxx/include/__ranges/data.h +++ b/libcxx/include/__ranges/data.h @@ -40,7 +40,7 @@ template <class _Tp> concept __ptr_to_object = is_pointer_v<_Tp> && is_object_v<remove_pointer_t<_Tp>>; template <class _Tp> -concept __member_data = __can_borrow<_Tp> && __workaround_52970<_Tp> && requires(_Tp&& __t) { +concept __member_data = __can_borrow<_Tp> && requires(_Tp&& __t) { { _LIBCPP_AUTO_CAST(__t.data()) } -> __ptr_to_object; }; diff --git a/libcxx/include/__ranges/empty.h b/libcxx/include/__ranges/empty.h index acd55dae224c..5c1004042aba 100644 --- a/libcxx/include/__ranges/empty.h +++ b/libcxx/include/__ranges/empty.h @@ -29,7 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __empty { template <class _Tp> -concept __member_empty = __workaround_52970<_Tp> && requires(_Tp&& __t) { bool(__t.empty()); }; +concept __member_empty = requires(_Tp&& __t) { bool(__t.empty()); }; template <class _Tp> concept __can_invoke_size = !__member_empty<_Tp> && requires(_Tp&& __t) { ranges::size(__t); }; diff --git a/libcxx/include/__ranges/rbegin.h b/libcxx/include/__ranges/rbegin.h index 947e428f00cd..12e739e1a2b8 100644 --- a/libcxx/include/__ranges/rbegin.h +++ b/libcxx/include/__ranges/rbegin.h @@ -36,7 +36,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __rbegin { template <class _Tp> -concept __member_rbegin = __can_borrow<_Tp> && __workaround_52970<_Tp> && requires(_Tp&& __t) { +concept __member_rbegin = __can_borrow<_Tp> && requires(_Tp&& __t) { { _LIBCPP_AUTO_CAST(__t.rbegin()) } -> input_or_output_iterator; }; diff --git a/libcxx/include/__ranges/rend.h b/libcxx/include/__ranges/rend.h index 1b6be58fea24..5edbc4e3160c 100644 --- a/libcxx/include/__ranges/rend.h +++ b/libcxx/include/__ranges/rend.h @@ -37,7 +37,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __rend { template <class _Tp> -concept __member_rend = __can_borrow<_Tp> && __workaround_52970<_Tp> && requires(_Tp&& __t) { +concept __member_rend = __can_borrow<_Tp> && requires(_Tp&& __t) { ranges::rbegin(__t); { _LIBCPP_AUTO_CAST(__t.rend()) } -> sentinel_for<decltype(ranges::rbegin(__t))>; }; diff --git a/libcxx/include/__ranges/size.h b/libcxx/include/__ranges/size.h index 59ca2b11ee38..40b0c6b6aad7 100644 --- a/libcxx/include/__ranges/size.h +++ b/libcxx/include/__ranges/size.h @@ -47,7 +47,7 @@ template <class _Tp> concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>; template <class _Tp> -concept __member_size = __size_enabled<_Tp> && __workaround_52970<_Tp> && requires(_Tp&& __t) { +concept __member_size = __size_enabled<_Tp> && requires(_Tp&& __t) { { _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like; }; -- GitLab From 070d1e83213f0e9eb71582141dd2323131a307e3 Mon Sep 17 00:00:00 2001 From: Pravin Jagtap <prjagtap@amd.com> Date: Wed, 20 Mar 2024 14:45:38 +0530 Subject: [PATCH 199/307] [AMDGPU] Add test for fpext & fptrunc with bf16. (#85909) Authored-by: Pravin Jagtap <Pravin.Jagtap@amd.com> --- llvm/test/CodeGen/AMDGPU/bf16-conversions.ll | 344 +++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 llvm/test/CodeGen/AMDGPU/bf16-conversions.ll diff --git a/llvm/test/CodeGen/AMDGPU/bf16-conversions.ll b/llvm/test/CodeGen/AMDGPU/bf16-conversions.ll new file mode 100644 index 000000000000..1eb2771618dc --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/bf16-conversions.ll @@ -0,0 +1,344 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -march=amdgcn -mcpu=gfx940 < %s | FileCheck --check-prefixes=GCN %s + +; TODO: Add global-isel when it can support bf16 +define amdgpu_ps float @v_test_cvt_bf16_f32_v(bfloat %v) { +; GCN-LABEL: v_test_cvt_bf16_f32_v: +; GCN: ; %bb.0: +; GCN-NEXT: v_lshlrev_b32_e32 v0, 16, v0 +; GCN-NEXT: ; return to shader part epilog + %cvt = fpext bfloat %v to float + ret float %cvt +} +define amdgpu_ps float @v_test_cvt_bf16_f32_s(bfloat inreg %v) { +; GCN-LABEL: v_test_cvt_bf16_f32_s: +; GCN: ; %bb.0: +; GCN-NEXT: s_lshl_b32 s0, s0, 16 +; GCN-NEXT: v_mov_b32_e32 v0, s0 +; GCN-NEXT: ; return to shader part epilog + %cvt = fpext bfloat %v to float + ret float %cvt +} +define amdgpu_ps float @v_test_cvt_v2f32_v2bf16_v(<2 x float> %src) { +; GCN-LABEL: v_test_cvt_v2f32_v2bf16_v: +; GCN: ; %bb.0: +; GCN-NEXT: v_bfe_u32 v2, v0, 16, 1 +; GCN-NEXT: s_movk_i32 s0, 0x7fff +; GCN-NEXT: v_add3_u32 v2, v2, v0, s0 +; GCN-NEXT: v_or_b32_e32 v3, 0x400000, v0 +; GCN-NEXT: v_cmp_u_f32_e32 vcc, v0, v0 +; GCN-NEXT: s_nop 1 +; GCN-NEXT: v_cndmask_b32_e32 v0, v2, v3, vcc +; GCN-NEXT: v_bfe_u32 v2, v1, 16, 1 +; GCN-NEXT: v_add3_u32 v2, v2, v1, s0 +; GCN-NEXT: v_or_b32_e32 v3, 0x400000, v1 +; GCN-NEXT: v_cmp_u_f32_e32 vcc, v1, v1 +; GCN-NEXT: s_mov_b32 s0, 0x7060302 +; GCN-NEXT: s_nop 0 +; GCN-NEXT: v_cndmask_b32_e32 v1, v2, v3, vcc +; GCN-NEXT: v_perm_b32 v0, v1, v0, s0 +; GCN-NEXT: ; return to shader part epilog + %res = fptrunc <2 x float> %src to <2 x bfloat> + %cast = bitcast <2 x bfloat> %res to float + ret float %cast +} +define amdgpu_ps float @v_test_cvt_v2f32_v2bf16_s(<2 x float> inreg %src) { +; GCN-LABEL: v_test_cvt_v2f32_v2bf16_s: +; GCN: ; %bb.0: +; GCN-NEXT: s_bfe_u32 s2, s1, 0x10010 +; GCN-NEXT: s_add_i32 s2, s2, s1 +; GCN-NEXT: s_or_b32 s4, s1, 0x400000 +; GCN-NEXT: s_add_i32 s5, s2, 0x7fff +; GCN-NEXT: v_cmp_u_f32_e64 s[2:3], s1, s1 +; GCN-NEXT: s_and_b64 s[2:3], s[2:3], exec +; GCN-NEXT: s_cselect_b32 s2, s4, s5 +; GCN-NEXT: s_bfe_u32 s1, s0, 0x10010 +; GCN-NEXT: s_add_i32 s1, s1, s0 +; GCN-NEXT: s_or_b32 s3, s0, 0x400000 +; GCN-NEXT: s_add_i32 s4, s1, 0x7fff +; GCN-NEXT: v_cmp_u_f32_e64 s[0:1], s0, s0 +; GCN-NEXT: s_and_b64 s[0:1], s[0:1], exec +; GCN-NEXT: s_cselect_b32 s0, s3, s4 +; GCN-NEXT: s_pack_hh_b32_b16 s0, s0, s2 +; GCN-NEXT: v_mov_b32_e32 v0, s0 +; GCN-NEXT: ; return to shader part epilog + %res = fptrunc <2 x float> %src to <2 x bfloat> + %cast = bitcast <2 x bfloat> %res to float + ret float %cast +} +define amdgpu_ps float @v_test_cvt_f32_bf16_v(float %src) { +; GCN-LABEL: v_test_cvt_f32_bf16_v: +; GCN: ; %bb.0: +; GCN-NEXT: v_bfe_u32 v1, v0, 16, 1 +; GCN-NEXT: s_movk_i32 s0, 0x7fff +; GCN-NEXT: v_add3_u32 v1, v1, v0, s0 +; GCN-NEXT: v_or_b32_e32 v2, 0x400000, v0 +; GCN-NEXT: v_cmp_u_f32_e32 vcc, v0, v0 +; GCN-NEXT: s_nop 1 +; GCN-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc +; GCN-NEXT: v_and_b32_e32 v0, 0xffff0000, v0 +; GCN-NEXT: ; return to shader part epilog + %trunc = fptrunc float %src to bfloat + %ext = fpext bfloat %trunc to float + ret float %ext +} +define amdgpu_ps float @v_test_cvt_v2f64_v2bf16_v(<2 x double> %src) { +; GCN-LABEL: v_test_cvt_v2f64_v2bf16_v: +; GCN: ; %bb.0: +; GCN-NEXT: v_cvt_f32_f64_e64 v6, |v[0:1]| +; GCN-NEXT: v_cvt_f64_f32_e32 v[4:5], v6 +; GCN-NEXT: v_and_b32_e32 v7, 1, v6 +; GCN-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[0:1]|, v[4:5] +; GCN-NEXT: v_cmp_nlg_f64_e64 s[0:1], |v[0:1]|, v[4:5] +; GCN-NEXT: v_cmp_eq_u32_e32 vcc, 1, v7 +; GCN-NEXT: v_cndmask_b32_e64 v4, -1, 1, s[2:3] +; GCN-NEXT: v_add_u32_e32 v4, v6, v4 +; GCN-NEXT: s_or_b64 vcc, s[0:1], vcc +; GCN-NEXT: v_cndmask_b32_e32 v4, v4, v6, vcc +; GCN-NEXT: s_brev_b32 s4, 1 +; GCN-NEXT: v_and_or_b32 v5, v1, s4, v4 +; GCN-NEXT: v_bfe_u32 v4, v4, 16, 1 +; GCN-NEXT: s_movk_i32 s5, 0x7fff +; GCN-NEXT: v_add3_u32 v4, v4, v5, s5 +; GCN-NEXT: v_or_b32_e32 v5, 0x400000, v5 +; GCN-NEXT: v_cmp_u_f64_e32 vcc, v[0:1], v[0:1] +; GCN-NEXT: s_nop 1 +; GCN-NEXT: v_cndmask_b32_e32 v4, v4, v5, vcc +; GCN-NEXT: v_cvt_f32_f64_e64 v5, |v[2:3]| +; GCN-NEXT: v_cvt_f64_f32_e32 v[0:1], v5 +; GCN-NEXT: v_and_b32_e32 v6, 1, v5 +; GCN-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[2:3]|, v[0:1] +; GCN-NEXT: v_cmp_nlg_f64_e64 s[0:1], |v[2:3]|, v[0:1] +; GCN-NEXT: v_cmp_eq_u32_e32 vcc, 1, v6 +; GCN-NEXT: v_cndmask_b32_e64 v0, -1, 1, s[2:3] +; GCN-NEXT: v_add_u32_e32 v0, v5, v0 +; GCN-NEXT: s_or_b64 vcc, s[0:1], vcc +; GCN-NEXT: v_cndmask_b32_e32 v0, v0, v5, vcc +; GCN-NEXT: v_and_or_b32 v1, v3, s4, v0 +; GCN-NEXT: v_bfe_u32 v0, v0, 16, 1 +; GCN-NEXT: v_add3_u32 v0, v0, v1, s5 +; GCN-NEXT: v_or_b32_e32 v1, 0x400000, v1 +; GCN-NEXT: v_cmp_u_f64_e32 vcc, v[2:3], v[2:3] +; GCN-NEXT: s_mov_b32 s0, 0x7060302 +; GCN-NEXT: s_nop 0 +; GCN-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc +; GCN-NEXT: v_perm_b32 v0, v0, v4, s0 +; GCN-NEXT: ; return to shader part epilog + %res = fptrunc <2 x double> %src to <2 x bfloat> + %cast = bitcast <2 x bfloat> %res to float + ret float %cast +} +define amdgpu_ps float @fptrunc_f32_f32_to_v2bf16(float %a, float %b) { +; GCN-LABEL: fptrunc_f32_f32_to_v2bf16: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: v_bfe_u32 v2, v0, 16, 1 +; GCN-NEXT: s_movk_i32 s0, 0x7fff +; GCN-NEXT: v_add3_u32 v2, v2, v0, s0 +; GCN-NEXT: v_or_b32_e32 v3, 0x400000, v0 +; GCN-NEXT: v_cmp_u_f32_e32 vcc, v0, v0 +; GCN-NEXT: s_nop 1 +; GCN-NEXT: v_cndmask_b32_e32 v0, v2, v3, vcc +; GCN-NEXT: v_bfe_u32 v2, v1, 16, 1 +; GCN-NEXT: v_add3_u32 v2, v2, v1, s0 +; GCN-NEXT: v_or_b32_e32 v3, 0x400000, v1 +; GCN-NEXT: v_cmp_u_f32_e32 vcc, v1, v1 +; GCN-NEXT: s_mov_b32 s0, 0x7060302 +; GCN-NEXT: s_nop 0 +; GCN-NEXT: v_cndmask_b32_e32 v1, v2, v3, vcc +; GCN-NEXT: v_perm_b32 v0, v1, v0, s0 +; GCN-NEXT: ; return to shader part epilog +entry: + %a.cvt = fptrunc float %a to bfloat + %b.cvt = fptrunc float %b to bfloat + %v2.1 = insertelement <2 x bfloat> undef, bfloat %a.cvt, i32 0 + %v2.2 = insertelement <2 x bfloat> %v2.1, bfloat %b.cvt, i32 1 + %ret = bitcast <2 x bfloat> %v2.2 to float + ret float %ret +} +define amdgpu_ps float @fptrunc_f32_f32_to_v2bf16_mods(float %a, float %b) { +; GCN-LABEL: fptrunc_f32_f32_to_v2bf16_mods: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: v_xor_b32_e32 v2, 0x80000000, v0 +; GCN-NEXT: v_bfe_u32 v3, v2, 16, 1 +; GCN-NEXT: s_movk_i32 s0, 0x7fff +; GCN-NEXT: v_add3_u32 v3, v3, v2, s0 +; GCN-NEXT: v_or_b32_e32 v2, 0x400000, v2 +; GCN-NEXT: v_cmp_u_f32_e64 vcc, -v0, -v0 +; GCN-NEXT: s_nop 1 +; GCN-NEXT: v_cndmask_b32_e32 v0, v3, v2, vcc +; GCN-NEXT: v_and_b32_e32 v2, 0x7fffffff, v1 +; GCN-NEXT: v_bfe_u32 v3, v2, 16, 1 +; GCN-NEXT: v_add3_u32 v3, v3, v2, s0 +; GCN-NEXT: v_or_b32_e32 v2, 0x400000, v2 +; GCN-NEXT: v_cmp_u_f32_e64 vcc, |v1|, |v1| +; GCN-NEXT: s_mov_b32 s0, 0x7060302 +; GCN-NEXT: s_nop 0 +; GCN-NEXT: v_cndmask_b32_e32 v1, v3, v2, vcc +; GCN-NEXT: v_perm_b32 v0, v1, v0, s0 +; GCN-NEXT: ; return to shader part epilog +entry: + %a.neg = fneg float %a + %a.cvt = fptrunc float %a.neg to bfloat + %b.abs = call float @llvm.fabs.f32(float %b) + %b.cvt = fptrunc float %b.abs to bfloat + %v2.1 = insertelement <2 x bfloat> undef, bfloat %a.cvt, i32 0 + %v2.2 = insertelement <2 x bfloat> %v2.1, bfloat %b.cvt, i32 1 + %ret = bitcast <2 x bfloat> %v2.2 to float + ret float %ret +} +define amdgpu_ps void @fptrunc_f32_to_bf16(float %a, ptr %out) { +; GCN-LABEL: fptrunc_f32_to_bf16: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: v_mov_b32_e32 v3, v2 +; GCN-NEXT: v_mov_b32_e32 v2, v1 +; GCN-NEXT: v_bfe_u32 v1, v0, 16, 1 +; GCN-NEXT: s_movk_i32 s0, 0x7fff +; GCN-NEXT: v_add3_u32 v1, v1, v0, s0 +; GCN-NEXT: v_or_b32_e32 v4, 0x400000, v0 +; GCN-NEXT: v_cmp_u_f32_e32 vcc, v0, v0 +; GCN-NEXT: s_nop 1 +; GCN-NEXT: v_cndmask_b32_e32 v0, v1, v4, vcc +; GCN-NEXT: flat_store_short_d16_hi v[2:3], v0 sc0 sc1 +; GCN-NEXT: s_endpgm +entry: + %a.cvt = fptrunc float %a to bfloat + store bfloat %a.cvt, ptr %out + ret void +} +define amdgpu_ps void @fptrunc_f32_to_bf16_abs(float %a, ptr %out) { +; GCN-LABEL: fptrunc_f32_to_bf16_abs: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: v_mov_b32_e32 v3, v2 +; GCN-NEXT: v_mov_b32_e32 v2, v1 +; GCN-NEXT: v_and_b32_e32 v1, 0x7fffffff, v0 +; GCN-NEXT: v_bfe_u32 v4, v1, 16, 1 +; GCN-NEXT: s_movk_i32 s0, 0x7fff +; GCN-NEXT: v_add3_u32 v4, v4, v1, s0 +; GCN-NEXT: v_or_b32_e32 v1, 0x400000, v1 +; GCN-NEXT: v_cmp_u_f32_e64 vcc, |v0|, |v0| +; GCN-NEXT: s_nop 1 +; GCN-NEXT: v_cndmask_b32_e32 v0, v4, v1, vcc +; GCN-NEXT: flat_store_short_d16_hi v[2:3], v0 sc0 sc1 +; GCN-NEXT: s_endpgm +entry: + %a.abs = call float @llvm.fabs.f32(float %a) + %a.cvt = fptrunc float %a.abs to bfloat + store bfloat %a.cvt, ptr %out + ret void +} +define amdgpu_ps void @fptrunc_f32_to_bf16_neg(float %a, ptr %out) { +; GCN-LABEL: fptrunc_f32_to_bf16_neg: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: v_mov_b32_e32 v3, v2 +; GCN-NEXT: v_mov_b32_e32 v2, v1 +; GCN-NEXT: v_xor_b32_e32 v1, 0x80000000, v0 +; GCN-NEXT: v_bfe_u32 v4, v1, 16, 1 +; GCN-NEXT: s_movk_i32 s0, 0x7fff +; GCN-NEXT: v_add3_u32 v4, v4, v1, s0 +; GCN-NEXT: v_or_b32_e32 v1, 0x400000, v1 +; GCN-NEXT: v_cmp_u_f32_e64 vcc, -v0, -v0 +; GCN-NEXT: s_nop 1 +; GCN-NEXT: v_cndmask_b32_e32 v0, v4, v1, vcc +; GCN-NEXT: flat_store_short_d16_hi v[2:3], v0 sc0 sc1 +; GCN-NEXT: s_endpgm +entry: + %a.neg = fneg float %a + %a.cvt = fptrunc float %a.neg to bfloat + store bfloat %a.cvt, ptr %out + ret void +} +define amdgpu_ps void @fptrunc_f64_to_bf16(double %a, ptr %out) { +; GCN-LABEL: fptrunc_f64_to_bf16: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: v_cvt_f32_f64_e64 v6, |v[0:1]| +; GCN-NEXT: v_cvt_f64_f32_e32 v[4:5], v6 +; GCN-NEXT: v_and_b32_e32 v7, 1, v6 +; GCN-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[0:1]|, v[4:5] +; GCN-NEXT: v_cmp_nlg_f64_e64 s[0:1], |v[0:1]|, v[4:5] +; GCN-NEXT: v_cmp_eq_u32_e32 vcc, 1, v7 +; GCN-NEXT: v_cndmask_b32_e64 v4, -1, 1, s[2:3] +; GCN-NEXT: v_add_u32_e32 v4, v6, v4 +; GCN-NEXT: s_or_b64 vcc, s[0:1], vcc +; GCN-NEXT: v_cndmask_b32_e32 v4, v4, v6, vcc +; GCN-NEXT: s_brev_b32 s0, 1 +; GCN-NEXT: v_and_or_b32 v5, v1, s0, v4 +; GCN-NEXT: v_bfe_u32 v4, v4, 16, 1 +; GCN-NEXT: s_movk_i32 s0, 0x7fff +; GCN-NEXT: v_add3_u32 v4, v4, v5, s0 +; GCN-NEXT: v_or_b32_e32 v5, 0x400000, v5 +; GCN-NEXT: v_cmp_u_f64_e32 vcc, v[0:1], v[0:1] +; GCN-NEXT: s_nop 1 +; GCN-NEXT: v_cndmask_b32_e32 v0, v4, v5, vcc +; GCN-NEXT: flat_store_short_d16_hi v[2:3], v0 sc0 sc1 +; GCN-NEXT: s_endpgm +entry: + %a.cvt = fptrunc double %a to bfloat + store bfloat %a.cvt, ptr %out + ret void +} +define amdgpu_ps void @fptrunc_f64_to_bf16_neg(double %a, ptr %out) { +; GCN-LABEL: fptrunc_f64_to_bf16_neg: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: v_cvt_f32_f64_e64 v7, |v[0:1]| +; GCN-NEXT: v_cvt_f64_f32_e32 v[4:5], v7 +; GCN-NEXT: v_and_b32_e32 v8, 1, v7 +; GCN-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[0:1]|, v[4:5] +; GCN-NEXT: v_cmp_nlg_f64_e64 s[0:1], |v[0:1]|, v[4:5] +; GCN-NEXT: v_cmp_eq_u32_e32 vcc, 1, v8 +; GCN-NEXT: v_cndmask_b32_e64 v4, -1, 1, s[2:3] +; GCN-NEXT: v_add_u32_e32 v4, v7, v4 +; GCN-NEXT: s_or_b64 vcc, s[0:1], vcc +; GCN-NEXT: s_brev_b32 s4, 1 +; GCN-NEXT: v_xor_b32_e32 v6, 0x80000000, v1 +; GCN-NEXT: v_cndmask_b32_e32 v4, v4, v7, vcc +; GCN-NEXT: v_and_or_b32 v5, v6, s4, v4 +; GCN-NEXT: v_bfe_u32 v4, v4, 16, 1 +; GCN-NEXT: s_movk_i32 s0, 0x7fff +; GCN-NEXT: v_add3_u32 v4, v4, v5, s0 +; GCN-NEXT: v_or_b32_e32 v5, 0x400000, v5 +; GCN-NEXT: v_cmp_u_f64_e64 vcc, -v[0:1], -v[0:1] +; GCN-NEXT: s_nop 1 +; GCN-NEXT: v_cndmask_b32_e32 v0, v4, v5, vcc +; GCN-NEXT: flat_store_short_d16_hi v[2:3], v0 sc0 sc1 +; GCN-NEXT: s_endpgm +entry: + %a.neg = fneg double %a + %a.cvt = fptrunc double %a.neg to bfloat + store bfloat %a.cvt, ptr %out + ret void +} +define amdgpu_ps void @fptrunc_f64_to_bf16_abs(double %a, ptr %out) { +; GCN-LABEL: fptrunc_f64_to_bf16_abs: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: v_cvt_f32_f64_e64 v7, |v[0:1]| +; GCN-NEXT: v_cvt_f64_f32_e32 v[4:5], v7 +; GCN-NEXT: v_and_b32_e32 v8, 1, v7 +; GCN-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[0:1]|, v[4:5] +; GCN-NEXT: v_cmp_nlg_f64_e64 s[0:1], |v[0:1]|, v[4:5] +; GCN-NEXT: v_cmp_eq_u32_e32 vcc, 1, v8 +; GCN-NEXT: v_cndmask_b32_e64 v4, -1, 1, s[2:3] +; GCN-NEXT: v_add_u32_e32 v4, v7, v4 +; GCN-NEXT: s_or_b64 vcc, s[0:1], vcc +; GCN-NEXT: v_and_b32_e32 v6, 0x7fffffff, v1 +; GCN-NEXT: v_cndmask_b32_e32 v4, v4, v7, vcc +; GCN-NEXT: s_brev_b32 s0, 1 +; GCN-NEXT: v_and_or_b32 v5, v6, s0, v4 +; GCN-NEXT: v_bfe_u32 v4, v4, 16, 1 +; GCN-NEXT: s_movk_i32 s0, 0x7fff +; GCN-NEXT: v_add3_u32 v4, v4, v5, s0 +; GCN-NEXT: v_or_b32_e32 v5, 0x400000, v5 +; GCN-NEXT: v_cmp_u_f64_e64 vcc, |v[0:1]|, |v[0:1]| +; GCN-NEXT: s_nop 1 +; GCN-NEXT: v_cndmask_b32_e32 v0, v4, v5, vcc +; GCN-NEXT: flat_store_short_d16_hi v[2:3], v0 sc0 sc1 +; GCN-NEXT: s_endpgm +entry: + %a.abs = call double @llvm.fabs.f64(double %a) + %a.cvt = fptrunc double %a.abs to bfloat + store bfloat %a.cvt, ptr %out + ret void +} + +declare float @llvm.fabs.f32(float) +declare double @llvm.fabs.f64(double) + -- GitLab From e6b5bd5854c80eac05f415ad282ba84b840b8af8 Mon Sep 17 00:00:00 2001 From: Alexandros Lamprineas <alexandros.lamprineas@arm.com> Date: Wed, 20 Mar 2024 09:24:29 +0000 Subject: [PATCH 200/307] [FMV] Emit the resolver along with the default version definition. (#84405) We would like the resolver to be generated eagerly, even if the versioned function is not called from the current translation unit. Fixes #81494. It further allows Multi Versioning to work even if the default target version attribute is omitted from function declarations. --- clang/lib/CodeGen/CodeGenModule.cpp | 55 +- clang/lib/CodeGen/CodeGenModule.h | 5 + clang/test/CodeGen/attr-target-version.c | 546 ++++++++++++------ clang/test/CodeGenCXX/attr-target-version.cpp | 261 +++++++-- 4 files changed, 629 insertions(+), 238 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index bb26bfcddaeb..cb153066b28d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3449,6 +3449,9 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) { // Implicit template instantiations may change linkage if they are later // explicitly instantiated, so they should not be emitted eagerly. return false; + // Defer until all versions have been semantically checked. + if (FD->hasAttr<TargetVersionAttr>() && !FD->isMultiVersion()) + return false; } if (const auto *VD = dyn_cast<VarDecl>(Global)) { if (Context.getInlineVariableDefinitionKind(VD) == @@ -3997,10 +4000,13 @@ void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD, EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr); // Ensure that the resolver function is also emitted. GetOrCreateMultiVersionResolver(GD); - } else if (FD->hasAttr<TargetVersionAttr>()) { - GetOrCreateMultiVersionResolver(GD); } else EmitGlobalFunctionDefinition(GD, GV); + + // Defer the resolver emission until we can reason whether the TU + // contains a default target version implementation. + if (FD->isTargetVersionMultiVersion()) + AddDeferredMultiVersionResolverToEmit(GD); } void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { @@ -4093,10 +4099,11 @@ void CodeGenModule::emitMultiVersionFunctions() { const auto *FD = cast<FunctionDecl>(GD.getDecl()); assert(FD && "Expected a FunctionDecl"); + bool EmitResolver = !FD->isTargetVersionMultiVersion(); SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options; if (FD->isTargetMultiVersion()) { getContext().forEachMultiversionedFunctionVersion( - FD, [this, &GD, &Options](const FunctionDecl *CurFD) { + FD, [this, &GD, &Options, &EmitResolver](const FunctionDecl *CurFD) { GlobalDecl CurGD{ (CurFD->isDefined() ? CurFD->getDefinition() : CurFD)}; StringRef MangledName = getMangledName(CurGD); @@ -4122,6 +4129,9 @@ void CodeGenModule::emitMultiVersionFunctions() { TA->getArchitecture(), Feats); } else { const auto *TVA = CurFD->getAttr<TargetVersionAttr>(); + if (CurFD->isUsed() || (TVA->isDefaultVersion() && + CurFD->doesThisDeclarationHaveABody())) + EmitResolver = true; llvm::SmallVector<StringRef, 8> Feats; TVA->getFeatures(Feats); Options.emplace_back(cast<llvm::Function>(Func), @@ -4177,22 +4187,27 @@ void CodeGenModule::emitMultiVersionFunctions() { continue; } + if (!EmitResolver) + continue; + llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver(GD); if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) { ResolverConstant = IFunc->getResolver(); if (FD->isTargetClonesMultiVersion() || FD->isTargetVersionMultiVersion()) { - const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); - llvm::FunctionType *DeclTy = getTypes().GetFunctionType(FI); std::string MangledName = getMangledNameImpl( *this, GD, FD, /*OmitMultiVersionMangling=*/true); - // In prior versions of Clang, the mangling for ifuncs incorrectly - // included an .ifunc suffix. This alias is generated for backward - // compatibility. It is deprecated, and may be removed in the future. - auto *Alias = llvm::GlobalAlias::create( - DeclTy, 0, getMultiversionLinkage(*this, GD), - MangledName + ".ifunc", IFunc, &getModule()); - SetCommonAttributes(FD, Alias); + if (!GetGlobalValue(MangledName + ".ifunc")) { + const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); + llvm::FunctionType *DeclTy = getTypes().GetFunctionType(FI); + // In prior versions of Clang, the mangling for ifuncs incorrectly + // included an .ifunc suffix. This alias is generated for backward + // compatibility. It is deprecated, and may be removed in the future. + auto *Alias = llvm::GlobalAlias::create( + DeclTy, 0, getMultiversionLinkage(*this, GD), + MangledName + ".ifunc", IFunc, &getModule()); + SetCommonAttributes(FD, Alias); + } } } llvm::Function *ResolverFunc = cast<llvm::Function>(ResolverConstant); @@ -4349,6 +4364,20 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { } } +/// Adds a declaration to the list of multi version functions if not present. +void CodeGenModule::AddDeferredMultiVersionResolverToEmit(GlobalDecl GD) { + const auto *FD = cast<FunctionDecl>(GD.getDecl()); + assert(FD && "Not a FunctionDecl?"); + + if (FD->isTargetVersionMultiVersion()) { + std::string MangledName = + getMangledNameImpl(*this, GD, FD, /*OmitMultiVersionMangling=*/true); + if (!DeferredResolversToEmit.insert(MangledName).second) + return; + } + MultiVersionFuncs.push_back(GD); +} + /// If a dispatcher for the specified mangled name is not in the module, create /// and return an llvm Function with the specified type. llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { @@ -4388,7 +4417,7 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { // The resolver needs to be created. For target and target_clones, defer // creation until the end of the TU. if (FD->isTargetMultiVersion() || FD->isTargetClonesMultiVersion()) - MultiVersionFuncs.push_back(GD); + AddDeferredMultiVersionResolverToEmit(GD); // For cpu_specific, don't create an ifunc yet because we don't know if the // cpu_dispatch will be emitted in this translation unit. diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index ec34680fd3f7..1cc447765e2c 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -348,6 +348,8 @@ private: /// yet. llvm::DenseMap<StringRef, GlobalDecl> DeferredDecls; + llvm::StringSet<llvm::BumpPtrAllocator> DeferredResolversToEmit; + /// This is a list of deferred decls which we have seen that *are* actually /// referenced. These get code generated when the module is done. std::vector<GlobalDecl> DeferredDeclsToEmit; @@ -1588,6 +1590,9 @@ private: llvm::AttributeList ExtraAttrs = llvm::AttributeList(), ForDefinition_t IsForDefinition = NotForDefinition); + // Adds a declaration to the list of multi version functions if not present. + void AddDeferredMultiVersionResolverToEmit(GlobalDecl GD); + // References to multiversion functions are resolved through an implicitly // defined resolver function. This function is responsible for creating // the resolver symbol for the provided declaration. The value returned diff --git a/clang/test/CodeGen/attr-target-version.c b/clang/test/CodeGen/attr-target-version.c index b7112c783da9..fc8bb680fe43 100644 --- a/clang/test/CodeGen/attr-target-version.c +++ b/clang/test/CodeGen/attr-target-version.c @@ -1,5 +1,5 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals --include-generated-funcs -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +ls64 -target-feature +fullfp16 -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -v9.5a -S -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fmv -S -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NOFMV int __attribute__((target_version("rng+flagm+fp16fml"))) fmv(void) { return 1; } @@ -11,15 +11,15 @@ int __attribute__((target_version("fp+aes"))) fmv(void) { return 6; } int __attribute__((target_version("crc+ls64_v"))) fmv(void) { return 7; } int __attribute__((target_version("bti"))) fmv(void) { return 8; } int __attribute__((target_version("sme2"))) fmv(void) { return 9; } -int __attribute__((target_version("default"))) fmv(void) { return 0; } +int __attribute__((target_version("default"))) fmv(void); int __attribute__((target_version("ls64+simd"))) fmv_one(void) { return 1; } int __attribute__((target_version("dpb"))) fmv_one(void) { return 2; } -int __attribute__((target_version("default"))) fmv_one(void) { return 0; } +int __attribute__((target_version("default"))) fmv_one(void); int __attribute__((target_version("fp"))) fmv_two(void) { return 1; } int __attribute__((target_version("simd"))) fmv_two(void) { return 2; } int __attribute__((target_version("dgh"))) fmv_two(void) { return 3; } int __attribute__((target_version("fp16+simd"))) fmv_two(void) { return 4; } -int __attribute__((target_version("default"))) fmv_two(void) { return 0; } +int __attribute__((target_version("default"))) fmv_two(void); int foo() { return fmv()+fmv_one()+fmv_two(); } @@ -84,9 +84,33 @@ int hoo(void) { return fp1() + fp2(); } +// This should generate one target version but no resolver. +__attribute__((target_version("default"))) int unused_with_forward_default_decl(void); +__attribute__((target_version("mops"))) int unused_with_forward_default_decl(void) { return 0; } +// This should also generate one target version but no resolver. +extern int unused_with_implicit_extern_forward_default_decl(void); +__attribute__((target_version("dotprod"))) +int unused_with_implicit_extern_forward_default_decl(void) { return 0; } +// This should also generate one target version but no resolver. +__attribute__((target_version("aes"))) int unused_with_default_decl(void) { return 0; } +__attribute__((target_version("default"))) int unused_with_default_decl(void); +// This should generate two target versions and the resolver. +__attribute__((target_version("sve"))) int unused_with_default_def(void) { return 0; } +__attribute__((target_version("default"))) int unused_with_default_def(void) { return 1; } + +// This should also generate two target versions and the resolver. +__attribute__((target_version("fp16"))) int unused_with_implicit_default_def(void) { return 0; } +int unused_with_implicit_default_def(void) { return 1; } + +// This should also generate two target versions and the resolver. +int unused_with_implicit_forward_default_def(void) { return 0; } +__attribute__((target_version("lse"))) int unused_with_implicit_forward_default_def(void) { return 1; } + +// This should generate a normal function. +__attribute__((target_version("rdm"))) int unused_without_default(void) { return 0; } //. // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } @@ -97,38 +121,107 @@ int hoo(void) { // CHECK: @fmv_c.ifunc = weak_odr alias void (), ptr @fmv_c // CHECK: @fmv_inline.ifunc = weak_odr alias i32 (), ptr @fmv_inline // CHECK: @fmv_d.ifunc = internal alias i32 (), ptr @fmv_d +// CHECK: @unused_with_default_def.ifunc = weak_odr alias i32 (), ptr @unused_with_default_def +// CHECK: @unused_with_implicit_default_def.ifunc = weak_odr alias i32 (), ptr @unused_with_implicit_default_def +// CHECK: @unused_with_implicit_forward_default_def.ifunc = weak_odr alias i32 (), ptr @unused_with_implicit_forward_default_def // CHECK: @fmv = weak_odr ifunc i32 (), ptr @fmv.resolver // CHECK: @fmv_one = weak_odr ifunc i32 (), ptr @fmv_one.resolver // CHECK: @fmv_two = weak_odr ifunc i32 (), ptr @fmv_two.resolver -// CHECK: @fmv_e = weak_odr ifunc i32 (), ptr @fmv_e.resolver -// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver // CHECK: @fmv_inline = weak_odr ifunc i32 (), ptr @fmv_inline.resolver +// CHECK: @fmv_e = weak_odr ifunc i32 (), ptr @fmv_e.resolver // CHECK: @fmv_d = internal ifunc i32 (), ptr @fmv_d.resolver +// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver +// CHECK: @unused_with_default_def = weak_odr ifunc i32 (), ptr @unused_with_default_def.resolver +// CHECK: @unused_with_implicit_default_def = weak_odr ifunc i32 (), ptr @unused_with_implicit_default_def.resolver +// CHECK: @unused_with_implicit_forward_default_def = weak_odr ifunc i32 (), ptr @unused_with_implicit_forward_default_def.resolver //. // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MflagmMfp16fmlMrng +// CHECK-LABEL: define {{[^@]+}}@fmv._Mflagm2Msme-i16i64 // CHECK-SAME: () #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 2 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mls64Msimd +// CHECK-LABEL: define {{[^@]+}}@fmv._MlseMsha2 // CHECK-SAME: () #[[ATTR1:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 3 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp -// CHECK-SAME: () #[[ATTR1]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._MdotprodMls64_accdata +// CHECK-SAME: () #[[ATTR2:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 4 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._Mfp16fmlMmemtag +// CHECK-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 5 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._MaesMfp +// CHECK-SAME: () #[[ATTR4:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 6 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._McrcMls64_v +// CHECK-SAME: () #[[ATTR5:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 7 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._Mbti +// CHECK-SAME: () #[[ATTR6:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 8 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._Msme2 +// CHECK-SAME: () #[[ATTR7:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 9 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mdpb +// CHECK-SAME: () #[[ATTR8:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 2 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Msimd +// CHECK-SAME: () #[[ATTR4]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 2 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mdgh +// CHECK-SAME: () #[[ATTR9:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 3 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp16Msimd +// CHECK-SAME: () #[[ATTR10:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 4 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@foo -// CHECK-SAME: () #[[ATTR2:[0-9]+]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv() // CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_one() @@ -158,16 +251,16 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv._Mflagm2Msme-i16i64 // CHECK: resolver_else2: // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 16 -// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16 +// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 9007199254741008 +// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 9007199254741008 // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] // CHECK: resolver_return3: // CHECK-NEXT: ret ptr @fmv._MdotprodMls64_accdata // CHECK: resolver_else4: // CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 1024 -// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 1024 +// CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 4503599627371520 +// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 4503599627371520 // CHECK-NEXT: [[TMP15:%.*]] = and i1 true, [[TMP14]] // CHECK-NEXT: br i1 [[TMP15]], label [[RESOLVER_RETURN5:%.*]], label [[RESOLVER_ELSE6:%.*]] // CHECK: resolver_return5: @@ -182,8 +275,8 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv._Mfp16fmlMmemtag // CHECK: resolver_else8: // CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 16384 -// CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 16384 +// CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 16640 +// CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 16640 // CHECK-NEXT: [[TMP23:%.*]] = and i1 true, [[TMP22]] // CHECK-NEXT: br i1 [[TMP23]], label [[RESOLVER_RETURN9:%.*]], label [[RESOLVER_ELSE10:%.*]] // CHECK: resolver_return9: @@ -218,43 +311,95 @@ int hoo(void) { // // CHECK-LABEL: define {{[^@]+}}@fmv_one.resolver() comdat { // CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2251799813685760 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2251799813685760 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: // CHECK-NEXT: ret ptr @fmv_one._Mls64Msimd +// CHECK: resolver_else: +// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 262144 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 262144 +// CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] +// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] +// CHECK: resolver_return1: +// CHECK-NEXT: ret ptr @fmv_one._Mdpb +// CHECK: resolver_else2: +// CHECK-NEXT: ret ptr @fmv_one.default // // // CHECK-LABEL: define {{[^@]+}}@fmv_two.resolver() comdat { // CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 66048 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 66048 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: // CHECK-NEXT: ret ptr @fmv_two._Mfp16Msimd +// CHECK: resolver_else: +// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 33554432 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 33554432 +// CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] +// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] +// CHECK: resolver_return1: +// CHECK-NEXT: ret ptr @fmv_two._Mdgh +// CHECK: resolver_else2: +// CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 512 +// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 512 +// CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] +// CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] +// CHECK: resolver_return3: +// CHECK-NEXT: ret ptr @fmv_two._Msimd +// CHECK: resolver_else4: +// CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 256 +// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 256 +// CHECK-NEXT: [[TMP15:%.*]] = and i1 true, [[TMP14]] +// CHECK-NEXT: br i1 [[TMP15]], label [[RESOLVER_RETURN5:%.*]], label [[RESOLVER_ELSE6:%.*]] +// CHECK: resolver_return5: +// CHECK-NEXT: ret ptr @fmv_two._Mfp +// CHECK: resolver_else6: +// CHECK-NEXT: ret ptr @fmv_two.default // // -// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: ret ptr @fmv_e._Mls64 +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_e.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 20 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 111 // // -// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: -// CHECK-NEXT: ret ptr @fmv_c._Mssbs -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @fmv_c.default +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret void +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_c.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret void // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@goo -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv_inline() // CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_e() @@ -268,8 +413,8 @@ int hoo(void) { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398048608320 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398048608320 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398048673856 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398048673856 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: @@ -364,8 +509,8 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv_inline._Mdpb2Mjscvt // CHECK: resolver_else22: // CHECK-NEXT: [[TMP48:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP49:%.*]] = and i64 [[TMP48]], 8 -// CHECK-NEXT: [[TMP50:%.*]] = icmp eq i64 [[TMP49]], 8 +// CHECK-NEXT: [[TMP49:%.*]] = and i64 [[TMP48]], 520 +// CHECK-NEXT: [[TMP50:%.*]] = icmp eq i64 [[TMP49]], 520 // CHECK-NEXT: [[TMP51:%.*]] = and i1 true, [[TMP50]] // CHECK-NEXT: br i1 [[TMP51]], label [[RESOLVER_RETURN23:%.*]], label [[RESOLVER_ELSE24:%.*]] // CHECK: resolver_return23: @@ -388,8 +533,8 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv_inline._MlseMrdm // CHECK: resolver_else28: // CHECK-NEXT: [[TMP60:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP61:%.*]] = and i64 [[TMP60]], 32 -// CHECK-NEXT: [[TMP62:%.*]] = icmp eq i64 [[TMP61]], 32 +// CHECK-NEXT: [[TMP61:%.*]] = and i64 [[TMP60]], 288 +// CHECK-NEXT: [[TMP62:%.*]] = icmp eq i64 [[TMP61]], 288 // CHECK-NEXT: [[TMP63:%.*]] = and i1 true, [[TMP62]] // CHECK-NEXT: br i1 [[TMP63]], label [[RESOLVER_RETURN29:%.*]], label [[RESOLVER_ELSE30:%.*]] // CHECK: resolver_return29: @@ -398,6 +543,20 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv_inline.default // // +// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2251799813685248 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2251799813685248 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @fmv_e._Mls64 +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @fmv_e.default +// +// // CHECK-LABEL: define {{[^@]+}}@fmv_d.resolver() { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -412,9 +571,23 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv_d.default // // +// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @fmv_c._Mssbs +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @fmv_c.default +// +// // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@recur -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: call void @reca() // CHECK-NEXT: ret void @@ -422,7 +595,7 @@ int hoo(void) { // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@main -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 @@ -433,7 +606,7 @@ int hoo(void) { // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@hoo -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FP1:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[FP2:%.*]] = alloca ptr, align 8 @@ -449,288 +622,274 @@ int hoo(void) { // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Mflagm2Msme-i16i64 -// CHECK-SAME: () #[[ATTR4:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MlseMsha2 -// CHECK-SAME: () #[[ATTR5:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 3 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MdotprodMls64_accdata -// CHECK-SAME: () #[[ATTR6:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 4 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Mfp16fmlMmemtag -// CHECK-SAME: () #[[ATTR7:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 5 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MaesMfp -// CHECK-SAME: () #[[ATTR1]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_forward_default_decl._Mmops +// CHECK-SAME: () #[[ATTR12:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 6 +// CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._McrcMls64_v -// CHECK-SAME: () #[[ATTR8:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_extern_forward_default_decl._Mdotprod +// CHECK-SAME: () #[[ATTR13:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 7 +// CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Mbti -// CHECK-SAME: () #[[ATTR9:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def.default +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 8 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Msme2 -// CHECK-SAME: () #[[ATTR10:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def.default +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 9 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def.default +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mdpb -// CHECK-SAME: () #[[ATTR11:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_one.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def._Mlse +// CHECK-SAME: () #[[ATTR14:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Msimd -// CHECK-SAME: () #[[ATTR1]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._MflagmMfp16fmlMrng +// CHECK-SAME: () #[[ATTR15:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mdgh -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mls64Msimd +// CHECK-SAME: () #[[ATTR4]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 3 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp16Msimd -// CHECK-SAME: () #[[ATTR1]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp +// CHECK-SAME: () #[[ATTR4]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 4 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_decl._Maes +// CHECK-SAME: () #[[ATTR4]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_e.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def._Msve +// CHECK-SAME: () #[[ATTR16:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 20 +// CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_c.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def._Mfp16 +// CHECK-SAME: () #[[ATTR10]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret void +// CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_without_default +// CHECK-SAME: () #[[ATTR17:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret void +// CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mf64mmMpmullMsha1 -// CHECK-SAME: () #[[ATTR12:[0-9]+]] { +// CHECK-SAME: () #[[ATTR18:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfcmaMfp16MrdmMsme -// CHECK-SAME: () #[[ATTR13:[0-9]+]] { +// CHECK-SAME: () #[[ATTR19:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 2 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mf32mmMi8mmMsha3 -// CHECK-SAME: () #[[ATTR14:[0-9]+]] { +// CHECK-SAME: () #[[ATTR20:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 12 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MditMsve-ebf16 -// CHECK-SAME: () #[[ATTR15:[0-9]+]] { +// CHECK-SAME: () #[[ATTR21:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 8 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MdpbMrcpc2 -// CHECK-SAME: () #[[ATTR16:[0-9]+]] { +// CHECK-SAME: () #[[ATTR22:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 6 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mdpb2Mjscvt -// CHECK-SAME: () #[[ATTR17:[0-9]+]] { +// CHECK-SAME: () #[[ATTR23:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 7 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfrinttsMrcpc -// CHECK-SAME: () #[[ATTR18:[0-9]+]] { +// CHECK-SAME: () #[[ATTR24:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 3 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MsveMsve-bf16 -// CHECK-SAME: () #[[ATTR19:[0-9]+]] { +// CHECK-SAME: () #[[ATTR25:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 4 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Msve2-aesMsve2-sha3 -// CHECK-SAME: () #[[ATTR20:[0-9]+]] { +// CHECK-SAME: () #[[ATTR26:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 5 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Msve2Msve2-bitpermMsve2-pmull128 -// CHECK-SAME: () #[[ATTR21:[0-9]+]] { +// CHECK-SAME: () #[[ATTR27:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 9 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mmemtag2Msve2-sm4 -// CHECK-SAME: () #[[ATTR22:[0-9]+]] { +// CHECK-SAME: () #[[ATTR28:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 10 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mmemtag3MmopsMrcpc3 -// CHECK-SAME: () #[[ATTR23:[0-9]+]] { +// CHECK-SAME: () #[[ATTR29:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 11 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MaesMdotprod -// CHECK-SAME: () #[[ATTR6]] { +// CHECK-SAME: () #[[ATTR13]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 13 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mfp16fmlMsimd -// CHECK-SAME: () #[[ATTR7]] { +// CHECK-SAME: () #[[ATTR3]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 14 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfpMsm4 -// CHECK-SAME: () #[[ATTR24:[0-9]+]] { +// CHECK-SAME: () #[[ATTR30:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 15 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MlseMrdm -// CHECK-SAME: () #[[ATTR25:[0-9]+]] { +// CHECK-SAME: () #[[ATTR31:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 16 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 3 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_d._Msb -// CHECK-SAME: () #[[ATTR26:[0-9]+]] { +// CHECK-SAME: () #[[ATTR32:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_d.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 1 // // -// CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv -// CHECK-NOFMV-SAME: () #[[ATTR0:[0-9]+]] { -// CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 0 +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @unused_with_default_def._Msve +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @unused_with_default_def.default // // -// CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_one -// CHECK-NOFMV-SAME: () #[[ATTR0]] { -// CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 0 +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65536 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65536 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @unused_with_implicit_default_def._Mfp16 +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @unused_with_implicit_default_def.default // // -// CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_two -// CHECK-NOFMV-SAME: () #[[ATTR0]] { -// CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 0 +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 128 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 128 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @unused_with_implicit_forward_default_def._Mlse +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @unused_with_implicit_forward_default_def.default // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone // CHECK-NOFMV-LABEL: define {{[^@]+}}@foo -// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-SAME: () #[[ATTR0:[0-9]+]] { // CHECK-NOFMV-NEXT: entry: // CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 @fmv() // CHECK-NOFMV-NEXT: [[CALL1:%.*]] = call i32 @fmv_one() @@ -815,34 +974,61 @@ int hoo(void) { // CHECK-NOFMV-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] // CHECK-NOFMV-NEXT: ret i32 [[ADD]] // +// +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_default_def +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 1 +// +// +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_implicit_default_def +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 1 +// +// +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 0 +// //. -// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+flagm,+fp-armv8,+fp16fml,+fullfp16,+ls64,+neon,+rand" } -// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon" } -// CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } -// CHECK: attributes #[[ATTR3:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } -// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+altnzcv,+bf16,+flagm,+fullfp16,+ls64,+sme,+sme-i16i64" } -// CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+lse,+neon,+sha2" } -// CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+fullfp16,+ls64,+neon" } -// CHECK: attributes #[[ATTR7]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fp16fml,+fullfp16,+ls64,+neon" } -// CHECK: attributes #[[ATTR8]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,+fullfp16,+ls64" } -// CHECK: attributes #[[ATTR9]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti,+fullfp16,+ls64" } -// CHECK: attributes #[[ATTR10]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fullfp16,+ls64,+sme,+sme2" } -// CHECK: attributes #[[ATTR11]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+fullfp16,+ls64" } -// CHECK: attributes #[[ATTR12]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+aes,+f64mm,+fp-armv8,+fullfp16,+ls64,+neon,+sve" } -// CHECK: attributes #[[ATTR13]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+complxnum,+fp-armv8,+fullfp16,+ls64,+neon,+rdm,+sme" } -// CHECK: attributes #[[ATTR14]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+f32mm,+fp-armv8,+fullfp16,+i8mm,+ls64,+neon,+sha2,+sha3,+sve" } -// CHECK: attributes #[[ATTR15]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+dit,+fp-armv8,+fullfp16,+ls64,+neon,+sve" } -// CHECK: attributes #[[ATTR16]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+fullfp16,+ls64,+rcpc" } -// CHECK: attributes #[[ATTR17]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccdp,+ccpp,+fp-armv8,+fullfp16,+jsconv,+ls64,+neon" } -// CHECK: attributes #[[ATTR18]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint,+fullfp16,+ls64,+rcpc" } -// CHECK: attributes #[[ATTR19]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+fullfp16,+ls64,+neon,+sve" } -// CHECK: attributes #[[ATTR20]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon,+sve,+sve2,+sve2-aes,+sve2-sha3" } -// CHECK: attributes #[[ATTR21]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon,+sve,+sve2,+sve2-aes,+sve2-bitperm" } -// CHECK: attributes #[[ATTR22]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+mte,+neon,+sve,+sve2,+sve2-sm4" } -// CHECK: attributes #[[ATTR23]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64,+mops,+mte,+rcpc,+rcpc3" } -// CHECK: attributes #[[ATTR24]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon,+sm4" } -// CHECK: attributes #[[ATTR25]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+lse,+neon,+rdm" } -// CHECK: attributes #[[ATTR26]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64,+sb" } +// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+altnzcv,+bf16,+flagm,+sme,+sme-i16i64,-v9.5a" } +// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon,+sha2,-v9.5a" } +// CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+ls64,+neon,-v9.5a" } +// CHECK: attributes #[[ATTR3]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fp16fml,+fullfp16,+neon,-v9.5a" } +// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,-v9.5a" } +// CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,-v9.5a" } +// CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti,-v9.5a" } +// CHECK: attributes #[[ATTR7]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme2,-v9.5a" } +// CHECK: attributes #[[ATTR8]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,-v9.5a" } +// CHECK: attributes #[[ATTR9]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-v9.5a" } +// CHECK: attributes #[[ATTR10]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,-v9.5a" } +// CHECK: attributes #[[ATTR11:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-v9.5a" } +// CHECK: attributes #[[ATTR12]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops,-v9.5a" } +// CHECK: attributes #[[ATTR13]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon,-v9.5a" } +// CHECK: attributes #[[ATTR14]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-v9.5a" } +// CHECK: attributes #[[ATTR15]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+flagm,+fp-armv8,+fp16fml,+fullfp16,+neon,+rand,-v9.5a" } +// CHECK: attributes #[[ATTR16]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } +// CHECK: attributes #[[ATTR17]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm,-v9.5a" } +// CHECK: attributes #[[ATTR18]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+aes,+f64mm,+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } +// CHECK: attributes #[[ATTR19]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+complxnum,+fp-armv8,+fullfp16,+neon,+rdm,+sme,-v9.5a" } +// CHECK: attributes #[[ATTR20]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+f32mm,+fp-armv8,+fullfp16,+i8mm,+neon,+sha2,+sha3,+sve,-v9.5a" } +// CHECK: attributes #[[ATTR21]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+dit,+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } +// CHECK: attributes #[[ATTR22]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+rcpc,-v9.5a" } +// CHECK: attributes #[[ATTR23]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccdp,+ccpp,+fp-armv8,+jsconv,+neon,-v9.5a" } +// CHECK: attributes #[[ATTR24]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint,+rcpc,-v9.5a" } +// CHECK: attributes #[[ATTR25]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } +// CHECK: attributes #[[ATTR26]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-aes,+sve2-sha3,-v9.5a" } +// CHECK: attributes #[[ATTR27]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-aes,+sve2-bitperm,-v9.5a" } +// CHECK: attributes #[[ATTR28]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+mte,+neon,+sve,+sve2,+sve2-sm4,-v9.5a" } +// CHECK: attributes #[[ATTR29]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops,+mte,+rcpc,+rcpc3,-v9.5a" } +// CHECK: attributes #[[ATTR30]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+sm4,-v9.5a" } +// CHECK: attributes #[[ATTR31]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon,+rdm,-v9.5a" } +// CHECK: attributes #[[ATTR32]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+sb,-v9.5a" } //. // CHECK-NOFMV: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" } // CHECK-NOFMV: attributes #[[ATTR1:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" } diff --git a/clang/test/CodeGenCXX/attr-target-version.cpp b/clang/test/CodeGenCXX/attr-target-version.cpp index 82a928a385e1..e06121d1a719 100644 --- a/clang/test/CodeGenCXX/attr-target-version.cpp +++ b/clang/test/CodeGenCXX/attr-target-version.cpp @@ -10,41 +10,196 @@ struct MyClass { int __attribute__((target_version("dotprod"))) goo(int); int __attribute__((target_version("crc"))) goo(int); int __attribute__((target_version("default"))) goo(int); + + // This should generate one target version but no resolver. + int __attribute__((target_version("default"))) unused_with_forward_default_decl(void); + int __attribute__((target_version("mops"))) unused_with_forward_default_decl(void); + + // This should also generate one target version but no resolver. + int unused_with_implicit_forward_default_decl(void); + int __attribute__((target_version("dotprod"))) unused_with_implicit_forward_default_decl(void); + + // This should also generate one target version but no resolver. + int __attribute__((target_version("aes"))) unused_with_default_decl(void); + int __attribute__((target_version("default"))) unused_with_default_decl(void); + + // This should generate two target versions and the resolver. + int __attribute__((target_version("sve"))) unused_with_default_def(void); + int __attribute__((target_version("default"))) unused_with_default_def(void); + + // This should also generate two target versions and the resolver. + int __attribute__((target_version("fp16"))) unused_with_implicit_default_def(void); + int unused_with_implicit_default_def(void); + + // This should also generate two target versions and the resolver. + int unused_with_implicit_forward_default_def(void); + int __attribute__((target_version("lse"))) unused_with_implicit_forward_default_def(void); + + // This should generate a normal function. + int __attribute__((target_version("rdm"))) unused_without_default(void); }; int __attribute__((target_version("default"))) MyClass::goo(int) { return 1; } int __attribute__((target_version("crc"))) MyClass::goo(int) { return 2; } int __attribute__((target_version("dotprod"))) MyClass::goo(int) { return 3; } +int __attribute__((target_version("mops"))) MyClass::unused_with_forward_default_decl(void) { return 0; } +int __attribute__((target_version("dotprod"))) MyClass::unused_with_implicit_forward_default_decl(void) { return 0; } +int __attribute__((target_version("aes"))) MyClass::unused_with_default_decl(void) { return 0; } +int __attribute__((target_version("sve"))) MyClass::unused_with_default_def(void) { return 0; } +int __attribute__((target_version("default"))) MyClass::unused_with_default_def(void) { return 1; } +int __attribute__((target_version("fp16"))) MyClass::unused_with_implicit_default_def(void) { return 0; } +int MyClass::unused_with_implicit_default_def(void) { return 1; } +int MyClass::unused_with_implicit_forward_default_def(void) { return 0; } +int __attribute__((target_version("lse"))) MyClass::unused_with_implicit_forward_default_def(void) { return 1; } +int __attribute__((target_version("rdm"))) MyClass::unused_without_default(void) { return 0; } + int bar() { MyClass m; return m.goo(1) + foo(1) + foo(); } - - //. // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } -// CHECK: @_ZN7MyClass3gooEi.ifunc = weak_odr alias i32 (ptr, i32), ptr @_ZN7MyClass3gooEi // CHECK: @_Z3fooi.ifunc = weak_odr alias i32 (i32), ptr @_Z3fooi // CHECK: @_Z3foov.ifunc = weak_odr alias i32 (), ptr @_Z3foov +// CHECK: @_ZN7MyClass3gooEi.ifunc = weak_odr alias i32 (ptr, i32), ptr @_ZN7MyClass3gooEi +// CHECK: @_ZN7MyClass23unused_with_default_defEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN7MyClass23unused_with_default_defEv +// CHECK: @_ZN7MyClass32unused_with_implicit_default_defEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN7MyClass32unused_with_implicit_default_defEv +// CHECK: @_ZN7MyClass40unused_with_implicit_forward_default_defEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv // CHECK: @_ZN7MyClass3gooEi = weak_odr ifunc i32 (ptr, i32), ptr @_ZN7MyClass3gooEi.resolver // CHECK: @_Z3fooi = weak_odr ifunc i32 (i32), ptr @_Z3fooi.resolver // CHECK: @_Z3foov = weak_odr ifunc i32 (), ptr @_Z3foov.resolver +// CHECK: @_ZN7MyClass23unused_with_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass23unused_with_default_defEv.resolver +// CHECK: @_ZN7MyClass32unused_with_implicit_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass32unused_with_implicit_default_defEv.resolver +// CHECK: @_ZN7MyClass40unused_with_implicit_forward_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver //. -// CHECK-LABEL: @_Z3fooi._Mbf16Msme-f64f64( +// CHECK-LABEL: @_Z3fooi.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: ret i32 2 +// +// +// CHECK-LABEL: @_Z3foov.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 4 +// +// +// CHECK-LABEL: @_ZN7MyClass3gooEi.default( // CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_Z3foov._Mebf16Msm4( +// CHECK-LABEL: @_ZN7MyClass3gooEi._Mcrc( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 2 +// +// +// CHECK-LABEL: @_ZN7MyClass3gooEi._Mdotprod( // CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 3 // // +// CHECK-LABEL: @_ZN7MyClass32unused_with_forward_default_declEv._Mmops( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass41unused_with_implicit_forward_default_declEv._Mdotprod( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass24unused_with_default_declEv._Maes( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv._Msve( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 1 +// +// +// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv._Mfp16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 1 +// +// +// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv._Mlse( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 1 +// +// +// CHECK-LABEL: @_Z3barv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[M:%.*]] = alloca [[STRUCT_MYCLASS:%.*]], align 1 +// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN7MyClass3gooEi(ptr noundef nonnull align 1 dereferenceable(1) [[M]], i32 noundef 1) +// CHECK-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z3fooi(i32 noundef 1) +// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] +// CHECK-NEXT: [[CALL2:%.*]] = call noundef i32 @_Z3foov() +// CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]] +// CHECK-NEXT: ret i32 [[ADD3]] +// +// // CHECK-LABEL: @_ZN7MyClass3gooEi.resolver( // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -67,17 +222,6 @@ int bar() { // CHECK-NEXT: ret ptr @_ZN7MyClass3gooEi.default // // -// CHECK-LABEL: @_Z3barv( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[M:%.*]] = alloca [[STRUCT_MYCLASS:%.*]], align 1 -// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN7MyClass3gooEi(ptr noundef nonnull align 1 dereferenceable(1) [[M]], i32 noundef 1) -// CHECK-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z3fooi(i32 noundef 1) -// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] -// CHECK-NEXT: [[CALL2:%.*]] = call noundef i32 @_Z3foov() -// CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]] -// CHECK-NEXT: ret i32 [[ADD3]] -// -// // CHECK-LABEL: @_Z3fooi.resolver( // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -106,53 +250,80 @@ int bar() { // CHECK-NEXT: ret ptr @_Z3foov.default // // -// CHECK-LABEL: @_ZN7MyClass3gooEi._Mdotprod( +// CHECK-LABEL: @_Z3fooi._Mbf16Msme-f64f64( // CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 3 +// CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_ZN7MyClass3gooEi._Mcrc( +// CHECK-LABEL: @_Z3foov._Mebf16Msm4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 2 +// CHECK-NEXT: ret i32 3 // // -// CHECK-LABEL: @_ZN7MyClass3gooEi.default( +// CHECK-LABEL: @_ZN7MyClass22unused_without_defaultEv( // CHECK-NEXT: entry: // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 // CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 0 // // -// CHECK-LABEL: @_Z3fooi.default( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 -// CHECK-NEXT: ret i32 2 +// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv.resolver( +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @_ZN7MyClass23unused_with_default_defEv._Msve +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @_ZN7MyClass23unused_with_default_defEv.default // // -// CHECK-LABEL: @_Z3foov.default( -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 4 +// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv.resolver( +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65536 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65536 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @_ZN7MyClass32unused_with_implicit_default_defEv._Mfp16 +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @_ZN7MyClass32unused_with_implicit_default_defEv.default +// +// +// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver( +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 128 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 128 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv._Mlse +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.default // //. -// CHECK: attributes #[[ATTR0:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } -// CHECK: attributes #[[ATTR1:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+neon,+sm4" } -// CHECK: attributes #[[ATTR2:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -// CHECK: attributes #[[ATTR3:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon" } -// CHECK: attributes #[[ATTR4:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc" } +// CHECK: attributes #[[ATTR0:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR1:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc" } +// CHECK: attributes #[[ATTR2:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon" } +// CHECK: attributes #[[ATTR3:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops" } +// CHECK: attributes #[[ATTR4:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon" } +// CHECK: attributes #[[ATTR5:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } +// CHECK: attributes #[[ATTR6:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" } +// CHECK: attributes #[[ATTR7:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse" } +// CHECK: attributes #[[ATTR8:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } +// CHECK: attributes #[[ATTR9:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+neon,+sm4" } +// CHECK: attributes #[[ATTR10:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm" } +// CHECK: attributes #[[ATTR11:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} -- GitLab From 9fd1c4121f7c797ff7222161cb40cd68ecf0fbc8 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme <thomas.preudhomme@arm.com> Date: Wed, 20 Mar 2024 09:26:16 +0000 Subject: [PATCH 201/307] [MLIR] Add missing MLIRLinalgTransforms to LinalgToStandard conv (#84545) This fixes the following failure when doing a clean build (in particular no .ninja* lying around) of lib/libMLIRLinalgToStandard.a only: ``` In file included from mlir/include/mlir/Dialect/Vector/Transforms/VectorTransforms.h:12, from mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h:21, from mlir/lib/Conversion/LinalgToStandard/LinalgToStandard.cpp:15: mlir/include/mlir/Dialect/Vector/Transforms/VectorRewritePatterns.h:20:10: fatal error: mlir/Dialect/Vector/Transforms/VectorTransformsEnums.h.inc: No such file or directory ``` --- mlir/lib/Conversion/LinalgToStandard/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/mlir/lib/Conversion/LinalgToStandard/CMakeLists.txt b/mlir/lib/Conversion/LinalgToStandard/CMakeLists.txt index 0c8816b65d19..cbe85789b29a 100644 --- a/mlir/lib/Conversion/LinalgToStandard/CMakeLists.txt +++ b/mlir/lib/Conversion/LinalgToStandard/CMakeLists.txt @@ -14,6 +14,7 @@ add_mlir_conversion_library(MLIRLinalgToStandard MLIRFuncDialect MLIRIR MLIRLinalgDialect + MLIRLinalgTransforms MLIRMemRefDialect MLIRPass MLIRSCFDialect -- GitLab From d03263814aa1a686e5aaca99ab9d87408b2c6cb5 Mon Sep 17 00:00:00 2001 From: Qiu Chaofan <qiucofan@cn.ibm.com> Date: Wed, 20 Mar 2024 17:45:19 +0800 Subject: [PATCH 202/307] [PowerPC] Fix operand regclass of XSTSTDCSP --- llvm/lib/Target/PowerPC/PPCInstrVSX.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td index 0e5f6b773bb5..dd07892794d5 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td +++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td @@ -1596,7 +1596,7 @@ let Predicates = [HasVSX, HasP9Vector] in { // FIXME: Setting the hasSideEffects flag here to match current behaviour. let hasSideEffects = 1 in { def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298, - (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB), + (outs crrc:$BF), (ins u7imm:$DCMX, vssrc:$XB), "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>; def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362, (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB), -- GitLab From 1f1e0948f20338961f995426c11497e8f21ceb08 Mon Sep 17 00:00:00 2001 From: Tom Eccles <tom.eccles@arm.com> Date: Wed, 20 Mar 2024 09:47:49 +0000 Subject: [PATCH 203/307] [flang] run CFG conversion on omp reduction declare ops (#84953) Most FIR passes only look for FIR operations inside of functions (either because they run only on func.func or they run on the module but iterate over functions internally). But there can also be FIR operations inside of fir.global, some OpenMP and OpenACC container operations. This has worked so far for fir.global and OpenMP reductions because they only contained very simple FIR code which doesn't need most passes to be lowered into LLVM IR. I am not sure how OpenACC works. In the long run, I hope to see a more systematic approach to making sure that every pass runs on all of these container operations. I will write an RFC for this soon. In the meantime, this pass duplicates the CFG conversion pass to also run on omp reduction operations. This is similar to how the AbstractResult pass is already duplicated for fir.global operations. OpenMP array reductions 2/6 Previous PR: https://github.com/llvm/llvm-project/pull/84952 Next PR: https://github.com/llvm/llvm-project/pull/84954 --------- Co-authored-by: Mats Petersson <mats.petersson@arm.com> --- .../flang/Optimizer/Transforms/Passes.h | 10 +++- .../flang/Optimizer/Transforms/Passes.td | 12 +++- flang/include/flang/Tools/CLOptions.inc | 4 +- .../Transforms/ControlFlowConverter.cpp | 38 ++++++++++--- flang/test/Driver/bbc-mlir-pass-pipeline.f90 | 5 +- .../test/Driver/mlir-debug-pass-pipeline.f90 | 16 +++--- flang/test/Driver/mlir-pass-pipeline.f90 | 16 ++++-- flang/test/Fir/array-value-copy-2.fir | 4 +- flang/test/Fir/basic-program.fir | 5 +- .../Fir/convert-to-llvm-openmp-and-fir.fir | 2 +- flang/test/Fir/loop01.fir | 2 +- flang/test/Fir/loop02.fir | 4 +- flang/test/Lower/OpenMP/FIR/flush.f90 | 2 +- flang/test/Lower/OpenMP/FIR/master.f90 | 2 +- .../Lower/OpenMP/FIR/parallel-sections.f90 | 2 +- .../omp-reduction-cfg-conversion.fir | 57 +++++++++++++++++++ 16 files changed, 143 insertions(+), 38 deletions(-) create mode 100644 flang/test/Transforms/omp-reduction-cfg-conversion.fir diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index e1d22c8c986d..a60d39c8df08 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -11,6 +11,7 @@ #include "flang/Optimizer/Dialect/FIROps.h" #include "mlir/Dialect/LLVMIR/LLVMAttrs.h" +#include "mlir/Dialect/OpenMP/OpenMPDialect.h" #include "mlir/Pass/Pass.h" #include "mlir/Pass/PassRegistry.h" #include <memory> @@ -37,7 +38,8 @@ namespace fir { #define GEN_PASS_DECL_ANNOTATECONSTANTOPERANDS #define GEN_PASS_DECL_ARRAYVALUECOPY #define GEN_PASS_DECL_CHARACTERCONVERSION -#define GEN_PASS_DECL_CFGCONVERSION +#define GEN_PASS_DECL_CFGCONVERSIONONFUNC +#define GEN_PASS_DECL_CFGCONVERSIONONREDUCTION #define GEN_PASS_DECL_EXTERNALNAMECONVERSION #define GEN_PASS_DECL_MEMREFDATAFLOWOPT #define GEN_PASS_DECL_SIMPLIFYINTRINSICS @@ -53,7 +55,8 @@ std::unique_ptr<mlir::Pass> createAbstractResultOnGlobalOptPass(); std::unique_ptr<mlir::Pass> createAffineDemotionPass(); std::unique_ptr<mlir::Pass> createArrayValueCopyPass(fir::ArrayValueCopyOptions options = {}); -std::unique_ptr<mlir::Pass> createFirToCfgPass(); +std::unique_ptr<mlir::Pass> createFirToCfgOnFuncPass(); +std::unique_ptr<mlir::Pass> createFirToCfgOnReductionPass(); std::unique_ptr<mlir::Pass> createCharacterConversionPass(); std::unique_ptr<mlir::Pass> createExternalNameConversionPass(); std::unique_ptr<mlir::Pass> @@ -96,6 +99,9 @@ createFunctionAttrPass(FunctionAttrTypes &functionAttr, bool noInfsFPMath, bool noNaNsFPMath, bool approxFuncFPMath, bool noSignedZerosFPMath, bool unsafeFPMath); +void populateCfgConversionRewrites(mlir::RewritePatternSet &patterns, + bool forceLoopToExecuteOnce = false); + // declarative passes #define GEN_PASS_REGISTRATION #include "flang/Optimizer/Transforms/Passes.h.inc" diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index 5fb576fd8762..e6ea92d81440 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -145,7 +145,8 @@ def CharacterConversion : Pass<"character-conversion"> { ]; } -def CFGConversion : Pass<"cfg-conversion", "::mlir::func::FuncOp"> { +class CFGConversionBase<string optExt, string operation> + : Pass<"cfg-conversion-on-" # optExt # "-opt", operation> { let summary = "Convert FIR structured control flow ops to CFG ops."; let description = [{ Transform the `fir.do_loop`, `fir.if`, `fir.iterate_while` and @@ -154,7 +155,6 @@ def CFGConversion : Pass<"cfg-conversion", "::mlir::func::FuncOp"> { This pass is required before code gen to the LLVM IR dialect. }]; - let constructor = "::fir::createFirToCfgPass()"; let dependentDialects = [ "fir::FIROpsDialect", "mlir::func::FuncDialect" ]; @@ -165,6 +165,14 @@ def CFGConversion : Pass<"cfg-conversion", "::mlir::func::FuncOp"> { ]; } +def CFGConversionOnFunc : CFGConversionBase<"func", "mlir::func::FuncOp"> { + let constructor = "::fir::createFirToCfgOnFuncPass()"; +} + +def CFGConversionOnReduction : CFGConversionBase<"reduce", "mlir::omp::ReductionDeclareOp"> { + let constructor = "::fir::createFirToCfgOnReductionPass()"; +} + def ExternalNameConversion : Pass<"external-name-interop", "mlir::ModuleOp"> { let summary = "Convert name for external interoperability"; let description = [{ diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index 68e504d0ccb5..21b36dba9ac7 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -123,7 +123,9 @@ static void addCanonicalizerPassWithoutRegionSimplification( inline void addCfgConversionPass(mlir::PassManager &pm) { addNestedPassConditionally<mlir::func::FuncOp>( - pm, disableCfgConversion, fir::createFirToCfgPass); + pm, disableCfgConversion, fir::createFirToCfgOnFuncPass); + addNestedPassConditionally<mlir::omp::ReductionDeclareOp>( + pm, disableCfgConversion, fir::createFirToCfgOnReductionPass); } inline void addAVC( diff --git a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp index 0944b184ca0d..45609a99995d 100644 --- a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp +++ b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp @@ -24,7 +24,8 @@ #include "llvm/Support/CommandLine.h" namespace fir { -#define GEN_PASS_DEF_CFGCONVERSION +#define GEN_PASS_DEF_CFGCONVERSIONONFUNC +#define GEN_PASS_DEF_CFGCONVERSIONONREDUCTION #include "flang/Optimizer/Transforms/Passes.h.inc" } // namespace fir @@ -308,13 +309,13 @@ public: }; /// Convert FIR structured control flow ops to CFG ops. -class CfgConversion : public fir::impl::CFGConversionBase<CfgConversion> { +template <typename Pass, template <typename> class PassBase> +class CfgConversionTemplate : public PassBase<Pass> { public: void runOnOperation() override { - auto *context = &getContext(); + auto *context = &this->getContext(); mlir::RewritePatternSet patterns(context); - patterns.insert<CfgLoopConv, CfgIfConv, CfgIterWhileConv>( - context, forceLoopToExecuteOnce); + fir::populateCfgConversionRewrites(patterns, this->forceLoopToExecuteOnce); mlir::ConversionTarget target(*context); target.addLegalDialect<mlir::affine::AffineDialect, mlir::cf::ControlFlowDialect, FIROpsDialect, @@ -323,19 +324,38 @@ public: // apply the patterns target.addIllegalOp<ResultOp, DoLoopOp, IfOp, IterWhileOp>(); target.markUnknownOpDynamicallyLegal([](Operation *) { return true; }); - if (mlir::failed(mlir::applyPartialConversion(getOperation(), target, + if (mlir::failed(mlir::applyPartialConversion(this->getOperation(), target, std::move(patterns)))) { mlir::emitError(mlir::UnknownLoc::get(context), "error in converting to CFG\n"); - signalPassFailure(); + this->signalPassFailure(); } } }; + +class CfgConversionOnFunc + : public CfgConversionTemplate<CfgConversionOnFunc, + ::fir::impl::CFGConversionOnFuncBase> {}; + +class CfgConversionOnReduction + : public CfgConversionTemplate<CfgConversionOnReduction, + ::fir::impl::CFGConversionOnReductionBase> { +}; } // namespace +/// Expose conversion rewriters to other passes +void fir::populateCfgConversionRewrites(mlir::RewritePatternSet &patterns, + bool forceLoopToExecuteOnce) { + patterns.insert<CfgLoopConv, CfgIfConv, CfgIterWhileConv>( + patterns.getContext(), forceLoopToExecuteOnce); +} + /// Convert FIR's structured control flow ops to CFG ops. This /// conversion enables the `createLowerToCFGPass` to transform these to CFG /// form. -std::unique_ptr<mlir::Pass> fir::createFirToCfgPass() { - return std::make_unique<CfgConversion>(); +std::unique_ptr<mlir::Pass> fir::createFirToCfgOnFuncPass() { + return std::make_unique<CfgConversionOnFunc>(); +} +std::unique_ptr<mlir::Pass> fir::createFirToCfgOnReductionPass() { + return std::make_unique<CfgConversionOnReduction>(); } diff --git a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 b/flang/test/Driver/bbc-mlir-pass-pipeline.f90 index 243a620a9fd0..b25edf359917 100644 --- a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 +++ b/flang/test/Driver/bbc-mlir-pass-pipeline.f90 @@ -38,9 +38,12 @@ end program ! CHECK-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! CHECK-NEXT: (S) 0 num-dce'd - Number of operations DCE'd +! CHECK-NEXT: Pipeline Collection : ['func.func', 'omp.reduction.declare'] ! CHECK-NEXT: 'func.func' Pipeline ! CHECK-NEXT: PolymorphicOpConversion -! CHECK-NEXT: CFGConversion +! CHECK-NEXT: CFGConversionOnFunc +! CHECK-NEXT: 'omp.reduction.declare' Pipeline +! CHECK-NEXT: CFGConversionOnReduction ! CHECK-NEXT: SCFToControlFlow ! CHECK-NEXT: Canonicalizer diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90 index 45b1717d7187..a865b170c3d4 100644 --- a/flang/test/Driver/mlir-debug-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90 @@ -58,10 +58,12 @@ end program ! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd -! ALL-NEXT: 'func.func' Pipeline -! ALL-NEXT: PolymorphicOpConversion -! ALL-NEXT: CFGConversion - +! ALL-NEXT: Pipeline Collection : ['func.func', 'omp.reduction.declare'] +! ALL-NEXT: 'func.func' Pipeline +! ALL-NEXT: PolymorphicOpConversion +! ALL-NEXT: CFGConversionOnFunc +! ALL-NEXT: 'omp.reduction.declare' Pipeline +! ALL-NEXT: CFGConversionOnReduction ! ALL-NEXT: SCFToControlFlow ! ALL-NEXT: Canonicalizer ! ALL-NEXT: SimplifyRegionLite @@ -72,9 +74,9 @@ end program ! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func'] ! ALL-NEXT: 'fir.global' Pipeline -! ALL-NEXT: AbstractResultOnGlobalOpt -! ALL-NEXT: 'func.func' Pipeline -! ALL-NEXT: AbstractResultOnFuncOpt +! ALL-NEXT: AbstractResultOnGlobalOpt +! ALL-NEXT: 'func.func' Pipeline +! ALL-NEXT: AbstractResultOnFuncOpt ! ALL-NEXT: CodeGenRewrite ! ALL-NEXT: (S) 0 num-dce'd - Number of operations eliminated diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90 index 3d8c42f123e2..ee3f41a15ca4 100644 --- a/flang/test/Driver/mlir-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-pass-pipeline.f90 @@ -1,8 +1,8 @@ ! Test the MLIR pass pipeline -! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefixes=ALL %s +! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefixes=ALL,NOTO2 %s ! -O0 is the default: -! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -O0 -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL %s +! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -O0 -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,NOTO2 %s ! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -O2 -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,O2 %s ! REQUIRES: asserts @@ -49,11 +49,15 @@ end program ! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd -! ALL-NEXT: 'func.func' Pipeline -! ALL-NEXT: PolymorphicOpConversion +! O2-NEXT: 'func.func' Pipeline +! O2-NEXT: PolymorphicOpConversion ! O2-NEXT: AddAliasTags -! O2-NEXT: 'func.func' Pipeline -! ALL-NEXT: CFGConversion +! ALL-NEXT: Pipeline Collection : ['func.func', 'omp.reduction.declare'] +! ALL-NEXT: 'func.func' Pipeline +! NOTO2-NEXT: PolymorphicOpConversion +! ALL-NEXT: CFGConversionOnFunc +! ALL-NEXT: 'omp.reduction.declare' Pipeline +! ALL-NEXT: CFGConversionOnReduction ! ALL-NEXT: SCFToControlFlow ! ALL-NEXT: Canonicalizer diff --git a/flang/test/Fir/array-value-copy-2.fir b/flang/test/Fir/array-value-copy-2.fir index 21b340af10c6..cb8d6ca2b055 100644 --- a/flang/test/Fir/array-value-copy-2.fir +++ b/flang/test/Fir/array-value-copy-2.fir @@ -1,5 +1,5 @@ -// RUN: fir-opt --array-value-copy --cfg-conversion %s | FileCheck %s -// RUN: fir-opt --array-value-copy="optimize-conflicts=true" --cfg-conversion %s | FileCheck %s +// RUN: fir-opt --array-value-copy --cfg-conversion-on-func-opt %s | FileCheck %s +// RUN: fir-opt --array-value-copy="optimize-conflicts=true" --cfg-conversion-on-func-opt %s | FileCheck %s // CHECK-LABEL: func @_QPslice1( // CHECK-NOT: fir.allocmem diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir index d8a9e74c318c..516946bd4fb4 100644 --- a/flang/test/Fir/basic-program.fir +++ b/flang/test/Fir/basic-program.fir @@ -60,8 +60,11 @@ func.func @_QQmain() { // PASSES-NEXT: AddAliasTags +// PASSES-NEXT: Pipeline Collection : ['func.func', 'omp.reduction.declare'] // PASSES-NEXT: 'func.func' Pipeline -// PASSES-NEXT: CFGConversion +// PASSES-NEXT: CFGConversionOnFunc +// PASSES-NEXT: 'omp.reduction.declare' Pipeline +// PASSES-NEXT: CFGConversionOnReduction // PASSES-NEXT: SCFToControlFlow // PASSES-NEXT: Canonicalizer diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir index a1fc614334db..8d9bdca4bf54 100644 --- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir +++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir @@ -1,4 +1,4 @@ -// RUN: fir-opt --split-input-file --cfg-conversion --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s +// RUN: fir-opt --split-input-file --cfg-conversion-on-func-opt --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s func.func @_QPsb1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"}) { %c1_i64 = arith.constant 1 : i64 diff --git a/flang/test/Fir/loop01.fir b/flang/test/Fir/loop01.fir index 72ca1c3989e4..c849797b969e 100644 --- a/flang/test/Fir/loop01.fir +++ b/flang/test/Fir/loop01.fir @@ -1,4 +1,4 @@ -// RUN: fir-opt --split-input-file --cfg-conversion %s | FileCheck %s +// RUN: fir-opt --split-input-file --cfg-conversion-on-func-opt %s | FileCheck %s func.func @x(%lb : index, %ub : index, %step : index, %b : i1, %addr : !fir.ref<index>) { fir.do_loop %iv = %lb to %ub step %step unordered { diff --git a/flang/test/Fir/loop02.fir b/flang/test/Fir/loop02.fir index 50948e0e7aa6..8918666f0b34 100644 --- a/flang/test/Fir/loop02.fir +++ b/flang/test/Fir/loop02.fir @@ -1,5 +1,5 @@ -// RUN: fir-opt --cfg-conversion="always-execute-loop-body=true" %s | FileCheck %s -// RUN: fir-opt --cfg-conversion %s | FileCheck %s --check-prefix=NOOPT +// RUN: fir-opt --cfg-conversion-on-func-opt="always-execute-loop-body=true" %s | FileCheck %s +// RUN: fir-opt --cfg-conversion-on-func-opt %s | FileCheck %s --check-prefix=NOOPT func.func @x(%addr : !fir.ref<index>) { %bound = arith.constant 452 : index diff --git a/flang/test/Lower/OpenMP/FIR/flush.f90 b/flang/test/Lower/OpenMP/FIR/flush.f90 index 2c281632b85c..2868367fbdba 100644 --- a/flang/test/Lower/OpenMP/FIR/flush.f90 +++ b/flang/test/Lower/OpenMP/FIR/flush.f90 @@ -1,7 +1,7 @@ ! This test checks lowering of OpenMP Flush Directive. !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s --check-prefixes="FIRDialect,OMPDialect" -!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="LLVMIRDialect,OMPDialect" +!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion-on-func-opt | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="LLVMIRDialect,OMPDialect" subroutine flush_standalone(a, b, c) integer, intent(inout) :: a, b, c diff --git a/flang/test/Lower/OpenMP/FIR/master.f90 b/flang/test/Lower/OpenMP/FIR/master.f90 index dd9910da2f41..3bac582c7725 100644 --- a/flang/test/Lower/OpenMP/FIR/master.f90 +++ b/flang/test/Lower/OpenMP/FIR/master.f90 @@ -1,5 +1,5 @@ !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s --check-prefixes="FIRDialect,OMPDialect" -!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect" +!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion-on-func-opt | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect" !=============================================================================== ! parallel construct with function call which has master construct internally diff --git a/flang/test/Lower/OpenMP/FIR/parallel-sections.f90 b/flang/test/Lower/OpenMP/FIR/parallel-sections.f90 index 33fda178323f..78d73f038f07 100644 --- a/flang/test/Lower/OpenMP/FIR/parallel-sections.f90 +++ b/flang/test/Lower/OpenMP/FIR/parallel-sections.f90 @@ -1,5 +1,5 @@ !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s --check-prefixes="FIRDialect,OMPDialect" -!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect,LLVMDialect" +!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion-on-func-opt | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect,LLVMDialect" !=============================================================================== ! Parallel sections construct diff --git a/flang/test/Transforms/omp-reduction-cfg-conversion.fir b/flang/test/Transforms/omp-reduction-cfg-conversion.fir new file mode 100644 index 000000000000..c27bba2f7b07 --- /dev/null +++ b/flang/test/Transforms/omp-reduction-cfg-conversion.fir @@ -0,0 +1,57 @@ +// RUN: fir-opt --cfg-conversion-on-reduce-opt %s | FileCheck %s + +omp.reduction.declare @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init { +^bb0(%arg0: !fir.ref<!fir.box<!fir.array<3xi32>>>): + %c4_i32 = arith.constant 4 : i32 + %c0_i32 = arith.constant 0 : i32 + %c3 = arith.constant 3 : index + %0 = fir.alloca !fir.box<!fir.array<3xi32>> + %1 = fir.alloca !fir.array<3xi32> {bindc_name = "omp.reduction.array.init"} + %2 = fir.shape %c3 : (index) -> !fir.shape<1> + %3 = fir.declare %1(%2) {uniq_name = "omp.reduction.array.init"} : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.ref<!fir.array<3xi32>> + %4 = fir.embox %3(%2) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>> + %5 = fir.alloca i32 + fir.store %c0_i32 to %5 : !fir.ref<i32> + %6 = fir.embox %5 : (!fir.ref<i32>) -> !fir.box<i32> + fir.store %4 to %0 : !fir.ref<!fir.box<!fir.array<3xi32>>> + %7 = fir.address_of(@_QQclX9a9fdf8c5fd329fbbf2b0c08e2ca9a1e) : !fir.ref<!fir.char<1,40>> + %8 = fir.convert %0 : (!fir.ref<!fir.box<!fir.array<3xi32>>>) -> !fir.ref<!fir.box<none>> + %9 = fir.convert %6 : (!fir.box<i32>) -> !fir.box<none> + %10 = fir.convert %7 : (!fir.ref<!fir.char<1,40>>) -> !fir.ref<i8> + %11 = fir.call @_FortranAAssign(%8, %9, %10, %c4_i32) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none + %12 = fir.alloca !fir.box<!fir.array<3xi32>> + fir.store %4 to %12 : !fir.ref<!fir.box<!fir.array<3xi32>>> + omp.yield(%12 : !fir.ref<!fir.box<!fir.array<3xi32>>>) +} combiner { +^bb0(%arg0: !fir.ref<!fir.box<!fir.array<3xi32>>>, %arg1: !fir.ref<!fir.box<!fir.array<3xi32>>>): + %c1 = arith.constant 1 : index + %c0 = arith.constant 0 : index + %0 = fir.load %arg0 : !fir.ref<!fir.box<!fir.array<3xi32>>> + %1 = fir.load %arg1 : !fir.ref<!fir.box<!fir.array<3xi32>>> + %2:3 = fir.box_dims %0, %c0 : (!fir.box<!fir.array<3xi32>>, index) -> (index, index, index) + %3 = fir.shape_shift %2#0, %2#1 : (index, index) -> !fir.shapeshift<1> + fir.do_loop %arg2 = %c1 to %2#1 step %c1 unordered { + %4 = fir.array_coor %0(%3) %arg2 : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32> + %5 = fir.array_coor %1(%3) %arg2 : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32> + %6 = fir.load %4 : !fir.ref<i32> + %7 = fir.load %5 : !fir.ref<i32> + %8 = arith.addi %6, %7 : i32 + fir.store %8 to %4 : !fir.ref<i32> + } + omp.yield(%arg0 : !fir.ref<!fir.box<!fir.array<3xi32>>>) +} + +// ensure cfg conversion has run on the do loop +// CHECK: combiner { +// CHECK-NOT: fir.do_loop +// CHECK: ^bb0({{.*}}): +// ... +// CHECK: cf.br ^bb1 +// CHECK: ^bb1({{.*}}): +// ... +// CHECK: cf.cond_br %{{.*}} ^bb2, ^bb3 +// CHECK: ^bb2: +// ... +// CHECK: cf.br ^bb1 +// CHECK: ^bb3: + -- GitLab From 1f63a56cede85bcd5f4fea3663bd3a47b801a396 Mon Sep 17 00:00:00 2001 From: Tom Eccles <tom.eccles@arm.com> Date: Wed, 20 Mar 2024 09:52:04 +0000 Subject: [PATCH 204/307] [flang][CodeGen] Run PreCGRewrite on omp reduction declare ops (#84954) OpenMP reduction declare operations can contain FIR code which needs to be lowered to LLVM. With array reductions, these regions can contain more complicated operations which need PreCGRewriting. A similar extra case was already needed for fir::GlobalOp. OpenMP array reductions 3/6 Previous PR: https://github.com/llvm/llvm-project/pull/84953 Next PR: https://github.com/llvm/llvm-project/pull/84955 --- flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp index 9d48a2f08aba..665bf09b8fc3 100644 --- a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp +++ b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp @@ -283,7 +283,9 @@ public: class CodeGenRewrite : public fir::impl::CodeGenRewriteBase<CodeGenRewrite> { public: - void runOn(mlir::Operation *op, mlir::Region ®ion) { + void runOnOperation() override final { + mlir::ModuleOp mod = getOperation(); + auto &context = getContext(); mlir::ConversionTarget target(context); target.addLegalDialect<mlir::arith::ArithDialect, fir::FIROpsDialect, @@ -300,7 +302,7 @@ public: mlir::RewritePatternSet patterns(&context); fir::populatePreCGRewritePatterns(patterns); if (mlir::failed( - mlir::applyPartialConversion(op, target, std::move(patterns)))) { + mlir::applyPartialConversion(mod, target, std::move(patterns)))) { mlir::emitError(mlir::UnknownLoc::get(&context), "error in running the pre-codegen conversions"); signalPassFailure(); @@ -308,16 +310,7 @@ public: } // Erase any residual (fir.shape, fir.slice...). mlir::IRRewriter rewriter(&context); - (void)mlir::runRegionDCE(rewriter, op->getRegions()); - } - - void runOnOperation() override final { - // Call runOn on all top level regions that may contain emboxOp/arrayCoorOp. - auto mod = getOperation(); - for (auto func : mod.getOps<mlir::func::FuncOp>()) - runOn(func, func.getBody()); - for (auto global : mod.getOps<fir::GlobalOp>()) - runOn(global, global.getRegion()); + (void)mlir::runRegionDCE(rewriter, mod->getRegions()); } }; -- GitLab From 0f46e31cfbf415fcd3d3ce121bef94e92c6ccfc8 Mon Sep 17 00:00:00 2001 From: Nikita Popov <npopov@redhat.com> Date: Wed, 20 Mar 2024 10:59:45 +0100 Subject: [PATCH 205/307] [IR] Change representation of getelementptr inrange (#84341) As part of the migration to ptradd (https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699), we need to change the representation of the `inrange` attribute, which is used for vtable splitting. Currently, inrange is specified as follows: ``` getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr @vt, i64 0, inrange i32 1, i64 2) ``` The `inrange` is placed on a GEP index, and all accesses must be "in range" of that index. The new representation is as follows: ``` getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [4 x ptr] }, ptr @vt, i64 0, i32 1, i64 2) ``` This specifies which offsets are "in range" of the GEP result. The new representation will continue working when canonicalizing to ptradd representation: ``` getelementptr inbounds inrange(-16, 16) (i8, ptr @vt, i64 48) ``` The inrange offsets are relative to the return value of the GEP. An alternative design could make them relative to the source pointer instead. The result-relative format was chosen on the off-chance that we want to extend support to non-constant GEPs in the future, in which case this variant is more expressive. This implementation "upgrades" the old inrange representation in bitcode by simply dropping it. This is a very niche feature, and I don't think trying to upgrade it is worthwhile. Let me know if you disagree. --- clang/lib/CodeGen/CGVTT.cpp | 13 ++- clang/lib/CodeGen/ItaniumCXXABI.cpp | 20 +++-- .../diamond-virtual-inheritance.cpp | 6 +- clang/test/CodeGenCXX/auto-var-init.cpp | 4 +- clang/test/CodeGenCXX/const-init-cxx11.cpp | 6 +- clang/test/CodeGenCXX/constructor-init.cpp | 6 +- .../copy-constructor-synthesis-2.cpp | 2 +- .../CodeGenCXX/copy-constructor-synthesis.cpp | 2 +- clang/test/CodeGenCXX/dynamic-cast-exact.cpp | 6 +- clang/test/CodeGenCXX/microsoft-interface.cpp | 4 +- .../skip-vtable-pointer-initialization.cpp | 14 ++-- clang/test/CodeGenCXX/static-init.cpp | 2 +- .../CodeGenCXX/strict-vtable-pointers.cpp | 4 +- clang/test/CodeGenCXX/visibility.cpp | 2 +- .../vtable-assume-load-address-space.cpp | 14 ++-- clang/test/CodeGenCXX/vtable-assume-load.cpp | 14 ++-- ...e-pointer-initialization-address-space.cpp | 8 +- .../vtable-pointer-initialization.cpp | 8 +- clang/test/CodeGenCXX/vtt-address-space.cpp | 2 +- .../CodeGenCXX/vtt-layout-address-space.cpp | 8 +- clang/test/CodeGenCXX/vtt-layout.cpp | 8 +- ...ata_use_device_ptr_inheritance_codegen.cpp | 12 +-- .../devirt_validate_vtable_typeinfos_ref.ll | 4 +- .../devirt_validate_vtable_typeinfos_undef.ll | 2 +- .../ELF/lto/devirt_split_unit_localize.ll | 2 +- .../devirt_validate_vtable_typeinfos_ref.ll | 2 +- .../MachO/thinlto-split-unit-start-lib.ll | 4 +- llvm/docs/LangRef.rst | 20 ++--- llvm/include/llvm/AsmParser/LLParser.h | 3 +- llvm/include/llvm/Bitcode/LLVMBitCodes.h | 25 +++--- llvm/include/llvm/IR/ConstantFold.h | 2 +- llvm/include/llvm/IR/Constants.h | 13 +-- llvm/include/llvm/IR/Operator.h | 7 +- llvm/lib/Analysis/ConstantFolding.cpp | 43 +++++----- llvm/lib/AsmParser/LLParser.cpp | 57 +++++++++---- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 65 ++++++++------ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 7 +- llvm/lib/IR/AsmWriter.cpp | 13 ++- llvm/lib/IR/ConstantFold.cpp | 35 +++----- llvm/lib/IR/Constants.cpp | 28 ++++--- llvm/lib/IR/ConstantsContext.h | 51 ++++++++--- llvm/lib/IR/Operator.cpp | 8 +- .../AMDGPU/AMDGPULowerBufferFatPointers.cpp | 2 +- llvm/lib/Transforms/IPO/GlobalSplit.cpp | 84 +++++++++++++------ .../Transforms/Utils/FunctionComparator.cpp | 16 +++- llvm/test/Assembler/getelementptr.ll | 24 +++--- llvm/test/Assembler/inrange-errors.ll | 46 ++++++++++ llvm/test/Bitcode/compatibility-4.0.ll | 2 +- llvm/test/Bitcode/compatibility-5.0.ll | 2 +- llvm/test/Bitcode/compatibility-6.0.ll | 2 +- llvm/test/Bitcode/compatibility.ll | 4 +- llvm/test/Other/optimize-inrange-gep.ll | 18 +++- .../GlobalDCE/virtual-functions-base-call.ll | 4 +- .../virtual-functions-base-pointer-call.ll | 4 +- .../virtual-functions-derived-call.ll | 4 +- .../virtual-functions-derived-pointer-call.ll | 4 +- .../GlobalDCE/virtual-functions-novfe.ll | 4 +- .../virtual-functions-visibility-post-lto.ll | 6 +- .../virtual-functions-visibility-pre-lto.ll | 6 +- .../Transforms/GlobalDCE/virtual-functions.ll | 4 +- llvm/test/Transforms/GlobalDCE/vtable-rtti.ll | 2 +- llvm/test/Transforms/GlobalSplit/basic.ll | 20 ++--- .../Transforms/GlobalSplit/non-beneficial.ll | 2 +- llvm/test/Transforms/GlobalSplit/nonlocal.ll | 2 +- llvm/test/Transforms/Inline/devirtualize-4.ll | 6 +- llvm/test/Transforms/InstCombine/fmul.ll | 4 +- .../Transforms/InstSimplify/ConstProp/gep.ll | 12 +-- .../Internalize/vcall-visibility.ll | 2 +- llvm/test/Transforms/MergeFunc/constexpr.ll | 8 +- .../ThinLTOBitcodeWriter/pr33536.ll | 2 +- 70 files changed, 511 insertions(+), 341 deletions(-) create mode 100644 llvm/test/Assembler/inrange-errors.ll diff --git a/clang/lib/CodeGen/CGVTT.cpp b/clang/lib/CodeGen/CGVTT.cpp index 1d3f14f1c534..d2376b14dd58 100644 --- a/clang/lib/CodeGen/CGVTT.cpp +++ b/clang/lib/CodeGen/CGVTT.cpp @@ -77,9 +77,18 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT, llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.AddressPointIndex), }; + // Add inrange attribute to indicate that only the VTableIndex can be + // accessed. + unsigned ComponentSize = + CGM.getDataLayout().getTypeAllocSize(getVTableComponentType()); + unsigned VTableSize = CGM.getDataLayout().getTypeAllocSize( + cast<llvm::StructType>(VTable->getValueType()) + ->getElementType(AddressPoint.VTableIndex)); + unsigned Offset = ComponentSize * AddressPoint.AddressPointIndex; + llvm::ConstantRange InRange(llvm::APInt(32, -Offset, true), + llvm::APInt(32, VTableSize - Offset, true)); llvm::Constant *Init = llvm::ConstantExpr::getGetElementPtr( - VTable->getValueType(), VTable, Idxs, /*InBounds=*/true, - /*InRangeIndex=*/1); + VTable->getValueType(), VTable, Idxs, /*InBounds=*/true, InRange); VTTComponents.push_back(Init); } diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 60b45ee78d93..bdd53a192f82 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1885,19 +1885,27 @@ ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base, // Find the appropriate vtable within the vtable group, and the address point // within that vtable. + const VTableLayout &Layout = + CGM.getItaniumVTableContext().getVTableLayout(VTableClass); VTableLayout::AddressPointLocation AddressPoint = - CGM.getItaniumVTableContext() - .getVTableLayout(VTableClass) - .getAddressPoint(Base); + Layout.getAddressPoint(Base); llvm::Value *Indices[] = { llvm::ConstantInt::get(CGM.Int32Ty, 0), llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.VTableIndex), llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.AddressPointIndex), }; - return llvm::ConstantExpr::getGetElementPtr(VTable->getValueType(), VTable, - Indices, /*InBounds=*/true, - /*InRangeIndex=*/1); + // Add inrange attribute to indicate that only the VTableIndex can be + // accessed. + unsigned ComponentSize = + CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType()); + unsigned VTableSize = + ComponentSize * Layout.getVTableSize(AddressPoint.VTableIndex); + unsigned Offset = ComponentSize * AddressPoint.AddressPointIndex; + llvm::ConstantRange InRange(llvm::APInt(32, -Offset, true), + llvm::APInt(32, VTableSize - Offset, true)); + return llvm::ConstantExpr::getGetElementPtr( + VTable->getValueType(), VTable, Indices, /*InBounds=*/true, InRange); } // Check whether all the non-inline virtual methods for the class have the diff --git a/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-virtual-inheritance.cpp b/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-virtual-inheritance.cpp index f6cf834b5032..f03bb747b2a7 100644 --- a/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-virtual-inheritance.cpp +++ b/clang/test/CodeGenCXX/RelativeVTablesABI/diamond-virtual-inheritance.cpp @@ -9,19 +9,19 @@ // CHECK: @_ZTV1B.local = private unnamed_addr constant { [4 x i32], [4 x i32] } { [4 x i32] [i32 8, i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -8, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 1, i32 3) to i64)) to i32)] }, align 4 // VTT for B -// CHECK: @_ZTT1B ={{.*}} unnamed_addr constant [2 x ptr] [ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, inrange i32 1, i32 3)], align 8 +// CHECK: @_ZTT1B ={{.*}} unnamed_addr constant [2 x ptr] [ptr getelementptr inbounds inrange(-12, 4) ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 0, i32 3), ptr getelementptr inbounds inrange(-12, 4) ({ [4 x i32], [4 x i32] }, ptr @_ZTV1B.local, i32 0, i32 1, i32 3)], align 8 // VTable for C // CHECK: @_ZTV1C.local = private unnamed_addr constant { [4 x i32], [4 x i32] } { [4 x i32] [i32 8, i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -8, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1C.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 1, i32 3) to i64)) to i32)] }, align 4 // VTT for C -// CHECK: @_ZTT1C ={{.*}} unnamed_addr constant [2 x ptr] [ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, inrange i32 1, i32 3)], align 8 +// CHECK: @_ZTT1C ={{.*}} unnamed_addr constant [2 x ptr] [ptr getelementptr inbounds inrange(-12, 4) ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 0, i32 3), ptr getelementptr inbounds inrange(-12, 4) ({ [4 x i32], [4 x i32] }, ptr @_ZTV1C.local, i32 0, i32 1, i32 3)], align 8 // VTable for D // CHECK: @_ZTV1D.local = private unnamed_addr constant { [5 x i32], [4 x i32], [4 x i32] } { [5 x i32] [i32 16, i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1D3bazEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 8, i32 -8, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1C4barCEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 1, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -16, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1D.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 2, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 2, i32 3) to i64)) to i32)] }, align 4 // VTT for D -// CHECK: @_ZTT1D ={{.*}} unnamed_addr constant [7 x ptr] [ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, inrange i32 1, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D8_1C.local, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D8_1C.local, i32 0, inrange i32 1, i32 3), ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, inrange i32 2, i32 3), ptr getelementptr inbounds ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, inrange i32 1, i32 3)], align 8 +// CHECK: @_ZTT1D ={{.*}} unnamed_addr constant [7 x ptr] [ptr getelementptr inbounds inrange(-12, 8) ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 0, i32 3), ptr getelementptr inbounds inrange(-12, 4) ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, i32 0, i32 3), ptr getelementptr inbounds inrange(-12, 4) ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, i32 1, i32 3), ptr getelementptr inbounds inrange(-12, 4) ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D8_1C.local, i32 0, i32 0, i32 3), ptr getelementptr inbounds inrange(-12, 4) ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D8_1C.local, i32 0, i32 1, i32 3), ptr getelementptr inbounds inrange(-12, 4) ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 2, i32 3), ptr getelementptr inbounds inrange(-12, 4) ({ [5 x i32], [4 x i32], [4 x i32] }, ptr @_ZTV1D.local, i32 0, i32 1, i32 3)], align 8 // Construction vtable for B-in-D // CHECK: @_ZTC1D0_1B.local = private unnamed_addr constant { [4 x i32], [4 x i32] } { [4 x i32] [i32 16, i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1B4barBEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, i32 0, i32 3) to i64)) to i32)], [4 x i32] [i32 0, i32 -16, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, i32 1, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [4 x i32], [4 x i32] }, ptr @_ZTC1D0_1B.local, i32 0, i32 1, i32 3) to i64)) to i32)] }, align 4 diff --git a/clang/test/CodeGenCXX/auto-var-init.cpp b/clang/test/CodeGenCXX/auto-var-init.cpp index e5a9d015f22f..991eb73fe45c 100644 --- a/clang/test/CodeGenCXX/auto-var-init.cpp +++ b/clang/test/CodeGenCXX/auto-var-init.cpp @@ -1345,7 +1345,7 @@ TEST_UNINIT(base, base); // PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_base_uninit.uninit{{.+}}), !annotation [[AUTO_INIT]] // ZERO-LABEL: @test_base_uninit() // ZERO-O0: call void @llvm.memset{{.*}}, i8 0,{{.+}}), !annotation [[AUTO_INIT]] -// ZERO-O1: store ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV4base, i64 0, inrange i32 0, i64 2), {{.*}}, align 8 +// ZERO-O1: store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV4base, i64 0, i32 0, i64 2), {{.*}}, align 8 // ZERO-O1-NOT: !annotation TEST_BRACES(base, base); @@ -1366,7 +1366,7 @@ TEST_UNINIT(derived, derived); // ZERO-LABEL: @test_derived_uninit() // ZERO-O0: call void @llvm.memset{{.*}}, i8 0, {{.+}}), !annotation [[AUTO_INIT]] // ZERO-O1: store i64 0, {{.*}} align 8, !annotation [[AUTO_INIT]] -// ZERO-O1: store ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV7derived, i64 0, inrange i32 0, i64 2), {{.*}} align 8 +// ZERO-O1: store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV7derived, i64 0, i32 0, i64 2), {{.*}} align 8 TEST_BRACES(derived, derived); // CHECK-LABEL: @test_derived_braces() diff --git a/clang/test/CodeGenCXX/const-init-cxx11.cpp b/clang/test/CodeGenCXX/const-init-cxx11.cpp index 3a12fe444f13..7c92af0def52 100644 --- a/clang/test/CodeGenCXX/const-init-cxx11.cpp +++ b/clang/test/CodeGenCXX/const-init-cxx11.cpp @@ -344,13 +344,13 @@ namespace VirtualMembers { constexpr E() : B(3), c{'b','y','e'} {} char c[3]; }; - // CHECK: @_ZN14VirtualMembers1eE ={{.*}} global { ptr, double, i32, ptr, double, [5 x i8], i16, ptr, double, [5 x i8], [3 x i8] } { ptr getelementptr inbounds ({ [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 0, i32 2), double 1.000000e+00, i32 64, ptr getelementptr inbounds ({ [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 1, i32 2), double 2.000000e+00, [5 x i8] c"hello", i16 5, ptr getelementptr inbounds ({ [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN14VirtualMembers1EE, i32 0, inrange i32 2, i32 2), double 3.000000e+00, [5 x i8] c"world", [3 x i8] c"bye" } + // CHECK: @_ZN14VirtualMembers1eE ={{.*}} global { ptr, double, i32, ptr, double, [5 x i8], i16, ptr, double, [5 x i8], [3 x i8] } { ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN14VirtualMembers1EE, i32 0, i32 0, i32 2), double 1.000000e+00, i32 64, ptr getelementptr inbounds inrange(-16, 16) ({ [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN14VirtualMembers1EE, i32 0, i32 1, i32 2), double 2.000000e+00, [5 x i8] c"hello", i16 5, ptr getelementptr inbounds inrange(-16, 16) ({ [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN14VirtualMembers1EE, i32 0, i32 2, i32 2), double 3.000000e+00, [5 x i8] c"world", [3 x i8] c"bye" } E e; struct nsMemoryImpl { virtual void f(); }; - // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global %"struct.VirtualMembers::nsMemoryImpl" { ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN14VirtualMembers12nsMemoryImplE, i32 0, inrange i32 0, i32 2) } + // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global %"struct.VirtualMembers::nsMemoryImpl" { ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN14VirtualMembers12nsMemoryImplE, i32 0, i32 0, i32 2) } __attribute__((used)) static nsMemoryImpl sGlobalMemory; @@ -361,7 +361,7 @@ namespace VirtualMembers { T t; }; - // CHECK: @_ZN14VirtualMembers1tE ={{.*}} global { ptr, i32 } { ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN14VirtualMembers13TemplateClassIiEE, i32 0, inrange i32 0, i32 2), i32 42 } + // CHECK: @_ZN14VirtualMembers1tE ={{.*}} global { ptr, i32 } { ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN14VirtualMembers13TemplateClassIiEE, i32 0, i32 0, i32 2), i32 42 } TemplateClass<int> t; } diff --git a/clang/test/CodeGenCXX/constructor-init.cpp b/clang/test/CodeGenCXX/constructor-init.cpp index 3d473e67ea0d..f191599f360e 100644 --- a/clang/test/CodeGenCXX/constructor-init.cpp +++ b/clang/test/CodeGenCXX/constructor-init.cpp @@ -94,20 +94,20 @@ namespace InitVTable { }; // CHECK-LABEL: define{{.*}} void @_ZN10InitVTable1BC2Ev(ptr {{[^,]*}} %this) unnamed_addr - // CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2), ptr [[THIS:%.*]], + // CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN10InitVTable1BE, i32 0, i32 0, i32 2), ptr [[THIS:%.*]], // CHECK: [[VTBL:%.*]] = load ptr, ptr {{%.*}} // CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds ptr, ptr [[VTBL]], i64 0 // CHECK-NEXT: [[FN:%.*]] = load ptr, ptr [[FNP]] // CHECK-NEXT: [[ARG:%.*]] = call noundef i32 [[FN]](ptr {{[^,]*}} [[THIS]]) // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei(ptr {{[^,]*}} {{%.*}}, i32 noundef [[ARG]]) - // CHECK-NEXT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2), ptr [[THIS]] + // CHECK-NEXT: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN10InitVTable1BE, i32 0, i32 0, i32 2), ptr [[THIS]] // CHECK-NEXT: ret void B::B() : A(foo()) {} // CHECK-LABEL: define{{.*}} void @_ZN10InitVTable1BC2Ei(ptr {{[^,]*}} %this, i32 noundef %x) unnamed_addr // CHECK: [[ARG:%.*]] = add nsw i32 {{%.*}}, 5 // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei(ptr {{[^,]*}} {{%.*}}, i32 noundef [[ARG]]) - // CHECK-NEXT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2), ptr {{%.*}} + // CHECK-NEXT: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN10InitVTable1BE, i32 0, i32 0, i32 2), ptr {{%.*}} // CHECK-NEXT: ret void B::B(int x) : A(x + 5) {} } diff --git a/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp index 043dff44f37c..4f96a3ae6707 100644 --- a/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp +++ b/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp @@ -24,4 +24,4 @@ struct A { virtual void a(); }; A x(A& y) { return y; } // CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(ptr {{.*}}%this, ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %0) unnamed_addr -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, inrange i32 0, i32 2) +// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2) diff --git a/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp b/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp index 3548897ec4ba..e4f6995aec3c 100644 --- a/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp +++ b/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp @@ -163,7 +163,7 @@ void f(B b1) { // CHECK-LABEL: define linkonce_odr void @_ZN12rdar138169401AC2ERKS0_( // CHECK: [[THIS:%.*]] = load ptr, ptr -// CHECK-NEXT: store ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTVN12rdar138169401AE, i32 0, inrange i32 0, i32 2), ptr [[THIS]] +// CHECK-NEXT: store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTVN12rdar138169401AE, i32 0, i32 0, i32 2), ptr [[THIS]] // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], ptr [[THIS]], i32 0, i32 1 // CHECK-NEXT: [[OTHER:%.*]] = load ptr, ptr // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], ptr [[OTHER]], i32 0, i32 1 diff --git a/clang/test/CodeGenCXX/dynamic-cast-exact.cpp b/clang/test/CodeGenCXX/dynamic-cast-exact.cpp index bd283e85101b..86e1965b4ba6 100644 --- a/clang/test/CodeGenCXX/dynamic-cast-exact.cpp +++ b/clang/test/CodeGenCXX/dynamic-cast-exact.cpp @@ -23,7 +23,7 @@ B *exact_single(A *a) { // CHECK: [[LABEL_NOTNULL]]: // CHECK: %[[VPTR:.*]] = load ptr, ptr %[[PTR]] - // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[VPTR]], getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr @_ZTV1B, i32 0, inrange i32 1, i32 2) + // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[VPTR]], getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [4 x ptr] }, ptr @_ZTV1B, i32 0, i32 1, i32 2) // CHECK: %[[RESULT:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i64 -8 // CHECK: br i1 %[[MATCH]], label %[[LABEL_END:.*]], label %[[LABEL_FAILED]] @@ -42,7 +42,7 @@ B &exact_ref(A &a) { // CHECK: [[LABEL_NOTNULL]]: // CHECK: %[[VPTR:.*]] = load ptr, ptr %[[PTR]] - // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[VPTR]], getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr @_ZTV1B, i32 0, inrange i32 1, i32 2) + // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[VPTR]], getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [4 x ptr] }, ptr @_ZTV1B, i32 0, i32 1, i32 2) // CHECK: %[[RESULT:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i64 -8 // CHECK: br i1 %[[MATCH]], label %[[LABEL_END:.*]], label %[[LABEL_FAILED]] @@ -66,7 +66,7 @@ H *exact_multi(A *a) { // CHECK: %[[OFFSET_TO_TOP:.*]] = load i64, ptr %[[OFFSET_TO_TOP_SLOT]] // CHECK: %[[RESULT:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i64 %[[OFFSET_TO_TOP]] // CHECK: %[[DERIVED_VPTR:.*]] = load ptr, ptr %[[RESULT]] - // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[DERIVED_VPTR]], getelementptr inbounds ({ [5 x ptr], [4 x ptr], [4 x ptr], [6 x ptr], [6 x ptr] }, ptr @_ZTV1H, i32 0, inrange i32 0, i32 3) + // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[DERIVED_VPTR]], getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [4 x ptr], [4 x ptr], [6 x ptr], [6 x ptr] }, ptr @_ZTV1H, i32 0, i32 0, i32 3) // CHECK: br i1 %[[MATCH]], label %[[LABEL_END:.*]], label %[[LABEL_FAILED]] // CHECK: [[LABEL_FAILED]]: diff --git a/clang/test/CodeGenCXX/microsoft-interface.cpp b/clang/test/CodeGenCXX/microsoft-interface.cpp index d70caa15ed3c..09b30bc96c85 100644 --- a/clang/test/CodeGenCXX/microsoft-interface.cpp +++ b/clang/test/CodeGenCXX/microsoft-interface.cpp @@ -31,10 +31,10 @@ int fn() { // CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @_ZN1SC2Ev(ptr {{[^,]*}} %this) // CHECK: call x86_thiscallcc void @_ZN1IC2Ev(ptr {{[^,]*}} %{{[.0-9A-Z_a-z]+}}) -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1S, i32 0, inrange i32 0, i32 2), ptr %{{[.0-9A-Z_a-z]+}} +// CHECK: store ptr getelementptr inbounds inrange(-8, 4) ({ [3 x ptr] }, ptr @_ZTV1S, i32 0, i32 0, i32 2), ptr %{{[.0-9A-Z_a-z]+}} // CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @_ZN1IC2Ev(ptr {{[^,]*}} %this) -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1I, i32 0, inrange i32 0, i32 2), ptr %{{[.0-9A-Z_a-z]+}} +// CHECK: store ptr getelementptr inbounds inrange(-8, 4) ({ [3 x ptr] }, ptr @_ZTV1I, i32 0, i32 0, i32 2), ptr %{{[.0-9A-Z_a-z]+}} // CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef i32 @_ZN1I4testEv(ptr {{[^,]*}} %this) // CHECK: ret i32 1 diff --git a/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp index eb8f21b57aa7..c001ce9b755d 100644 --- a/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp +++ b/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp @@ -27,7 +27,7 @@ struct A { }; // CHECK-LABEL: define{{.*}} void @_ZN5Test21AD2Ev -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5Test21AE, i32 0, inrange i32 0, i32 2), ptr +// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test21AE, i32 0, i32 0, i32 2), ptr A::~A() { f(); } @@ -50,7 +50,7 @@ struct A { }; // CHECK-LABEL: define{{.*}} void @_ZN5Test31AD2Ev -// CHECK-NOT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5Test31AE, i32 0, inrange i32 0, i32 2), ptr +// CHECK-NOT: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test31AE, i32 0, i32 0, i32 2), ptr A::~A() { } @@ -76,7 +76,7 @@ struct A { }; // CHECK-LABEL: define{{.*}} void @_ZN5Test41AD2Ev -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5Test41AE, i32 0, inrange i32 0, i32 2), ptr +// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test41AE, i32 0, i32 0, i32 2), ptr A::~A() { } @@ -100,7 +100,7 @@ struct A { }; // CHECK-LABEL: define{{.*}} void @_ZN5Test51AD2Ev -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5Test51AE, i32 0, inrange i32 0, i32 2), ptr +// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test51AE, i32 0, i32 0, i32 2), ptr A::~A() { } @@ -128,7 +128,7 @@ struct A { }; // CHECK-LABEL: define{{.*}} void @_ZN5Test61AD2Ev -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5Test61AE, i32 0, inrange i32 0, i32 2), ptr +// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test61AE, i32 0, i32 0, i32 2), ptr A::~A() { } @@ -154,7 +154,7 @@ struct A { }; // CHECK-LABEL: define{{.*}} void @_ZN5Test71AD2Ev -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5Test71AE, i32 0, inrange i32 0, i32 2), ptr +// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test71AE, i32 0, i32 0, i32 2), ptr A::~A() { } @@ -180,7 +180,7 @@ struct A { }; // CHECK-LABEL: define{{.*}} void @_ZN5Test81AD2Ev -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5Test81AE, i32 0, inrange i32 0, i32 2), ptr +// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5Test81AE, i32 0, i32 0, i32 2), ptr A::~A() { } diff --git a/clang/test/CodeGenCXX/static-init.cpp b/clang/test/CodeGenCXX/static-init.cpp index a44f78116dbb..51080c895ec6 100644 --- a/clang/test/CodeGenCXX/static-init.cpp +++ b/clang/test/CodeGenCXX/static-init.cpp @@ -14,7 +14,7 @@ // CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0, comdat, align 8{{$}} // CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16 // CHECK98: @_ZZN5test414useStaticLocalEvE3obj = linkonce_odr global %"struct.test4::HasVTable" zeroinitializer, comdat, align 8 -// CHECK11: @_ZZN5test414useStaticLocalEvE3obj = linkonce_odr global %"struct.test4::HasVTable" { ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5test49HasVTableE, i32 0, inrange i32 0, i32 2) }, comdat, align 8 +// CHECK11: @_ZZN5test414useStaticLocalEvE3obj = linkonce_odr global %"struct.test4::HasVTable" { ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5test49HasVTableE, i32 0, i32 0, i32 2) }, comdat, align 8 struct A { A(); diff --git a/clang/test/CodeGenCXX/strict-vtable-pointers.cpp b/clang/test/CodeGenCXX/strict-vtable-pointers.cpp index 34e50b39a5da..6dffa50a5430 100644 --- a/clang/test/CodeGenCXX/strict-vtable-pointers.cpp +++ b/clang/test/CodeGenCXX/strict-vtable-pointers.cpp @@ -154,10 +154,10 @@ struct DynamicDerivedMultiple; // CHECK-CTORS: call void @_ZN12DynamicBase2C2Ev( // CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0 -// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 0, i32 2), {{.*}} %[[THIS0]] +// CHECK-CTORS: store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV22DynamicDerivedMultiple, i32 0, i32 0, i32 2), ptr %[[THIS0]] // CHECK-CTORS: %[[THIS_ADD:.*]] = getelementptr inbounds i8, ptr %[[THIS0]], i64 16 -// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 1, i32 2), {{.*}} %[[THIS_ADD]] +// CHECK-CTORS: store ptr getelementptr inbounds inrange(-16, 8) ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV22DynamicDerivedMultiple, i32 0, i32 1, i32 2), ptr %[[THIS_ADD]] // CHECK-CTORS-LABEL: {{^}}} struct DynamicFromStatic; diff --git a/clang/test/CodeGenCXX/visibility.cpp b/clang/test/CodeGenCXX/visibility.cpp index e307b8747c84..e1061f3dbd18 100644 --- a/clang/test/CodeGenCXX/visibility.cpp +++ b/clang/test/CodeGenCXX/visibility.cpp @@ -207,7 +207,7 @@ namespace test27 { // CHECK-HIDDEN: @_ZGVZN6test681fC1EvE4test = linkonce_odr hidden global // CHECK-HIDDEN: @_ZTVN6test701DE = linkonce_odr hidden unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr @_ZTIN6test701DE] }, align 8 -// CHECK-HIDDEN: @_ZTTN6test701DE = linkonce_odr hidden unnamed_addr constant [1 x ptr] [ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN6test701DE, i32 0, inrange i32 0, i32 3)], align 8 +// CHECK-HIDDEN: @_ZTTN6test701DE = linkonce_odr hidden unnamed_addr constant [1 x ptr] [ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr] }, ptr @_ZTVN6test701DE, i32 0, i32 0, i32 3)], align 8 // CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global // CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global diff --git a/clang/test/CodeGenCXX/vtable-assume-load-address-space.cpp b/clang/test/CodeGenCXX/vtable-assume-load-address-space.cpp index 251d12bbb62f..d765fe94d9b0 100644 --- a/clang/test/CodeGenCXX/vtable-assume-load-address-space.cpp +++ b/clang/test/CodeGenCXX/vtable-assume-load-address-space.cpp @@ -25,7 +25,7 @@ void g(A *a) { a->foo(); } // CHECK1-LABEL: define{{.*}} void @_ZN5test14fooAEv() // CHECK1: call void @_ZN5test11AC1Ev(ptr // CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr %{{.*}} -// CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11AE, i32 0, inrange i32 0, i32 2) +// CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11AE, i32 0, i32 0, i32 2) // CHECK1: call void @llvm.assume(i1 %[[CMP]]) // CHECK1-LABEL: {{^}}} @@ -37,7 +37,7 @@ void fooA() { // CHECK1-LABEL: define{{.*}} void @_ZN5test14fooBEv() // CHECK1: call void @_ZN5test11BC1Ev(ptr {{[^,]*}} %{{.*}}) // CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr %{{.*}} -// CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11BE, i32 0, inrange i32 0, i32 2) +// CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11BE, i32 0, i32 0, i32 2) // CHECK1: call void @llvm.assume(i1 %[[CMP]]) // CHECK1-LABEL: {{^}}} @@ -71,12 +71,12 @@ void h(B *b) { b->bar(); } // CHECK2-LABEL: define{{.*}} void @_ZN5test24testEv() // CHECK2: call void @_ZN5test21CC1Ev(ptr // CHECK2: %[[VTABLE:.*]] = load ptr addrspace(1), ptr {{.*}} -// CHECK2: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, inrange i32 0, i32 2) +// CHECK2: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, i32 0, i32 2) // CHECK2: call void @llvm.assume(i1 %[[CMP]]) // CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i64 8 // CHECK2: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr %[[ADD_PTR]] -// CHECK2: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, inrange i32 1, i32 2) +// CHECK2: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, i32 1, i32 2) // CHECK2: call void @llvm.assume(i1 %[[CMP2]]) // CHECK2: call void @_ZN5test21gEPNS_1AE( @@ -107,7 +107,7 @@ void g(B *a) { a->foo(); } // CHECK3-LABEL: define{{.*}} void @_ZN5test34testEv() // CHECK3: call void @_ZN5test31CC1Ev(ptr -// CHECK3: %[[CMP:.*]] = icmp eq ptr addrspace(1) %{{.*}}, getelementptr inbounds ({ [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test31CE, i32 0, inrange i32 0, i32 3) +// CHECK3: %[[CMP:.*]] = icmp eq ptr addrspace(1) %{{.*}}, getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test31CE, i32 0, i32 0, i32 3) // CHECK3: call void @llvm.assume(i1 %[[CMP]]) // CHECK3-LABLEL: } void test() { @@ -136,11 +136,11 @@ void g(C *c) { c->foo(); } // CHECK4-LABEL: define{{.*}} void @_ZN5test44testEv() // CHECK4: call void @_ZN5test41CC1Ev(ptr // CHECK4: %[[VTABLE:.*]] = load ptr addrspace(1), ptr %{{.*}} -// CHECK4: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, inrange i32 0, i32 4) +// CHECK4: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, i32 0, i32 4) // CHECK4: call void @llvm.assume(i1 %[[CMP]] // CHECK4: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr %{{.*}} -// CHECK4: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, inrange i32 0, i32 4) +// CHECK4: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, i32 0, i32 4) // CHECK4: call void @llvm.assume(i1 %[[CMP2]]) // CHECK4-LABEL: {{^}}} diff --git a/clang/test/CodeGenCXX/vtable-assume-load.cpp b/clang/test/CodeGenCXX/vtable-assume-load.cpp index bd9e4fc62520..6ce07d0db1b1 100644 --- a/clang/test/CodeGenCXX/vtable-assume-load.cpp +++ b/clang/test/CodeGenCXX/vtable-assume-load.cpp @@ -27,7 +27,7 @@ void g(A *a) { a->foo(); } // CHECK1-LABEL: define{{.*}} void @_ZN5test14fooAEv() // CHECK1: call void @_ZN5test11AC1Ev(ptr // CHECK1: %[[VTABLE:.*]] = load ptr, ptr %{{.*}} -// CHECK1: %[[CMP:.*]] = icmp eq ptr %[[VTABLE]], getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5test11AE, i32 0, inrange i32 0, i32 2) +// CHECK1: %[[CMP:.*]] = icmp eq ptr %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5test11AE, i32 0, i32 0, i32 2) // CHECK1: call void @llvm.assume(i1 %[[CMP]]) // CHECK1-LABEL: {{^}}} @@ -39,7 +39,7 @@ void fooA() { // CHECK1-LABEL: define{{.*}} void @_ZN5test14fooBEv() // CHECK1: call void @_ZN5test11BC1Ev(ptr {{[^,]*}} %{{.*}}) // CHECK1: %[[VTABLE:.*]] = load ptr, ptr %{{.*}} -// CHECK1: %[[CMP:.*]] = icmp eq ptr %[[VTABLE]], getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5test11BE, i32 0, inrange i32 0, i32 2) +// CHECK1: %[[CMP:.*]] = icmp eq ptr %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5test11BE, i32 0, i32 0, i32 2) // CHECK1: call void @llvm.assume(i1 %[[CMP]]) // CHECK1-LABEL: {{^}}} @@ -73,12 +73,12 @@ void h(B *b) { b->bar(); } // CHECK2-LABEL: define{{.*}} void @_ZN5test24testEv() // CHECK2: call void @_ZN5test21CC1Ev(ptr // CHECK2: %[[VTABLE:.*]] = load ptr, ptr {{.*}} -// CHECK2: %[[CMP:.*]] = icmp eq ptr %[[VTABLE]], getelementptr inbounds ({ [3 x ptr], [3 x ptr] }, ptr @_ZTVN5test21CE, i32 0, inrange i32 0, i32 2) +// CHECK2: %[[CMP:.*]] = icmp eq ptr %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr], [3 x ptr] }, ptr @_ZTVN5test21CE, i32 0, i32 0, i32 2) // CHECK2: call void @llvm.assume(i1 %[[CMP]]) // CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i64 8 // CHECK2: %[[VTABLE2:.*]] = load ptr, ptr %[[ADD_PTR]] -// CHECK2: %[[CMP2:.*]] = icmp eq ptr %[[VTABLE2]], getelementptr inbounds ({ [3 x ptr], [3 x ptr] }, ptr @_ZTVN5test21CE, i32 0, inrange i32 1, i32 2) +// CHECK2: %[[CMP2:.*]] = icmp eq ptr %[[VTABLE2]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr], [3 x ptr] }, ptr @_ZTVN5test21CE, i32 0, i32 1, i32 2) // CHECK2: call void @llvm.assume(i1 %[[CMP2]]) // CHECK2: call void @_ZN5test21gEPNS_1AE( @@ -109,7 +109,7 @@ void g(B *a) { a->foo(); } // CHECK3-LABEL: define{{.*}} void @_ZN5test34testEv() // CHECK3: call void @_ZN5test31CC1Ev(ptr -// CHECK3: %[[CMP:.*]] = icmp eq ptr %{{.*}}, getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTVN5test31CE, i32 0, inrange i32 0, i32 3) +// CHECK3: %[[CMP:.*]] = icmp eq ptr %{{.*}}, getelementptr inbounds inrange(-24, 8) ({ [4 x ptr] }, ptr @_ZTVN5test31CE, i32 0, i32 0, i32 3) // CHECK3: call void @llvm.assume(i1 %[[CMP]]) // CHECK3-LABLEL: } void test() { @@ -138,11 +138,11 @@ void g(C *c) { c->foo(); } // CHECK4-LABEL: define{{.*}} void @_ZN5test44testEv() // CHECK4: call void @_ZN5test41CC1Ev(ptr // CHECK4: %[[VTABLE:.*]] = load ptr, ptr %{{.*}} -// CHECK4: %[[CMP:.*]] = icmp eq ptr %[[VTABLE]], getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTVN5test41CE, i32 0, inrange i32 0, i32 4) +// CHECK4: %[[CMP:.*]] = icmp eq ptr %[[VTABLE]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTVN5test41CE, i32 0, i32 0, i32 4) // CHECK4: call void @llvm.assume(i1 %[[CMP]] // CHECK4: %[[VTABLE2:.*]] = load ptr, ptr %{{.*}} -// CHECK4: %[[CMP2:.*]] = icmp eq ptr %[[VTABLE2]], getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTVN5test41CE, i32 0, inrange i32 0, i32 4) +// CHECK4: %[[CMP2:.*]] = icmp eq ptr %[[VTABLE2]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTVN5test41CE, i32 0, i32 0, i32 4) // CHECK4: call void @llvm.assume(i1 %[[CMP2]]) // CHECK4-LABEL: {{^}}} diff --git a/clang/test/CodeGenCXX/vtable-pointer-initialization-address-space.cpp b/clang/test/CodeGenCXX/vtable-pointer-initialization-address-space.cpp index 247864862fec..a3f12f0ebfc8 100644 --- a/clang/test/CodeGenCXX/vtable-pointer-initialization-address-space.cpp +++ b/clang/test/CodeGenCXX/vtable-pointer-initialization-address-space.cpp @@ -21,13 +21,13 @@ struct A : Base { // CHECK-LABEL: define{{.*}} void @_ZN1AC2Ev(ptr {{[^,]*}} %this) unnamed_addr // CHECK: call void @_ZN4BaseC2Ev( -// CHECK: store ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1A, i32 0, inrange i32 0, i32 2) +// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1A, i32 0, i32 0, i32 2) // CHECK: call void @_ZN5FieldC1Ev( // CHECK: ret void A::A() { } // CHECK-LABEL: define{{.*}} void @_ZN1AD2Ev(ptr {{[^,]*}} %this) unnamed_addr -// CHECK: store ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1A, i32 0, inrange i32 0, i32 2) +// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1A, i32 0, i32 0, i32 2) // CHECK: call void @_ZN5FieldD1Ev( // CHECK: call void @_ZN4BaseD2Ev( // CHECK: ret void @@ -49,12 +49,12 @@ void f() { B b; } // CHECK-LABEL: define linkonce_odr void @_ZN1BC2Ev(ptr {{[^,]*}} %this) unnamed_addr // CHECK: call void @_ZN4BaseC2Ev( -// CHECK: store ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, inrange i32 0, i32 2) +// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2) // CHECK: call void @_ZN5FieldC1Ev // CHECK: ret void // CHECK-LABEL: define linkonce_odr void @_ZN1BD2Ev(ptr {{[^,]*}} %this) unnamed_addr -// CHECK: store ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, inrange i32 0, i32 2) +// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2) // CHECK: call void @_ZN5FieldD1Ev( // CHECK: call void @_ZN4BaseD2Ev( // CHECK: ret void diff --git a/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp b/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp index 00eda6233d94..16b180705fa6 100644 --- a/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp +++ b/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp @@ -21,13 +21,13 @@ struct A : Base { // CHECK-LABEL: define{{.*}} void @_ZN1AC2Ev(ptr {{[^,]*}} %this) unnamed_addr // CHECK: call void @_ZN4BaseC2Ev( -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, inrange i32 0, i32 2) +// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2) // CHECK: call void @_ZN5FieldC1Ev( // CHECK: ret void A::A() { } // CHECK-LABEL: define{{.*}} void @_ZN1AD2Ev(ptr {{[^,]*}} %this) unnamed_addr -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, inrange i32 0, i32 2) +// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2) // CHECK: call void @_ZN5FieldD1Ev( // CHECK: call void @_ZN4BaseD2Ev( // CHECK: ret void @@ -49,12 +49,12 @@ void f() { B b; } // CHECK-LABEL: define linkonce_odr void @_ZN1BC2Ev(ptr {{[^,]*}} %this) unnamed_addr // CHECK: call void @_ZN4BaseC2Ev( -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, inrange i32 0, i32 2) +// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 2) // CHECK: call void @_ZN5FieldC1Ev // CHECK: ret void // CHECK-LABEL: define linkonce_odr void @_ZN1BD2Ev(ptr {{[^,]*}} %this) unnamed_addr -// CHECK: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, inrange i32 0, i32 2) +// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 2) // CHECK: call void @_ZN5FieldD1Ev( // CHECK: call void @_ZN4BaseD2Ev( // CHECK: ret void diff --git a/clang/test/CodeGenCXX/vtt-address-space.cpp b/clang/test/CodeGenCXX/vtt-address-space.cpp index e567ae49811a..24f4e2a755da 100644 --- a/clang/test/CodeGenCXX/vtt-address-space.cpp +++ b/clang/test/CodeGenCXX/vtt-address-space.cpp @@ -18,7 +18,7 @@ namespace Test { D d; } -// CHECK: linkonce_odr unnamed_addr addrspace(1) constant [13 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, inrange i32 0, i32 5), ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE0_NS_2C1E, i32 0, inrange i32 0, i32 3), ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE0_NS_2C1E, i32 0, inrange i32 1, i32 3), ptr addrspace(1) getelementptr inbounds ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, inrange i32 0, i32 6), ptr addrspace(1) getelementptr inbounds ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, inrange i32 0, i32 6), ptr addrspace(1) getelementptr inbounds ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, inrange i32 1, i32 3), ptr addrspace(1) getelementptr inbounds ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, inrange i32 2, i32 3), ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, inrange i32 2, i32 3), ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, inrange i32 1, i32 6), ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, inrange i32 1, i32 6), ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, inrange i32 3, i32 3), ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE64_NS_2V2E, i32 0, inrange i32 0, i32 3), ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE64_NS_2V2E, i32 0, inrange i32 1, i32 3)], comdat, align 8 +// CHECK: linkonce_odr unnamed_addr addrspace(1) constant [13 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-40, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 0, i32 5), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE0_NS_2C1E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE0_NS_2C1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE16_NS_2C2E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN4Test1DE, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE64_NS_2V2E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN4Test1DE64_NS_2V2E, i32 0, i32 1, i32 3)], comdat, align 8 // CHECK: call void @_ZN4Test2V2C2Ev(ptr noundef nonnull align 8 dereferenceable(20) %2, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 11)) // CHECK: call void @_ZN4Test2C1C2Ev(ptr noundef nonnull align 8 dereferenceable(12) %this1, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 1)) // CHECK: call void @_ZN4Test2C2C2Ev(ptr noundef nonnull align 8 dereferenceable(12) %3, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 3)) diff --git a/clang/test/CodeGenCXX/vtt-layout-address-space.cpp b/clang/test/CodeGenCXX/vtt-layout-address-space.cpp index 2f80c9ec5f9f..409efb9be021 100644 --- a/clang/test/CodeGenCXX/vtt-layout-address-space.cpp +++ b/clang/test/CodeGenCXX/vtt-layout-address-space.cpp @@ -78,12 +78,12 @@ namespace Test6 { } } -// CHECK: @_ZTTN5Test11BE ={{.*}} unnamed_addr addrspace(1) constant [1 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds ({ [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test11BE, i32 0, inrange i32 0, i32 3)] +// CHECK: @_ZTTN5Test11BE ={{.*}} unnamed_addr addrspace(1) constant [1 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test11BE, i32 0, i32 0, i32 3)] // CHECK: @_ZTVN5Test51AE ={{.*}} unnamed_addr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTIN5Test51AE, ptr addrspace(1) addrspacecast (ptr @__cxa_pure_virtual to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN5Test51A6anchorEv to ptr addrspace(1))] } // CHECK: @_ZTVN5Test61AE ={{.*}} unnamed_addr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTIN5Test61AE, ptr addrspace(1) addrspacecast (ptr @__cxa_deleted_virtual to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @_ZN5Test61A6anchorEv to ptr addrspace(1))] } -// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr addrspace(1) constant [2 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4), ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4)] -// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr addrspace(1) constant [13 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, inrange i32 0, i32 5), ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 0, i32 3), ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 1, i32 3), ptr addrspace(1) getelementptr inbounds ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6), ptr addrspace(1) getelementptr inbounds ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6), ptr addrspace(1) getelementptr inbounds ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 1, i32 3), ptr addrspace(1) getelementptr inbounds ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 2, i32 3), ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, inrange i32 2, i32 3), ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6), ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6), ptr addrspace(1) getelementptr inbounds ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, inrange i32 3, i32 3), ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 0, i32 3), ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 1, i32 3)] +// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr addrspace(1) constant [2 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test21CE, i32 0, i32 0, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test21CE, i32 0, i32 0, i32 4)] +// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr addrspace(1) constant [13 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-40, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 0, i32 5), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [7 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-48, 8) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 1, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [5 x ptr addrspace(1)], [7 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test31DE, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 1, i32 3)] // CHECK: @_ZTVN5Test41DE = linkonce_odr unnamed_addr addrspace(1) constant { [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] } { [6 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 72 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 16 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 56 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 40 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) @_ZTIN5Test41DE], [8 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 40 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 24 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 56 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) inttoptr (i64 -16 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE, ptr addrspace(1) addrspacecast (ptr @_ZN5Test42V31gEv to ptr addrspace(1))], [3 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 16 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -40 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE], [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) inttoptr (i64 -56 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE, ptr addrspace(1) addrspacecast (ptr @_ZN5Test42A21fEv to ptr addrspace(1))], [4 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 -16 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -32 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -72 to ptr addrspace(1)), ptr addrspace(1) @_ZTIN5Test41DE] } -// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr addrspace(1) constant [19 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, inrange i32 0, i32 6), ptr addrspace(1) getelementptr inbounds ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 0, i32 4), ptr addrspace(1) getelementptr inbounds ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 1, i32 3), ptr addrspace(1) getelementptr inbounds ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 2, i32 3), ptr addrspace(1) getelementptr inbounds ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7), ptr addrspace(1) getelementptr inbounds ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7), ptr addrspace(1) getelementptr inbounds ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 1, i32 4), ptr addrspace(1) getelementptr inbounds ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 2, i32 3), ptr addrspace(1) getelementptr inbounds ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 3, i32 3), ptr addrspace(1) getelementptr inbounds ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, inrange i32 2, i32 3), ptr addrspace(1) getelementptr inbounds ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, inrange i32 3, i32 3), ptr addrspace(1) getelementptr inbounds ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7), ptr addrspace(1) getelementptr inbounds ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7), ptr addrspace(1) getelementptr inbounds ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, inrange i32 4, i32 4), ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 0, i32 3), ptr addrspace(1) getelementptr inbounds ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 1, i32 3), ptr addrspace(1) getelementptr inbounds ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 0, i32 4), ptr addrspace(1) getelementptr inbounds ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 1, i32 3), ptr addrspace(1) getelementptr inbounds ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 2, i32 3)] +// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr addrspace(1) constant [19 x ptr addrspace(1)] [ptr addrspace(1) getelementptr inbounds inrange(-48, 0) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 0, i32 6), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 0, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 0, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 0, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 1, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [8 x ptr addrspace(1)], [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 2, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 3, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 1, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-56, 8) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 1, i32 7), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [6 x ptr addrspace(1)], [8 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5Test41DE, i32 0, i32 4, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 0, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-32, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 0, i32 4), ptr addrspace(1) getelementptr inbounds inrange(-24, 0) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 1, i32 3), ptr addrspace(1) getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)], [3 x ptr addrspace(1)], [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 2, i32 3)] // CHECK: declare void @__cxa_pure_virtual() unnamed_addr // CHECK: declare void @__cxa_deleted_virtual() unnamed_addr diff --git a/clang/test/CodeGenCXX/vtt-layout.cpp b/clang/test/CodeGenCXX/vtt-layout.cpp index 595c64c6a33b..573a8de3094a 100644 --- a/clang/test/CodeGenCXX/vtt-layout.cpp +++ b/clang/test/CodeGenCXX/vtt-layout.cpp @@ -78,12 +78,12 @@ namespace Test6 { } } -// CHECK: @_ZTTN5Test11BE ={{.*}} unnamed_addr constant [1 x ptr] [ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTVN5Test11BE, i32 0, inrange i32 0, i32 3)] +// CHECK: @_ZTTN5Test11BE ={{.*}} unnamed_addr constant [1 x ptr] [ptr getelementptr inbounds inrange(-24, 8) ({ [4 x ptr] }, ptr @_ZTVN5Test11BE, i32 0, i32 0, i32 3)] // CHECK: @_ZTVN5Test51AE ={{.*}} unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTIN5Test51AE, ptr @__cxa_pure_virtual, ptr @_ZN5Test51A6anchorEv] } // CHECK: @_ZTVN5Test61AE ={{.*}} unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTIN5Test61AE, ptr @__cxa_deleted_virtual, ptr @_ZN5Test61A6anchorEv] } -// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x ptr] [ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4), ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTVN5Test21CE, i32 0, inrange i32 0, i32 4)] -// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x ptr] [ptr getelementptr inbounds ({ [5 x ptr], [7 x ptr], [4 x ptr], [3 x ptr] }, ptr @_ZTVN5Test31DE, i32 0, inrange i32 0, i32 5), ptr getelementptr inbounds ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE0_NS_2C1E, i32 0, inrange i32 1, i32 3), ptr getelementptr inbounds ({ [7 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6), ptr getelementptr inbounds ({ [7 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 0, i32 6), ptr getelementptr inbounds ({ [7 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 1, i32 3), ptr getelementptr inbounds ({ [7 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE16_NS_2C2E, i32 0, inrange i32 2, i32 3), ptr getelementptr inbounds ({ [5 x ptr], [7 x ptr], [4 x ptr], [3 x ptr] }, ptr @_ZTVN5Test31DE, i32 0, inrange i32 2, i32 3), ptr getelementptr inbounds ({ [5 x ptr], [7 x ptr], [4 x ptr], [3 x ptr] }, ptr @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6), ptr getelementptr inbounds ({ [5 x ptr], [7 x ptr], [4 x ptr], [3 x ptr] }, ptr @_ZTVN5Test31DE, i32 0, inrange i32 1, i32 6), ptr getelementptr inbounds ({ [5 x ptr], [7 x ptr], [4 x ptr], [3 x ptr] }, ptr @_ZTVN5Test31DE, i32 0, inrange i32 3, i32 3), ptr getelementptr inbounds ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE64_NS_2V2E, i32 0, inrange i32 1, i32 3)] +// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x ptr] [ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTVN5Test21CE, i32 0, i32 0, i32 4), ptr getelementptr inbounds inrange(-32, 8) ({ [5 x ptr] }, ptr @_ZTVN5Test21CE, i32 0, i32 0, i32 4)] +// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x ptr] [ptr getelementptr inbounds inrange(-40, 0) ({ [5 x ptr], [7 x ptr], [4 x ptr], [3 x ptr] }, ptr @_ZTVN5Test31DE, i32 0, i32 0, i32 5), ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 0, i32 3), ptr getelementptr inbounds inrange(-24, 8) ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE0_NS_2C1E, i32 0, i32 1, i32 3), ptr getelementptr inbounds inrange(-48, 8) ({ [7 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr getelementptr inbounds inrange(-48, 8) ({ [7 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 0, i32 6), ptr getelementptr inbounds inrange(-24, 0) ({ [7 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 1, i32 3), ptr getelementptr inbounds inrange(-24, 8) ({ [7 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE16_NS_2C2E, i32 0, i32 2, i32 3), ptr getelementptr inbounds inrange(-24, 8) ({ [5 x ptr], [7 x ptr], [4 x ptr], [3 x ptr] }, ptr @_ZTVN5Test31DE, i32 0, i32 2, i32 3), ptr getelementptr inbounds inrange(-48, 8) ({ [5 x ptr], [7 x ptr], [4 x ptr], [3 x ptr] }, ptr @_ZTVN5Test31DE, i32 0, i32 1, i32 6), ptr getelementptr inbounds inrange(-48, 8) ({ [5 x ptr], [7 x ptr], [4 x ptr], [3 x ptr] }, ptr @_ZTVN5Test31DE, i32 0, i32 1, i32 6), ptr getelementptr inbounds inrange(-24, 0) ({ [5 x ptr], [7 x ptr], [4 x ptr], [3 x ptr] }, ptr @_ZTVN5Test31DE, i32 0, i32 3, i32 3), ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 0, i32 3), ptr getelementptr inbounds inrange(-24, 8) ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test31DE64_NS_2V2E, i32 0, i32 1, i32 3)] // CHECK: @_ZTVN5Test41DE = linkonce_odr unnamed_addr constant { [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] } { [6 x ptr] [ptr inttoptr (i64 72 to ptr), ptr inttoptr (i64 16 to ptr), ptr inttoptr (i64 56 to ptr), ptr inttoptr (i64 40 to ptr), ptr null, ptr @_ZTIN5Test41DE], [8 x ptr] [ptr inttoptr (i64 40 to ptr), ptr inttoptr (i64 24 to ptr), ptr inttoptr (i64 56 to ptr), ptr null, ptr null, ptr inttoptr (i64 -16 to ptr), ptr @_ZTIN5Test41DE, ptr @_ZN5Test42V31gEv], [3 x ptr] [ptr inttoptr (i64 16 to ptr), ptr inttoptr (i64 -40 to ptr), ptr @_ZTIN5Test41DE], [4 x ptr] [ptr null, ptr inttoptr (i64 -56 to ptr), ptr @_ZTIN5Test41DE, ptr @_ZN5Test42A21fEv], [4 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -32 to ptr), ptr inttoptr (i64 -72 to ptr), ptr @_ZTIN5Test41DE] } -// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x ptr] [ptr getelementptr inbounds ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, inrange i32 0, i32 6), ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 0, i32 4), ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 1, i32 3), ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE0_NS_2C1E, i32 0, inrange i32 2, i32 3), ptr getelementptr inbounds ({ [8 x ptr], [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7), ptr getelementptr inbounds ({ [8 x ptr], [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 0, i32 7), ptr getelementptr inbounds ({ [8 x ptr], [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 1, i32 4), ptr getelementptr inbounds ({ [8 x ptr], [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 2, i32 3), ptr getelementptr inbounds ({ [8 x ptr], [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE16_NS_2C2E, i32 0, inrange i32 3, i32 3), ptr getelementptr inbounds ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, inrange i32 2, i32 3), ptr getelementptr inbounds ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, inrange i32 3, i32 3), ptr getelementptr inbounds ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7), ptr getelementptr inbounds ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, inrange i32 1, i32 7), ptr getelementptr inbounds ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, inrange i32 4, i32 4), ptr getelementptr inbounds ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 0, i32 3), ptr getelementptr inbounds ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE40_NS_2V1E, i32 0, inrange i32 1, i32 3), ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 0, i32 4), ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 1, i32 3), ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE72_NS_2V2E, i32 0, inrange i32 2, i32 3)] +// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x ptr] [ptr getelementptr inbounds inrange(-48, 0) ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, i32 0, i32 6), ptr getelementptr inbounds inrange(-32, 0) ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 0, i32 4), ptr getelementptr inbounds inrange(-24, 0) ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 1, i32 3), ptr getelementptr inbounds inrange(-24, 8) ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE0_NS_2C1E, i32 0, i32 2, i32 3), ptr getelementptr inbounds inrange(-56, 8) ({ [8 x ptr], [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 0, i32 7), ptr getelementptr inbounds inrange(-56, 8) ({ [8 x ptr], [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 0, i32 7), ptr getelementptr inbounds inrange(-32, 0) ({ [8 x ptr], [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 1, i32 4), ptr getelementptr inbounds inrange(-24, 0) ({ [8 x ptr], [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 2, i32 3), ptr getelementptr inbounds inrange(-24, 8) ({ [8 x ptr], [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE16_NS_2C2E, i32 0, i32 3, i32 3), ptr getelementptr inbounds inrange(-24, 0) ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, i32 2, i32 3), ptr getelementptr inbounds inrange(-24, 8) ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, i32 3, i32 3), ptr getelementptr inbounds inrange(-56, 8) ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, i32 1, i32 7), ptr getelementptr inbounds inrange(-56, 8) ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, i32 1, i32 7), ptr getelementptr inbounds inrange(-32, 0) ({ [6 x ptr], [8 x ptr], [3 x ptr], [4 x ptr], [4 x ptr] }, ptr @_ZTVN5Test41DE, i32 0, i32 4, i32 4), ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 0, i32 3), ptr getelementptr inbounds inrange(-24, 8) ({ [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE40_NS_2V1E, i32 0, i32 1, i32 3), ptr getelementptr inbounds inrange(-32, 0) ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 0, i32 4), ptr getelementptr inbounds inrange(-24, 0) ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 1, i32 3), ptr getelementptr inbounds inrange(-24, 8) ({ [4 x ptr], [3 x ptr], [4 x ptr] }, ptr @_ZTCN5Test41DE72_NS_2V2E, i32 0, i32 2, i32 3)] // CHECK: declare void @__cxa_pure_virtual() unnamed_addr // CHECK: declare void @__cxa_deleted_virtual() unnamed_addr diff --git a/clang/test/OpenMP/target_data_use_device_ptr_inheritance_codegen.cpp b/clang/test/OpenMP/target_data_use_device_ptr_inheritance_codegen.cpp index 3db18643d3f0..20d3bd2ce11c 100644 --- a/clang/test/OpenMP/target_data_use_device_ptr_inheritance_codegen.cpp +++ b/clang/test/OpenMP/target_data_use_device_ptr_inheritance_codegen.cpp @@ -91,7 +91,7 @@ void foo() { // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: call void @_ZN1AC2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR1]] -// CHECK-NEXT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, inrange i32 0, i32 2), ptr [[THIS1]], align 8 +// CHECK-NEXT: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 2), ptr [[THIS1]], align 8 // CHECK-NEXT: ret void // CHECK-LABEL: define {{[^@]+}}@_ZN1AC2Ev // CHECK-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 { @@ -99,7 +99,7 @@ void foo() { // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, inrange i32 0, i32 2), ptr [[THIS1]], align 8 +// CHECK-NEXT: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2), ptr [[THIS1]], align 8 // CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [[CLASS_A:%.*]], ptr [[THIS1]], i32 0, i32 1 // CHECK-NEXT: store ptr null, ptr [[PTR]], align 8 // CHECK-NEXT: ret void @@ -168,7 +168,7 @@ void foo() { // CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: call void @_ZN1AC2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR1]] -// CHECK1-NEXT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, inrange i32 0, i32 2), ptr [[THIS1]], align 8 +// CHECK1-NEXT: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 2), ptr [[THIS1]], align 8 // CHECK1-NEXT: ret void // // @@ -178,7 +178,7 @@ void foo() { // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK1-NEXT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, inrange i32 0, i32 2), ptr [[THIS1]], align 8 +// CHECK1-NEXT: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2), ptr [[THIS1]], align 8 // CHECK1-NEXT: [[PTR:%.*]] = getelementptr inbounds [[CLASS_A:%.*]], ptr [[THIS1]], i32 0, i32 1 // CHECK1-NEXT: store ptr null, ptr [[PTR]], align 8 // CHECK1-NEXT: ret void @@ -249,7 +249,7 @@ void foo() { // CHECK2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 4 // CHECK2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 4 // CHECK2-NEXT: call void @_ZN1AC2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR1]] -// CHECK2-NEXT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, inrange i32 0, i32 2), ptr [[THIS1]], align 4 +// CHECK2-NEXT: store ptr getelementptr inbounds inrange(-8, 4) ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 2), ptr [[THIS1]], align 4 // CHECK2-NEXT: ret void // // @@ -259,7 +259,7 @@ void foo() { // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 4 // CHECK2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 4 // CHECK2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 4 -// CHECK2-NEXT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, inrange i32 0, i32 2), ptr [[THIS1]], align 4 +// CHECK2-NEXT: store ptr getelementptr inbounds inrange(-8, 4) ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2), ptr [[THIS1]], align 4 // CHECK2-NEXT: [[PTR:%.*]] = getelementptr inbounds [[CLASS_A:%.*]], ptr [[THIS1]], i32 0, i32 1 // CHECK2-NEXT: store ptr null, ptr [[PTR]], align 4 // CHECK2-NEXT: ret void diff --git a/lld/test/ELF/lto/Inputs/devirt_validate_vtable_typeinfos_ref.ll b/lld/test/ELF/lto/Inputs/devirt_validate_vtable_typeinfos_ref.ll index 43df8366aa2a..8219b8bea157 100644 --- a/lld/test/ELF/lto/Inputs/devirt_validate_vtable_typeinfos_ref.ll +++ b/lld/test/ELF/lto/Inputs/devirt_validate_vtable_typeinfos_ref.ll @@ -36,7 +36,7 @@ entry: store ptr %this, ptr %this.addr %this1 = load ptr, ptr %this.addr call void @_ZN1AC2Ev(ptr noundef nonnull align 8 dereferenceable(8) %this1) - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, inrange i32 0, i32 2), ptr %this1 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 2), ptr %this1 ret void } @@ -47,7 +47,7 @@ entry: %this.addr = alloca ptr store ptr %this, ptr %this.addr %this1 = load ptr, ptr %this.addr - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, inrange i32 0, i32 2), ptr %this1 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2), ptr %this1 ret void } diff --git a/lld/test/ELF/lto/Inputs/devirt_validate_vtable_typeinfos_undef.ll b/lld/test/ELF/lto/Inputs/devirt_validate_vtable_typeinfos_undef.ll index 6cc55df82e2f..43230948116d 100644 --- a/lld/test/ELF/lto/Inputs/devirt_validate_vtable_typeinfos_undef.ll +++ b/lld/test/ELF/lto/Inputs/devirt_validate_vtable_typeinfos_undef.ll @@ -9,7 +9,7 @@ define linkonce_odr void @_ZN1BC2Ev(ptr %this) #0 { %this.addr = alloca ptr, align 8 store ptr %this, ptr %this.addr, align 8 %this1 = load ptr, ptr %this.addr, align 8 - store ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1B, i32 0, inrange i32 0, i32 2), ptr %this1, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [4 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 2), ptr %this1, align 8 ret void } diff --git a/lld/test/ELF/lto/devirt_split_unit_localize.ll b/lld/test/ELF/lto/devirt_split_unit_localize.ll index 04f30dcd76b4..fb3564b26886 100644 --- a/lld/test/ELF/lto/devirt_split_unit_localize.ll +++ b/lld/test/ELF/lto/devirt_split_unit_localize.ll @@ -91,7 +91,7 @@ declare dso_local void @_ZNK3Cat9makeNoiseEv(ptr nonnull dereferenceable(8)) unn define dso_local void @_Z17useDoThingWithCatv() local_unnamed_addr { entry: %call = tail call noalias nonnull dereferenceable(8) ptr @_Znwm(i64 8) - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV3Cat, i64 0, inrange i32 0, i64 2), ptr %call, align 8, !tbaa !4 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV3Cat, i64 0, i32 0, i64 2), ptr %call, align 8, !tbaa !4 tail call void @_Z14doThingWithCatP6Animal(ptr nonnull %call) ret void } diff --git a/lld/test/ELF/lto/devirt_validate_vtable_typeinfos_ref.ll b/lld/test/ELF/lto/devirt_validate_vtable_typeinfos_ref.ll index 2318af4b16ab..2d6a30da5720 100644 --- a/lld/test/ELF/lto/devirt_validate_vtable_typeinfos_ref.ll +++ b/lld/test/ELF/lto/devirt_validate_vtable_typeinfos_ref.ll @@ -117,7 +117,7 @@ entry: %this.addr = alloca ptr, align 8 store ptr %this, ptr %this.addr, align 8 %this1 = load ptr, ptr %this.addr, align 8 - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, inrange i32 0, i32 2), ptr %this1, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2), ptr %this1, align 8 ret void } diff --git a/lld/test/MachO/thinlto-split-unit-start-lib.ll b/lld/test/MachO/thinlto-split-unit-start-lib.ll index 8c643b7c594e..1c4a2f68a8b4 100644 --- a/lld/test/MachO/thinlto-split-unit-start-lib.ll +++ b/lld/test/MachO/thinlto-split-unit-start-lib.ll @@ -57,14 +57,14 @@ target triple = "x86_64-apple-macosx11.0.0" ; Function Attrs: mustprogress nofree norecurse nosync nounwind ssp willreturn memory(argmem: write) uwtable define void @_ZN1SC2Ev(ptr nocapture noundef nonnull writeonly align 8 dereferenceable(8) %this) unnamed_addr align 2 { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1S, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1S, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } ; Function Attrs: mustprogress nofree norecurse nosync nounwind ssp willreturn memory(argmem: write) uwtable define void @_ZN1SC1Ev(ptr nocapture noundef nonnull writeonly align 8 dereferenceable(8) %this) unnamed_addr align 2 { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1S, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1S, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index e07b642285b3..8bc1cab01bf0 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -11049,9 +11049,10 @@ Syntax: :: - <result> = getelementptr <ty>, ptr <ptrval>{, [inrange] <ty> <idx>}* - <result> = getelementptr inbounds <ty>, ptr <ptrval>{, [inrange] <ty> <idx>}* - <result> = getelementptr <ty>, <N x ptr> <ptrval>, [inrange] <vector index type> <idx> + <result> = getelementptr <ty>, ptr <ptrval>{, <ty> <idx>}* + <result> = getelementptr inbounds <ty>, ptr <ptrval>{, <ty> <idx>}* + <result> = getelementptr inrange(S,E) <ty>, ptr <ptrval>{, <ty> <idx>}* + <result> = getelementptr <ty>, <N x ptr> <ptrval>, <vector index type> <idx> Overview: """"""""" @@ -11196,16 +11197,15 @@ These rules are based on the assumption that no allocated object may cross the unsigned address space boundary, and no allocated object may be larger than half the pointer index type space. -If the ``inrange`` keyword is present before any index, loading from or +If the ``inrange(Start, End)`` attribute is present, loading from or storing to any pointer derived from the ``getelementptr`` has undefined -behavior if the load or store would access memory outside of the bounds of -the element selected by the index marked as ``inrange``. The result of a -pointer comparison or ``ptrtoint`` (including ``ptrtoint``-like operations +behavior if the load or store would access memory outside the half-open range +``[Start, End)`` from the ``getelementptr`` expression result. The result of +a pointer comparison or ``ptrtoint`` (including ``ptrtoint``-like operations involving memory) involving a pointer derived from a ``getelementptr`` with the ``inrange`` keyword is undefined, with the exception of comparisons -in the case where both operands are in the range of the element selected -by the ``inrange`` keyword, inclusive of the address one past the end of -that element. Note that the ``inrange`` keyword is currently only allowed +in the case where both operands are in the closed range ``[Start, End]``. +Note that the ``inrange`` keyword is currently only allowed in constant ``getelementptr`` expressions. The getelementptr instruction is often confusing. For some more insight diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h index e85728aa3c0d..8ebd0d3409c8 100644 --- a/llvm/include/llvm/AsmParser/LLParser.h +++ b/llvm/include/llvm/AsmParser/LLParser.h @@ -563,8 +563,7 @@ namespace llvm { Type *ExpectedTy = nullptr); bool parseGlobalValue(Type *Ty, Constant *&C); bool parseGlobalTypeAndValue(Constant *&V); - bool parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts, - std::optional<unsigned> *InRangeOp = nullptr); + bool parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts); bool parseOptionalComdat(StringRef GlobalName, Comdat *&C); bool parseSanitizer(GlobalVariable *GV); bool parseMetadataAsValue(Value *&V, PerFunctionState &PFS); diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 39303e648521..4018ef03f960 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -399,18 +399,19 @@ enum ConstantsCodes { CST_CODE_DATA = 22, // DATA: [n x elements] CST_CODE_INLINEASM_OLD2 = 23, // INLINEASM: [sideeffect|alignstack| // asmdialect,asmstr,conststr] - CST_CODE_CE_GEP_WITH_INRANGE_INDEX = 24, // [opty, flags, n x operands] - CST_CODE_CE_UNOP = 25, // CE_UNOP: [opcode, opval] - CST_CODE_POISON = 26, // POISON - CST_CODE_DSO_LOCAL_EQUIVALENT = 27, // DSO_LOCAL_EQUIVALENT [gvty, gv] - CST_CODE_INLINEASM_OLD3 = 28, // INLINEASM: [sideeffect|alignstack| - // asmdialect|unwind, - // asmstr,conststr] - CST_CODE_NO_CFI_VALUE = 29, // NO_CFI [ fty, f ] - CST_CODE_INLINEASM = 30, // INLINEASM: [fnty, - // sideeffect|alignstack| - // asmdialect|unwind, - // asmstr,conststr] + CST_CODE_CE_GEP_WITH_INRANGE_INDEX_OLD = 24, // [opty, flags, n x operands] + CST_CODE_CE_UNOP = 25, // CE_UNOP: [opcode, opval] + CST_CODE_POISON = 26, // POISON + CST_CODE_DSO_LOCAL_EQUIVALENT = 27, // DSO_LOCAL_EQUIVALENT [gvty, gv] + CST_CODE_INLINEASM_OLD3 = 28, // INLINEASM: [sideeffect|alignstack| + // asmdialect|unwind, + // asmstr,conststr] + CST_CODE_NO_CFI_VALUE = 29, // NO_CFI [ fty, f ] + CST_CODE_INLINEASM = 30, // INLINEASM: [fnty, + // sideeffect|alignstack| + // asmdialect|unwind, + // asmstr,conststr] + CST_CODE_CE_GEP_WITH_INRANGE = 31, // [opty, flags, range, n x operands] }; /// CastOpcodes - These are values used in the bitcode files to encode which diff --git a/llvm/include/llvm/IR/ConstantFold.h b/llvm/include/llvm/IR/ConstantFold.h index 77f5f0eb174a..9b3c8a0e5a63 100644 --- a/llvm/include/llvm/IR/ConstantFold.h +++ b/llvm/include/llvm/IR/ConstantFold.h @@ -53,7 +53,7 @@ namespace llvm { Constant *ConstantFoldCompareInstruction(CmpInst::Predicate Predicate, Constant *C1, Constant *C2); Constant *ConstantFoldGetElementPtr(Type *Ty, Constant *C, bool InBounds, - std::optional<unsigned> InRangeIndex, + std::optional<ConstantRange> InRange, ArrayRef<Value *> Idxs); } // End llvm namespace diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h index c5e1e19d6498..e50cd1f1c73e 100644 --- a/llvm/include/llvm/IR/Constants.h +++ b/llvm/include/llvm/IR/Constants.h @@ -26,6 +26,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/Constant.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/OperandTraits.h" @@ -1195,31 +1196,31 @@ public: /// Getelementptr form. Value* is only accepted for convenience; /// all elements must be Constants. /// - /// \param InRangeIndex the inrange index if present or std::nullopt. + /// \param InRange the inrange range if present or std::nullopt. /// \param OnlyIfReducedTy see \a getWithOperands() docs. static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef<Constant *> IdxList, bool InBounds = false, - std::optional<unsigned> InRangeIndex = std::nullopt, + std::optional<ConstantRange> InRange = std::nullopt, Type *OnlyIfReducedTy = nullptr) { return getGetElementPtr( Ty, C, ArrayRef((Value *const *)IdxList.data(), IdxList.size()), - InBounds, InRangeIndex, OnlyIfReducedTy); + InBounds, InRange, OnlyIfReducedTy); } static Constant * getGetElementPtr(Type *Ty, Constant *C, Constant *Idx, bool InBounds = false, - std::optional<unsigned> InRangeIndex = std::nullopt, + std::optional<ConstantRange> InRange = std::nullopt, Type *OnlyIfReducedTy = nullptr) { // This form of the function only exists to avoid ambiguous overload // warnings about whether to convert Idx to ArrayRef<Constant *> or // ArrayRef<Value *>. - return getGetElementPtr(Ty, C, cast<Value>(Idx), InBounds, InRangeIndex, + return getGetElementPtr(Ty, C, cast<Value>(Idx), InBounds, InRange, OnlyIfReducedTy); } static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef<Value *> IdxList, bool InBounds = false, - std::optional<unsigned> InRangeIndex = std::nullopt, + std::optional<ConstantRange> InRange = std::nullopt, Type *OnlyIfReducedTy = nullptr); /// Create an "inbounds" getelementptr. See the documentation for the diff --git a/llvm/include/llvm/IR/Operator.h b/llvm/include/llvm/IR/Operator.h index e52649833901..e14a916b4749 100644 --- a/llvm/include/llvm/IR/Operator.h +++ b/llvm/include/llvm/IR/Operator.h @@ -404,7 +404,6 @@ class GEPOperator enum { IsInBounds = (1 << 0), - // InRangeIndex: bits 1-6 }; void setIsInBounds(bool B) { @@ -423,11 +422,7 @@ public: /// Returns the offset of the index with an inrange attachment, or /// std::nullopt if none. - std::optional<unsigned> getInRangeIndex() const { - if (SubclassOptionalData >> 1 == 0) - return std::nullopt; - return (SubclassOptionalData >> 1) - 1; - } + std::optional<ConstantRange> getInRange() const; inline op_iterator idx_begin() { return op_begin()+1; } inline const_op_iterator idx_begin() const { return op_begin()+1; } diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 6b2e88d06b18..6139b5be85be 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -828,7 +828,7 @@ Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0, Constant *Op1, /// that they aren't implicitly casted by the getelementptr. Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops, Type *ResultTy, bool InBounds, - std::optional<unsigned> InRangeIndex, + std::optional<ConstantRange> InRange, const DataLayout &DL, const TargetLibraryInfo *TLI) { Type *IntIdxTy = DL.getIndexType(ResultTy); Type *IntIdxScalarTy = IntIdxTy->getScalarType(); @@ -856,8 +856,8 @@ Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops, if (!Any) return nullptr; - Constant *C = ConstantExpr::getGetElementPtr( - SrcElemTy, Ops[0], NewIdxs, InBounds, InRangeIndex); + Constant *C = ConstantExpr::getGetElementPtr(SrcElemTy, Ops[0], NewIdxs, + InBounds, InRange); return ConstantFoldConstant(C, DL, TLI); } @@ -866,7 +866,6 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, ArrayRef<Constant *> Ops, const DataLayout &DL, const TargetLibraryInfo *TLI) { - const GEPOperator *InnermostGEP = GEP; bool InBounds = GEP->isInBounds(); Type *SrcElemTy = GEP->getSourceElementType(); @@ -875,9 +874,8 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, if (!SrcElemTy->isSized() || isa<ScalableVectorType>(SrcElemTy)) return nullptr; - if (Constant *C = CastGEPIndices(SrcElemTy, Ops, ResTy, - GEP->isInBounds(), GEP->getInRangeIndex(), - DL, TLI)) + if (Constant *C = CastGEPIndices(SrcElemTy, Ops, ResTy, GEP->isInBounds(), + GEP->getInRange(), DL, TLI)) return C; Constant *Ptr = Ops[0]; @@ -896,9 +894,12 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, DL.getIndexedOffsetInType( SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1))); + std::optional<ConstantRange> InRange = GEP->getInRange(); + if (InRange) + InRange = InRange->sextOrTrunc(BitWidth); + // If this is a GEP of a GEP, fold it all into a single GEP. while (auto *GEP = dyn_cast<GEPOperator>(Ptr)) { - InnermostGEP = GEP; InBounds &= GEP->isInBounds(); SmallVector<Value *, 4> NestedOps(llvm::drop_begin(GEP->operands())); @@ -913,6 +914,14 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, if (!AllConstantInt) break; + // TODO: Try to intersect two inrange attributes? + if (!InRange) { + InRange = GEP->getInRange(); + if (InRange) + // Adjust inrange by offset until now. + InRange = InRange->sextOrTrunc(BitWidth).subtract(Offset); + } + Ptr = cast<Constant>(GEP->getOperand(0)); SrcElemTy = GEP->getSourceElementType(); Offset += APInt(BitWidth, DL.getIndexedOffsetInType(SrcElemTy, NestedOps)); @@ -971,21 +980,8 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, NewIdxs.push_back(ConstantInt::get( Type::getIntNTy(Ptr->getContext(), Index.getBitWidth()), Index)); - // Preserve the inrange index from the innermost GEP if possible. We must - // have calculated the same indices up to and including the inrange index. - std::optional<unsigned> InRangeIndex; - if (std::optional<unsigned> LastIRIndex = InnermostGEP->getInRangeIndex()) - if (SrcElemTy == InnermostGEP->getSourceElementType() && - NewIdxs.size() > *LastIRIndex) { - InRangeIndex = LastIRIndex; - for (unsigned I = 0; I <= *LastIRIndex; ++I) - if (NewIdxs[I] != InnermostGEP->getOperand(I + 1)) - return nullptr; - } - - // Create a GEP. return ConstantExpr::getGetElementPtr(SrcElemTy, Ptr, NewIdxs, InBounds, - InRangeIndex); + InRange); } /// Attempt to constant fold an instruction with the @@ -1033,8 +1029,7 @@ Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode, return C; return ConstantExpr::getGetElementPtr(SrcElemTy, Ops[0], Ops.slice(1), - GEP->isInBounds(), - GEP->getInRangeIndex()); + GEP->isInBounds(), GEP->getInRange()); } if (auto *CE = dyn_cast<ConstantExpr>(InstOrCE)) { diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 2c352be74931..8738cb47dd9c 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4169,11 +4169,32 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { unsigned Opc = Lex.getUIntVal(); SmallVector<Constant*, 16> Elts; bool InBounds = false; + bool HasInRange = false; + APSInt InRangeStart; + APSInt InRangeEnd; Type *Ty; Lex.Lex(); - if (Opc == Instruction::GetElementPtr) + if (Opc == Instruction::GetElementPtr) { InBounds = EatIfPresent(lltok::kw_inbounds); + if (EatIfPresent(lltok::kw_inrange)) { + if (parseToken(lltok::lparen, "expected '('")) + return true; + if (Lex.getKind() != lltok::APSInt) + return tokError("expected integer"); + InRangeStart = Lex.getAPSIntVal(); + Lex.Lex(); + if (parseToken(lltok::comma, "expected ','")) + return true; + if (Lex.getKind() != lltok::APSInt) + return tokError("expected integer"); + InRangeEnd = Lex.getAPSIntVal(); + Lex.Lex(); + if (parseToken(lltok::rparen, "expected ')'")) + return true; + HasInRange = true; + } + } if (parseToken(lltok::lparen, "expected '(' in constantexpr")) return true; @@ -4184,9 +4205,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { return true; } - std::optional<unsigned> InRangeOp; - if (parseGlobalValueVector( - Elts, Opc == Instruction::GetElementPtr ? &InRangeOp : nullptr) || + if (parseGlobalValueVector(Elts) || parseToken(lltok::rparen, "expected ')' in constantexpr")) return true; @@ -4196,6 +4215,17 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { return error(ID.Loc, "base of getelementptr must be a pointer"); Type *BaseType = Elts[0]->getType(); + std::optional<ConstantRange> InRange; + if (HasInRange) { + unsigned IndexWidth = + M->getDataLayout().getIndexTypeSizeInBits(BaseType); + InRangeStart = InRangeStart.extOrTrunc(IndexWidth); + InRangeEnd = InRangeEnd.extOrTrunc(IndexWidth); + if (InRangeStart.sge(InRangeEnd)) + return error(ID.Loc, "expected end to be larger than start"); + InRange = ConstantRange::getNonEmpty(InRangeStart, InRangeEnd); + } + unsigned GEPWidth = BaseType->isVectorTy() ? cast<FixedVectorType>(BaseType)->getNumElements() @@ -4225,15 +4255,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { if (!GetElementPtrInst::getIndexedType(Ty, Indices)) return error(ID.Loc, "invalid getelementptr indices"); - if (InRangeOp) { - if (*InRangeOp == 0) - return error(ID.Loc, - "inrange keyword may not appear on pointer operand"); - --*InRangeOp; - } - ID.ConstantVal = ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices, - InBounds, InRangeOp); + InBounds, InRange); } else if (Opc == Instruction::ShuffleVector) { if (Elts.size() != 3) return error(ID.Loc, "expected three operands to shufflevector"); @@ -4309,9 +4332,8 @@ bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) { /// parseGlobalValueVector /// ::= /*empty*/ -/// ::= [inrange] TypeAndValue (',' [inrange] TypeAndValue)* -bool LLParser::parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts, - std::optional<unsigned> *InRangeOp) { +/// ::= TypeAndValue (',' TypeAndValue)* +bool LLParser::parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) { // Empty list. if (Lex.getKind() == lltok::rbrace || Lex.getKind() == lltok::rsquare || @@ -4320,8 +4342,9 @@ bool LLParser::parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts, return false; do { - if (InRangeOp && !*InRangeOp && EatIfPresent(lltok::kw_inrange)) - *InRangeOp = Elts.size(); + // Let the caller deal with inrange. + if (Lex.getKind() == lltok::kw_inrange) + return false; Constant *C; if (parseGlobalTypeAndValue(C)) diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 826108432383..fa7038acc524 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -520,25 +520,31 @@ public: struct ExtraInfo { uint8_t Opcode; uint8_t Flags; - unsigned Extra; - Type *SrcElemTy; + unsigned BlockAddressBB = 0; + Type *SrcElemTy = nullptr; + std::optional<ConstantRange> InRange; - ExtraInfo(uint8_t Opcode, uint8_t Flags = 0, unsigned Extra = 0, - Type *SrcElemTy = nullptr) - : Opcode(Opcode), Flags(Flags), Extra(Extra), SrcElemTy(SrcElemTy) {} + ExtraInfo(uint8_t Opcode, uint8_t Flags = 0, Type *SrcElemTy = nullptr, + std::optional<ConstantRange> InRange = std::nullopt) + : Opcode(Opcode), Flags(Flags), SrcElemTy(SrcElemTy), + InRange(std::move(InRange)) {} + + ExtraInfo(uint8_t Opcode, uint8_t Flags, unsigned BlockAddressBB) + : Opcode(Opcode), Flags(Flags), BlockAddressBB(BlockAddressBB) {} }; uint8_t Opcode; uint8_t Flags; unsigned NumOperands; - unsigned Extra; // GEP inrange index or blockaddress BB id. + unsigned BlockAddressBB; Type *SrcElemTy; // GEP source element type. + std::optional<ConstantRange> InRange; // GEP inrange attribute. private: BitcodeConstant(Type *Ty, const ExtraInfo &Info, ArrayRef<unsigned> OpIDs) : Value(Ty, SubclassID), Opcode(Info.Opcode), Flags(Info.Flags), - NumOperands(OpIDs.size()), Extra(Info.Extra), - SrcElemTy(Info.SrcElemTy) { + NumOperands(OpIDs.size()), BlockAddressBB(Info.BlockAddressBB), + SrcElemTy(Info.SrcElemTy), InRange(Info.InRange) { std::uninitialized_copy(OpIDs.begin(), OpIDs.end(), getTrailingObjects<unsigned>()); } @@ -560,11 +566,9 @@ public: return ArrayRef(getTrailingObjects<unsigned>(), NumOperands); } - std::optional<unsigned> getInRangeIndex() const { + std::optional<ConstantRange> getInRange() const { assert(Opcode == Instruction::GetElementPtr); - if (Extra == (unsigned)-1) - return std::nullopt; - return Extra; + return InRange; } const char *getOpcodeName() const { @@ -1559,7 +1563,7 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, // If the function is already parsed we can insert the block address // right away. BasicBlock *BB; - unsigned BBID = BC->Extra; + unsigned BBID = BC->BlockAddressBB; if (!BBID) // Invalid reference to entry block. return error("Invalid ID"); @@ -1602,7 +1606,7 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, case Instruction::GetElementPtr: C = ConstantExpr::getGetElementPtr(BC->SrcElemTy, ConstOps[0], ArrayRef(ConstOps).drop_front(), - BC->Flags, BC->getInRangeIndex()); + BC->Flags, BC->getInRange()); break; case Instruction::ExtractElement: C = ConstantExpr::getExtractElement(ConstOps[0], ConstOps[1]); @@ -3308,22 +3312,34 @@ Error BitcodeReader::parseConstants() { } case bitc::CST_CODE_CE_INBOUNDS_GEP: // [ty, n x operands] case bitc::CST_CODE_CE_GEP: // [ty, n x operands] - case bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX: { // [ty, flags, n x - // operands] + case bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX_OLD: // [ty, flags, n x + // operands] + case bitc::CST_CODE_CE_GEP_WITH_INRANGE: { // [ty, flags, start, end, n x + // operands] if (Record.size() < 2) return error("Constant GEP record must have at least two elements"); unsigned OpNum = 0; Type *PointeeType = nullptr; - if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX || - Record.size() % 2) + if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX_OLD || + BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE || Record.size() % 2) PointeeType = getTypeByID(Record[OpNum++]); bool InBounds = false; - std::optional<unsigned> InRangeIndex; - if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX) { + std::optional<ConstantRange> InRange; + if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX_OLD) { + uint64_t Op = Record[OpNum++]; + InBounds = Op & 1; + unsigned InRangeIndex = Op >> 1; + // "Upgrade" inrange by dropping it. The feature is too niche to + // bother. + (void)InRangeIndex; + } else if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE) { uint64_t Op = Record[OpNum++]; InBounds = Op & 1; - InRangeIndex = Op >> 1; + Expected<ConstantRange> MaybeInRange = readConstantRange(Record, OpNum); + if (!MaybeInRange) + return MaybeInRange.takeError(); + InRange = MaybeInRange.get(); } else if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP) InBounds = true; @@ -3356,10 +3372,9 @@ Error BitcodeReader::parseConstants() { return error("Missing element type for old-style constant GEP"); } - V = BitcodeConstant::create(Alloc, CurTy, - {Instruction::GetElementPtr, InBounds, - InRangeIndex.value_or(-1), PointeeType}, - Elts); + V = BitcodeConstant::create( + Alloc, CurTy, + {Instruction::GetElementPtr, InBounds, PointeeType, InRange}, Elts); break; } case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index fd211f74f07c..a1ee02918dfa 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -2751,9 +2751,10 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, Code = bitc::CST_CODE_CE_GEP; const auto *GO = cast<GEPOperator>(C); Record.push_back(VE.getTypeID(GO->getSourceElementType())); - if (std::optional<unsigned> Idx = GO->getInRangeIndex()) { - Code = bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX; - Record.push_back((*Idx << 1) | GO->isInBounds()); + if (std::optional<ConstantRange> Range = GO->getInRange()) { + Code = bitc::CST_CODE_CE_GEP_WITH_INRANGE; + Record.push_back(GO->isInBounds()); + emitConstantRange(Record, *Range); } else if (GO->isInBounds()) Code = bitc::CST_CODE_CE_INBOUNDS_GEP; for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) { diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index d7fee609a2ba..5caed518e265 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1414,6 +1414,10 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) { if (GEP->isInBounds()) Out << " inbounds"; + if (auto InRange = GEP->getInRange()) { + Out << " inrange(" << InRange->getLower() << ", " << InRange->getUpper() + << ")"; + } } else if (const auto *NNI = dyn_cast<PossiblyNonNegInst>(U)) { if (NNI->hasNonNeg()) Out << " nneg"; @@ -1691,18 +1695,13 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, Out << ' ' << static_cast<CmpInst::Predicate>(CE->getPredicate()); Out << " ("; - std::optional<unsigned> InRangeOp; if (const GEPOperator *GEP = dyn_cast<GEPOperator>(CE)) { WriterCtx.TypePrinter->print(GEP->getSourceElementType(), Out); Out << ", "; - InRangeOp = GEP->getInRangeIndex(); - if (InRangeOp) - ++*InRangeOp; } - for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) { - if (InRangeOp && unsigned(OI - CE->op_begin()) == *InRangeOp) - Out << "inrange "; + for (User::const_op_iterator OI = CE->op_begin(); OI != CE->op_end(); + ++OI) { WriterCtx.TypePrinter->print((*OI)->getType(), Out); Out << ' '; WriteAsOperandInternal(Out, *OI, WriterCtx); diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index e22785174e23..a766b1fe6018 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -1468,6 +1468,10 @@ static Constant *foldGEPOfGEP(GEPOperator *GEP, Type *PointeeTy, bool InBounds, if (PointeeTy != GEP->getResultElementType()) return nullptr; + // Leave inrange handling to DL-aware constant folding. + if (GEP->getInRange()) + return nullptr; + Constant *Idx0 = cast<Constant>(Idxs[0]); if (Idx0->isNullValue()) { // Handle the simple case of a zero index. @@ -1477,7 +1481,7 @@ static Constant *foldGEPOfGEP(GEPOperator *GEP, Type *PointeeTy, bool InBounds, NewIndices.append(Idxs.begin() + 1, Idxs.end()); return ConstantExpr::getGetElementPtr( GEP->getSourceElementType(), cast<Constant>(GEP->getPointerOperand()), - NewIndices, InBounds && GEP->isInBounds(), GEP->getInRangeIndex()); + NewIndices, InBounds && GEP->isInBounds()); } gep_type_iterator LastI = gep_type_end(GEP); @@ -1526,21 +1530,14 @@ static Constant *foldGEPOfGEP(GEPOperator *GEP, Type *PointeeTy, bool InBounds, NewIndices.push_back(ConstantExpr::get(Instruction::Add, Idx0, LastIdx)); NewIndices.append(Idxs.begin() + 1, Idxs.end()); - // The combined GEP normally inherits its index inrange attribute from - // the inner GEP, but if the inner GEP's last index was adjusted by the - // outer GEP, any inbounds attribute on that index is invalidated. - std::optional<unsigned> IRIndex = GEP->getInRangeIndex(); - if (IRIndex && *IRIndex == GEP->getNumIndices() - 1) - IRIndex = std::nullopt; - return ConstantExpr::getGetElementPtr( GEP->getSourceElementType(), cast<Constant>(GEP->getPointerOperand()), - NewIndices, InBounds && GEP->isInBounds(), IRIndex); + NewIndices, InBounds && GEP->isInBounds()); } Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, bool InBounds, - std::optional<unsigned> InRangeIndex, + std::optional<ConstantRange> InRange, ArrayRef<Value *> Idxs) { if (Idxs.empty()) return C; @@ -1556,7 +1553,7 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, auto IsNoOp = [&]() { // Avoid losing inrange information. - if (InRangeIndex) + if (InRange) return false; return all_of(Idxs, [](Value *Idx) { @@ -1594,12 +1591,6 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, if (!isa<ConstantInt>(Idxs[i - 1]) && !isa<ConstantDataVector>(Idxs[i - 1])) // Skip if the type of the previous index is not supported. continue; - if (InRangeIndex && i == *InRangeIndex + 1) { - // If an index is marked inrange, we cannot apply this canonicalization to - // the following index, as that will cause the inrange index to point to - // the wrong element. - continue; - } if (isa<StructType>(Ty)) { // The verify makes sure that GEPs into a struct are in range. continue; @@ -1621,16 +1612,16 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, } } else { auto *CV = cast<ConstantDataVector>(Idxs[i]); - bool InRange = true; + bool IsInRange = true; for (unsigned I = 0, E = CV->getNumElements(); I != E; ++I) { auto *CI = cast<ConstantInt>(CV->getElementAsConstant(I)); - InRange &= isIndexInRangeOfArrayType(STy->getNumElements(), CI); + IsInRange &= isIndexInRangeOfArrayType(STy->getNumElements(), CI); if (CI->isNegative()) { Unknown = true; break; } } - if (InRange || Unknown) + if (IsInRange || Unknown) // It's in range, skip to the next index. // It's out of range and negative, don't try to factor it. continue; @@ -1720,7 +1711,7 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, for (unsigned i = 0, e = Idxs.size(); i != e; ++i) if (!NewIdxs[i]) NewIdxs[i] = cast<Constant>(Idxs[i]); return ConstantExpr::getGetElementPtr(PointeeTy, C, NewIdxs, InBounds, - InRangeIndex); + InRange); } // If all indices are known integers and normalized, we can do a simple @@ -1730,7 +1721,7 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, if (!GV->hasExternalWeakLinkage() && GV->getValueType() == PointeeTy && isInBoundsIndices(Idxs)) return ConstantExpr::getGetElementPtr(PointeeTy, C, Idxs, - /*InBounds=*/true, InRangeIndex); + /*InBounds=*/true, InRange); return nullptr; } diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 07b5bced96da..c17419b529ac 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -1568,7 +1568,7 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty, assert(SrcTy || (Ops[0]->getType() == getOperand(0)->getType())); return ConstantExpr::getGetElementPtr( SrcTy ? SrcTy : GEPO->getSourceElementType(), Ops[0], Ops.slice(1), - GEPO->isInBounds(), GEPO->getInRangeIndex(), OnlyIfReducedTy); + GEPO->isInBounds(), GEPO->getInRange(), OnlyIfReducedTy); } case Instruction::ICmp: case Instruction::FCmp: @@ -2349,17 +2349,16 @@ Constant *ConstantExpr::getCompare(unsigned short Predicate, Constant *C1, Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C, ArrayRef<Value *> Idxs, bool InBounds, - std::optional<unsigned> InRangeIndex, + std::optional<ConstantRange> InRange, Type *OnlyIfReducedTy) { assert(Ty && "Must specify element type"); assert(isSupportedGetElementPtr(Ty) && "Element type is unsupported!"); - if (Constant *FC = - ConstantFoldGetElementPtr(Ty, C, InBounds, InRangeIndex, Idxs)) - return FC; // Fold a few common cases. + if (Constant *FC = ConstantFoldGetElementPtr(Ty, C, InBounds, InRange, Idxs)) + return FC; // Fold a few common cases. - assert(GetElementPtrInst::getIndexedType(Ty, Idxs) && - "GEP indices invalid!");; + assert(GetElementPtrInst::getIndexedType(Ty, Idxs) && "GEP indices invalid!"); + ; // Get the result type of the getelementptr! Type *ReqTy = GetElementPtrInst::getGEPReturnType(C, Idxs); @@ -2392,10 +2391,9 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C, } unsigned SubClassOptionalData = InBounds ? GEPOperator::IsInBounds : 0; - if (InRangeIndex && *InRangeIndex < 63) - SubClassOptionalData |= (*InRangeIndex + 1) << 1; const ConstantExprKeyType Key(Instruction::GetElementPtr, ArgVec, 0, - SubClassOptionalData, std::nullopt, Ty); + SubClassOptionalData, std::nullopt, Ty, + InRange); LLVMContextImpl *pImpl = C->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ReqTy, Key); @@ -2691,13 +2689,15 @@ const char *ConstantExpr::getOpcodeName() const { } GetElementPtrConstantExpr::GetElementPtrConstantExpr( - Type *SrcElementTy, Constant *C, ArrayRef<Constant *> IdxList, Type *DestTy) + Type *SrcElementTy, Constant *C, ArrayRef<Constant *> IdxList, Type *DestTy, + std::optional<ConstantRange> InRange) : ConstantExpr(DestTy, Instruction::GetElementPtr, OperandTraits<GetElementPtrConstantExpr>::op_end(this) - (IdxList.size() + 1), IdxList.size() + 1), SrcElementTy(SrcElementTy), - ResElementTy(GetElementPtrInst::getIndexedType(SrcElementTy, IdxList)) { + ResElementTy(GetElementPtrInst::getIndexedType(SrcElementTy, IdxList)), + InRange(std::move(InRange)) { Op<0>() = C; Use *OperandList = getOperandList(); for (unsigned i = 0, E = IdxList.size(); i != E; ++i) @@ -2712,6 +2712,10 @@ Type *GetElementPtrConstantExpr::getResultElementType() const { return ResElementTy; } +std::optional<ConstantRange> GetElementPtrConstantExpr::getInRange() const { + return InRange; +} + //===----------------------------------------------------------------------===// // ConstantData* implementations diff --git a/llvm/lib/IR/ConstantsContext.h b/llvm/lib/IR/ConstantsContext.h index 44a926b5dc58..7067d0d12111 100644 --- a/llvm/lib/IR/ConstantsContext.h +++ b/llvm/lib/IR/ConstantsContext.h @@ -183,25 +183,29 @@ public: /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is /// used behind the scenes to implement getelementptr constant exprs. -class GetElementPtrConstantExpr final : public ConstantExpr { +class GetElementPtrConstantExpr : public ConstantExpr { Type *SrcElementTy; Type *ResElementTy; + std::optional<ConstantRange> InRange; GetElementPtrConstantExpr(Type *SrcElementTy, Constant *C, - ArrayRef<Constant *> IdxList, Type *DestTy); + ArrayRef<Constant *> IdxList, Type *DestTy, + std::optional<ConstantRange> InRange); public: - static GetElementPtrConstantExpr *Create(Type *SrcElementTy, Constant *C, - ArrayRef<Constant *> IdxList, - Type *DestTy, unsigned Flags) { + static GetElementPtrConstantExpr * + Create(Type *SrcElementTy, Constant *C, ArrayRef<Constant *> IdxList, + Type *DestTy, unsigned Flags, std::optional<ConstantRange> InRange) { GetElementPtrConstantExpr *Result = new (IdxList.size() + 1) - GetElementPtrConstantExpr(SrcElementTy, C, IdxList, DestTy); + GetElementPtrConstantExpr(SrcElementTy, C, IdxList, DestTy, + std::move(InRange)); Result->SubclassOptionalData = Flags; return Result; } Type *getSourceElementType() const; Type *getResultElementType() const; + std::optional<ConstantRange> getInRange() const; /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -405,6 +409,7 @@ private: ArrayRef<Constant *> Ops; ArrayRef<int> ShuffleMask; Type *ExplicitTy; + std::optional<ConstantRange> InRange; static ArrayRef<int> getShuffleMaskIfValid(const ConstantExpr *CE) { if (CE->getOpcode() == Instruction::ShuffleVector) @@ -418,22 +423,31 @@ private: return nullptr; } + static std::optional<ConstantRange> + getInRangeIfValid(const ConstantExpr *CE) { + if (auto *GEPCE = dyn_cast<GetElementPtrConstantExpr>(CE)) + return GEPCE->getInRange(); + return std::nullopt; + } + public: ConstantExprKeyType(unsigned Opcode, ArrayRef<Constant *> Ops, unsigned short SubclassData = 0, unsigned short SubclassOptionalData = 0, ArrayRef<int> ShuffleMask = std::nullopt, - Type *ExplicitTy = nullptr) + Type *ExplicitTy = nullptr, + std::optional<ConstantRange> InRange = std::nullopt) : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData), SubclassData(SubclassData), Ops(Ops), ShuffleMask(ShuffleMask), - ExplicitTy(ExplicitTy) {} + ExplicitTy(ExplicitTy), InRange(std::move(InRange)) {} ConstantExprKeyType(ArrayRef<Constant *> Operands, const ConstantExpr *CE) : Opcode(CE->getOpcode()), SubclassOptionalData(CE->getRawSubclassOptionalData()), SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands), ShuffleMask(getShuffleMaskIfValid(CE)), - ExplicitTy(getSourceElementTypeIfValid(CE)) {} + ExplicitTy(getSourceElementTypeIfValid(CE)), + InRange(getInRangeIfValid(CE)) {} ConstantExprKeyType(const ConstantExpr *CE, SmallVectorImpl<Constant *> &Storage) @@ -441,17 +455,26 @@ public: SubclassOptionalData(CE->getRawSubclassOptionalData()), SubclassData(CE->isCompare() ? CE->getPredicate() : 0), ShuffleMask(getShuffleMaskIfValid(CE)), - ExplicitTy(getSourceElementTypeIfValid(CE)) { + ExplicitTy(getSourceElementTypeIfValid(CE)), + InRange(getInRangeIfValid(CE)) { assert(Storage.empty() && "Expected empty storage"); for (unsigned I = 0, E = CE->getNumOperands(); I != E; ++I) Storage.push_back(CE->getOperand(I)); Ops = Storage; } + static bool rangesEqual(const std::optional<ConstantRange> &A, + const std::optional<ConstantRange> &B) { + if (!A.has_value() || !B.has_value()) + return A.has_value() == B.has_value(); + return A->getBitWidth() == B->getBitWidth() && A == B; + } + bool operator==(const ConstantExprKeyType &X) const { return Opcode == X.Opcode && SubclassData == X.SubclassData && SubclassOptionalData == X.SubclassOptionalData && Ops == X.Ops && - ShuffleMask == X.ShuffleMask && ExplicitTy == X.ExplicitTy; + ShuffleMask == X.ShuffleMask && ExplicitTy == X.ExplicitTy && + rangesEqual(InRange, X.InRange); } bool operator==(const ConstantExpr *CE) const { @@ -470,6 +493,8 @@ public: return false; if (ExplicitTy != getSourceElementTypeIfValid(CE)) return false; + if (!rangesEqual(InRange, getInRangeIfValid(CE))) + return false; return true; } @@ -499,8 +524,8 @@ public: case Instruction::ShuffleVector: return new ShuffleVectorConstantExpr(Ops[0], Ops[1], ShuffleMask); case Instruction::GetElementPtr: - return GetElementPtrConstantExpr::Create(ExplicitTy, Ops[0], Ops.slice(1), - Ty, SubclassOptionalData); + return GetElementPtrConstantExpr::Create( + ExplicitTy, Ops[0], Ops.slice(1), Ty, SubclassOptionalData, InRange); case Instruction::ICmp: return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData, Ops[0], Ops[1]); diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp index caf8fe654a36..b9cd219d94dc 100644 --- a/llvm/lib/IR/Operator.cpp +++ b/llvm/lib/IR/Operator.cpp @@ -37,7 +37,7 @@ bool Operator::hasPoisonGeneratingFlags() const { case Instruction::GetElementPtr: { auto *GEP = cast<GEPOperator>(this); // Note: inrange exists on constexpr only - return GEP->isInBounds() || GEP->getInRangeIndex() != std::nullopt; + return GEP->isInBounds() || GEP->getInRange() != std::nullopt; } case Instruction::ZExt: if (auto *NNI = dyn_cast<PossiblyNonNegInst>(this)) @@ -69,6 +69,12 @@ Type *GEPOperator::getResultElementType() const { return cast<GetElementPtrConstantExpr>(this)->getResultElementType(); } +std::optional<ConstantRange> GEPOperator::getInRange() const { + if (auto *CE = dyn_cast<GetElementPtrConstantExpr>(this)) + return CE->getInRange(); + return std::nullopt; +} + Align GEPOperator::getMaxPreservedAlignment(const DataLayout &DL) const { /// compute the worse possible offset for every level of the GEP et accumulate /// the minimum alignment into Result. diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp index 2cfd1de93a04..9083150b3384 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp @@ -801,7 +801,7 @@ Value *FatPtrConstMaterializer::materialize(Value *V) { Ops.push_back(cast<Constant>(U.get())); auto *NewGEP = ConstantExpr::getGetElementPtr( NewSrcTy, Ops[0], ArrayRef<Constant *>(Ops).slice(1), - GEPO->isInBounds(), GEPO->getInRangeIndex()); + GEPO->isInBounds(), GEPO->getInRange()); LLVM_DEBUG(dbgs() << "p7-getting GEP: " << *GEPO << " becomes " << *NewGEP << "\n"); Value *FurtherMap = materialize(NewGEP); diff --git a/llvm/lib/Transforms/IPO/GlobalSplit.cpp b/llvm/lib/Transforms/IPO/GlobalSplit.cpp index 84e9c219f935..dced3a5fdc78 100644 --- a/llvm/lib/Transforms/IPO/GlobalSplit.cpp +++ b/llvm/lib/Transforms/IPO/GlobalSplit.cpp @@ -47,28 +47,66 @@ static bool splitGlobal(GlobalVariable &GV) { if (!Init) return false; - // Verify that each user of the global is an inrange getelementptr constant. - // From this it follows that any loads from or stores to that global must use - // a pointer derived from an inrange getelementptr constant, which is - // sufficient to allow us to apply the splitting transform. + const DataLayout &DL = GV.getParent()->getDataLayout(); + const StructLayout *SL = DL.getStructLayout(Init->getType()); + ArrayRef<TypeSize> MemberOffsets = SL->getMemberOffsets(); + unsigned IndexWidth = DL.getIndexTypeSizeInBits(GV.getType()); + + // Verify that each user of the global is an inrange getelementptr constant, + // and collect information on how it relates to the global. + struct GEPInfo { + GEPOperator *GEP; + unsigned MemberIndex; + APInt MemberRelativeOffset; + + GEPInfo(GEPOperator *GEP, unsigned MemberIndex, APInt MemberRelativeOffset) + : GEP(GEP), MemberIndex(MemberIndex), + MemberRelativeOffset(std::move(MemberRelativeOffset)) {} + }; + SmallVector<GEPInfo> Infos; for (User *U : GV.users()) { - if (!isa<Constant>(U)) + auto *GEP = dyn_cast<GEPOperator>(U); + if (!GEP) return false; - auto *GEP = dyn_cast<GEPOperator>(U); - if (!GEP || !GEP->getInRangeIndex() || *GEP->getInRangeIndex() != 1 || - !isa<ConstantInt>(GEP->getOperand(1)) || - !cast<ConstantInt>(GEP->getOperand(1))->isZero() || - !isa<ConstantInt>(GEP->getOperand(2))) + std::optional<ConstantRange> InRange = GEP->getInRange(); + if (!InRange) + return false; + + APInt Offset(IndexWidth, 0); + if (!GEP->accumulateConstantOffset(DL, Offset)) + return false; + + // Determine source-relative inrange. + ConstantRange SrcInRange = InRange->sextOrTrunc(IndexWidth).add(Offset); + + // Check that the GEP offset is in the range (treating upper bound as + // inclusive here). + if (!SrcInRange.contains(Offset) && SrcInRange.getUpper() != Offset) + return false; + + // Find which struct member the range corresponds to. + if (SrcInRange.getLower().uge(SL->getSizeInBytes())) return false; + + unsigned MemberIndex = + SL->getElementContainingOffset(SrcInRange.getLower().getZExtValue()); + TypeSize MemberStart = MemberOffsets[MemberIndex]; + TypeSize MemberEnd = MemberIndex == MemberOffsets.size() - 1 + ? SL->getSizeInBytes() + : MemberOffsets[MemberIndex + 1]; + + // Verify that the range matches that struct member. + if (SrcInRange.getLower() != MemberStart || + SrcInRange.getUpper() != MemberEnd) + return false; + + Infos.emplace_back(GEP, MemberIndex, Offset - MemberStart); } SmallVector<MDNode *, 2> Types; GV.getMetadata(LLVMContext::MD_type, Types); - const DataLayout &DL = GV.getParent()->getDataLayout(); - const StructLayout *SL = DL.getStructLayout(Init->getType()); - IntegerType *Int32Ty = Type::getInt32Ty(GV.getContext()); std::vector<GlobalVariable *> SplitGlobals(Init->getNumOperands()); @@ -114,21 +152,13 @@ static bool splitGlobal(GlobalVariable &GV) { SplitGV->setVCallVisibilityMetadata(GV.getVCallVisibility()); } - for (User *U : GV.users()) { - auto *GEP = cast<GEPOperator>(U); - unsigned I = cast<ConstantInt>(GEP->getOperand(2))->getZExtValue(); - if (I >= SplitGlobals.size()) - continue; - - SmallVector<Value *, 4> Ops; - Ops.push_back(ConstantInt::get(Int32Ty, 0)); - for (unsigned I = 3; I != GEP->getNumOperands(); ++I) - Ops.push_back(GEP->getOperand(I)); - + for (const GEPInfo &Info : Infos) { + assert(Info.MemberIndex < SplitGlobals.size() && "Invalid member"); auto *NewGEP = ConstantExpr::getGetElementPtr( - SplitGlobals[I]->getInitializer()->getType(), SplitGlobals[I], Ops, - GEP->isInBounds()); - GEP->replaceAllUsesWith(NewGEP); + Type::getInt8Ty(GV.getContext()), SplitGlobals[Info.MemberIndex], + ConstantInt::get(GV.getContext(), Info.MemberRelativeOffset), + Info.GEP->isInBounds()); + Info.GEP->replaceAllUsesWith(NewGEP); } // Finally, remove the original global. Any remaining uses refer to invalid diff --git a/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/llvm/lib/Transforms/Utils/FunctionComparator.cpp index 09e19be0d293..8cfb8ed07d24 100644 --- a/llvm/lib/Transforms/Utils/FunctionComparator.cpp +++ b/llvm/lib/Transforms/Utils/FunctionComparator.cpp @@ -426,9 +426,19 @@ int FunctionComparator::cmpConstants(const Constant *L, return Res; if (int Res = cmpNumbers(GEPL->isInBounds(), GEPR->isInBounds())) return Res; - if (int Res = cmpNumbers(GEPL->getInRangeIndex().value_or(unsigned(-1)), - GEPR->getInRangeIndex().value_or(unsigned(-1)))) - return Res; + + std::optional<ConstantRange> InRangeL = GEPL->getInRange(); + std::optional<ConstantRange> InRangeR = GEPR->getInRange(); + if (InRangeL) { + if (!InRangeR) + return 1; + if (int Res = cmpAPInts(InRangeL->getLower(), InRangeR->getLower())) + return Res; + if (int Res = cmpAPInts(InRangeL->getUpper(), InRangeR->getUpper())) + return Res; + } else if (InRangeR) { + return -1; + } } if (auto *OBOL = dyn_cast<OverflowingBinaryOperator>(LE)) { auto *OBOR = cast<OverflowingBinaryOperator>(RE); diff --git a/llvm/test/Assembler/getelementptr.ll b/llvm/test/Assembler/getelementptr.ll index 50695a65abb3..45c6a2d00cc3 100644 --- a/llvm/test/Assembler/getelementptr.ll +++ b/llvm/test/Assembler/getelementptr.ll @@ -23,24 +23,26 @@ @PR23753_b = global ptr getelementptr (i8, ptr @PR23753_a, i64 ptrtoint (ptr @PR23753_a to i64)) ; CHECK: @PR23753_b = global ptr getelementptr (i8, ptr @PR23753_a, i64 ptrtoint (ptr @PR23753_a to i64)) -; Verify that inrange on an index inhibits over-indexed getelementptr folding. +; Verify that inrange doesn't inhibit over-indexed getelementptr folding, +; but does inhibit combining two GEPs where the inner one has inrange (this +; will be done when DataLayout is available instead). @nestedarray = global [2 x [4 x ptr]] zeroinitializer -; CHECK: @nestedarray.1 = alias ptr, getelementptr inbounds ([2 x [4 x ptr]], ptr @nestedarray, inrange i32 0, i64 1, i32 0) -@nestedarray.1 = alias ptr, getelementptr inbounds ([2 x [4 x ptr]], ptr @nestedarray, inrange i32 0, i32 0, i32 4) +; CHECK: @nestedarray.1 = alias ptr, getelementptr inbounds inrange(-32, 32) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i64 1, i32 0) +@nestedarray.1 = alias ptr, getelementptr inbounds inrange(-32, 32) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 0, i32 4) -; CHECK: @nestedarray.2 = alias ptr, getelementptr inbounds ([2 x [4 x ptr]], ptr @nestedarray, i32 0, inrange i32 0, i32 4) -@nestedarray.2 = alias ptr, getelementptr inbounds ([2 x [4 x ptr]], ptr @nestedarray, i32 0, inrange i32 0, i32 4) +; CHECK: @nestedarray.2 = alias ptr, getelementptr inbounds inrange(0, 1) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i64 1, i32 0) +@nestedarray.2 = alias ptr, getelementptr inbounds inrange(0, 1) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 0, i32 4) -; CHECK: @nestedarray.3 = alias ptr, getelementptr inbounds ([2 x [4 x ptr]], ptr @nestedarray, i32 0, inrange i32 0) -@nestedarray.3 = alias ptr, getelementptr inbounds ([4 x ptr], ptr getelementptr inbounds ([2 x [4 x ptr]], ptr @nestedarray, i32 0, inrange i32 0), i32 0, i32 0) +; CHECK: @nestedarray.3 = alias ptr, getelementptr inbounds inrange(0, 4) ([4 x ptr], ptr @nestedarray, i32 0, i32 0) +@nestedarray.3 = alias ptr, getelementptr inbounds inrange(0, 4) ([4 x ptr], ptr getelementptr inbounds ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 0), i32 0, i32 0) -; CHECK: @nestedarray.4 = alias ptr, getelementptr inbounds ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 1, i32 0) -@nestedarray.4 = alias ptr, getelementptr inbounds ([4 x ptr], ptr getelementptr inbounds ([2 x [4 x ptr]], ptr @nestedarray, i32 0, inrange i32 0), i32 1, i32 0) +; CHECK: @nestedarray.4 = alias ptr, getelementptr inbounds ([4 x ptr], ptr getelementptr inbounds inrange(0, 4) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 0), i32 1, i32 0) +@nestedarray.4 = alias ptr, getelementptr inbounds ([4 x ptr], ptr getelementptr inbounds inrange(0, 4) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 0), i32 1, i32 0) -; CHECK: @nestedarray.5 = alias ptr, getelementptr inbounds ([2 x [4 x ptr]], ptr @nestedarray, inrange i32 0, i32 1, i32 0) -@nestedarray.5 = alias ptr, getelementptr inbounds ([4 x ptr], ptr getelementptr inbounds ([2 x [4 x ptr]], ptr @nestedarray, inrange i32 0, i32 0), i32 1, i32 0) +; CHECK: @nestedarray.5 = alias ptr, getelementptr inbounds ([4 x ptr], ptr getelementptr inbounds inrange(0, 32) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 0), i32 1, i32 0) +@nestedarray.5 = alias ptr, getelementptr inbounds ([4 x ptr], ptr getelementptr inbounds inrange(0, 32) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 0), i32 1, i32 0) ; See if i92 indices work too. define ptr @test(ptr %t, i92 %n) { diff --git a/llvm/test/Assembler/inrange-errors.ll b/llvm/test/Assembler/inrange-errors.ll new file mode 100644 index 000000000000..128c21983ca6 --- /dev/null +++ b/llvm/test/Assembler/inrange-errors.ll @@ -0,0 +1,46 @@ +; RUN: split-file %s %t +; RUN: not llvm-as < %t/parse-error-1.ll -o /dev/null 2>&1 | FileCheck --check-prefix=PARSE-ERROR-1 %s +; RUN: not llvm-as < %t/parse-error-2.ll -o /dev/null 2>&1 | FileCheck --check-prefix=PARSE-ERROR-2 %s +; RUN: not llvm-as < %t/parse-error-3.ll -o /dev/null 2>&1 | FileCheck --check-prefix=PARSE-ERROR-3 %s +; RUN: not llvm-as < %t/parse-error-4.ll -o /dev/null 2>&1 | FileCheck --check-prefix=PARSE-ERROR-4 %s +; RUN: not llvm-as < %t/end-not-larger-start.ll -o /dev/null 2>&1 | FileCheck --check-prefix=END-NOT-LARGER-START %s + +;--- parse-error-1.ll + +; PARSE-ERROR-1: error: expected integer +@g = external global i8 +define ptr @test() { + ret ptr getelementptr inrange (i8, ptr @g, i64 8) +} + +;--- parse-error-2.ll + +; PARSE-ERROR-2: error: expected ',' +@g = external global i8 +define ptr @test() { + ret ptr getelementptr inrange(42 (i8, ptr @g, i64 8) +} + +;--- parse-error-3.ll + +; PARSE-ERROR-3: error: expected integer +@g = external global i8 +define ptr @test() { + ret ptr getelementptr inrange(42, (i8, ptr @g, i64 8) +} + +;--- parse-error-4.ll + +; PARSE-ERROR-4: error: expected ')' +@g = external global i8 +define ptr @test() { + ret ptr getelementptr inrange(42, 123 (i8, ptr @g, i64 8) +} + +;--- end-not-larger-start.ll + +; END-NOT-LARGER-START: error: expected end to be larger than start +@g = external global i8 +define ptr @test() { + ret ptr getelementptr inrange(42, 42) (i8, ptr @g, i64 8) +} diff --git a/llvm/test/Bitcode/compatibility-4.0.ll b/llvm/test/Bitcode/compatibility-4.0.ll index da5ea0e19639..06cb842059a4 100644 --- a/llvm/test/Bitcode/compatibility-4.0.ll +++ b/llvm/test/Bitcode/compatibility-4.0.ll @@ -1609,7 +1609,7 @@ declare void @f.writeonly() writeonly ;; Constant Expressions define i8** @constexpr() { - ; CHECK: ret ptr getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr null, i32 0, inrange i32 1, i32 2) + ; CHECK: ret ptr getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr null, i32 0, i32 1, i32 2) ret i8** getelementptr inbounds ({ [4 x i8*], [4 x i8*] }, { [4 x i8*], [4 x i8*] }* null, i32 0, inrange i32 1, i32 2) } diff --git a/llvm/test/Bitcode/compatibility-5.0.ll b/llvm/test/Bitcode/compatibility-5.0.ll index 7a39ae6256b8..f9ae558917cd 100644 --- a/llvm/test/Bitcode/compatibility-5.0.ll +++ b/llvm/test/Bitcode/compatibility-5.0.ll @@ -1624,7 +1624,7 @@ declare void @f.speculatable() speculatable ;; Constant Expressions define i8** @constexpr() { - ; CHECK: ret ptr getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr null, i32 0, inrange i32 1, i32 2) + ; CHECK: ret ptr getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr null, i32 0, i32 1, i32 2) ret i8** getelementptr inbounds ({ [4 x i8*], [4 x i8*] }, { [4 x i8*], [4 x i8*] }* null, i32 0, inrange i32 1, i32 2) } diff --git a/llvm/test/Bitcode/compatibility-6.0.ll b/llvm/test/Bitcode/compatibility-6.0.ll index 4cb1f3bd123c..1458e1b639ad 100644 --- a/llvm/test/Bitcode/compatibility-6.0.ll +++ b/llvm/test/Bitcode/compatibility-6.0.ll @@ -1634,7 +1634,7 @@ declare void @f.speculatable() speculatable ;; Constant Expressions define i8** @constexpr() { - ; CHECK: ret ptr getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr null, i32 0, inrange i32 1, i32 2) + ; CHECK: ret ptr getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr null, i32 0, i32 1, i32 2) ret i8** getelementptr inbounds ({ [4 x i8*], [4 x i8*] }, { [4 x i8*], [4 x i8*] }* null, i32 0, inrange i32 1, i32 2) } diff --git a/llvm/test/Bitcode/compatibility.ll b/llvm/test/Bitcode/compatibility.ll index ce6a6571ec14..fa8b0520567a 100644 --- a/llvm/test/Bitcode/compatibility.ll +++ b/llvm/test/Bitcode/compatibility.ll @@ -1941,8 +1941,8 @@ declare void @f.speculatable() speculatable ;; Constant Expressions define ptr @constexpr() { - ; CHECK: ret ptr getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr null, i32 0, inrange i32 1, i32 2) - ret ptr getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr null, i32 0, inrange i32 1, i32 2) + ; CHECK: ret ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [4 x ptr] }, ptr null, i32 0, i32 1, i32 2) + ret ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [4 x ptr] }, ptr null, i32 0, i32 1, i32 2) } define void @instructions.strictfp() strictfp { diff --git a/llvm/test/Other/optimize-inrange-gep.ll b/llvm/test/Other/optimize-inrange-gep.ll index cc2bd15b5b22..2eae34bdb09b 100644 --- a/llvm/test/Other/optimize-inrange-gep.ll +++ b/llvm/test/Other/optimize-inrange-gep.ll @@ -1,4 +1,5 @@ -; RUN: opt -O0 -S < %s | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 +; RUN: opt -O0 -S < %s | FileCheck %s --check-prefix=O0 ; RUN: opt -O1 -S < %s | FileCheck %s ; RUN: opt -O2 -S < %s | FileCheck %s ; RUN: opt -O3 -S < %s | FileCheck %s @@ -7,12 +8,21 @@ target datalayout = "e-p:64:64" -; Make sure that optimizations do not optimize inrange GEP. +; Make sure that optimizations do not lose inrange information. @vtable = constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr null] } define void @foo(ptr %p) { - ;CHECK: store ptr getelementptr {{.*}} ({ [3 x ptr] }, ptr @vtable, i{{.*}} 0, inrange i32 0, i{{.*}} 3), ptr %p - store ptr getelementptr ({ [3 x ptr] }, ptr @vtable, i32 0, inrange i32 0, i32 3), ptr %p +; O0-LABEL: define void @foo( +; O0-SAME: ptr [[P:%.*]]) { +; O0-NEXT: store ptr getelementptr inrange(-24, 0) ({ [3 x ptr], [3 x ptr] }, ptr @vtable, i32 0, i32 0, i32 3), ptr [[P]], align 8 +; O0-NEXT: ret void +; +; CHECK-LABEL: define void @foo( +; CHECK-SAME: ptr nocapture writeonly [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: store ptr getelementptr inbounds inrange(-24, 0) ({ [3 x ptr] }, ptr @vtable, i64 1, i32 0, i64 0), ptr [[P]], align 8 +; CHECK-NEXT: ret void +; + store ptr getelementptr inrange(-24, 0) ({ [3 x ptr], [3 x ptr] }, ptr @vtable, i32 0, i32 0, i32 3), ptr %p ret void } diff --git a/llvm/test/Transforms/GlobalDCE/virtual-functions-base-call.ll b/llvm/test/Transforms/GlobalDCE/virtual-functions-base-call.ll index 8ef2d895a029..baf5c7272dfe 100644 --- a/llvm/test/Transforms/GlobalDCE/virtual-functions-base-call.ll +++ b/llvm/test/Transforms/GlobalDCE/virtual-functions-base-call.ll @@ -45,13 +45,13 @@ entry: define hidden void @_ZN1AC2Ev(ptr nocapture %this) { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } define hidden void @_ZN1BC2Ev(ptr nocapture %this) { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1B, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1B, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } diff --git a/llvm/test/Transforms/GlobalDCE/virtual-functions-base-pointer-call.ll b/llvm/test/Transforms/GlobalDCE/virtual-functions-base-pointer-call.ll index 09979690da6d..47a80f843c93 100644 --- a/llvm/test/Transforms/GlobalDCE/virtual-functions-base-pointer-call.ll +++ b/llvm/test/Transforms/GlobalDCE/virtual-functions-base-pointer-call.ll @@ -65,13 +65,13 @@ entry: define hidden void @_ZN1AC2Ev(ptr nocapture %this) { entry: - store ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } define hidden void @_ZN1BC2Ev(ptr nocapture %this) { entry: - store ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1B, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV1B, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } diff --git a/llvm/test/Transforms/GlobalDCE/virtual-functions-derived-call.ll b/llvm/test/Transforms/GlobalDCE/virtual-functions-derived-call.ll index 896675f7655f..50b682543956 100644 --- a/llvm/test/Transforms/GlobalDCE/virtual-functions-derived-call.ll +++ b/llvm/test/Transforms/GlobalDCE/virtual-functions-derived-call.ll @@ -45,13 +45,13 @@ entry: define hidden void @_ZN1AC2Ev(ptr nocapture %this) { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } define hidden void @_ZN1BC2Ev(ptr nocapture %this) { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1B, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1B, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } diff --git a/llvm/test/Transforms/GlobalDCE/virtual-functions-derived-pointer-call.ll b/llvm/test/Transforms/GlobalDCE/virtual-functions-derived-pointer-call.ll index bdf97d25ac3f..e5dea7ad9a81 100644 --- a/llvm/test/Transforms/GlobalDCE/virtual-functions-derived-pointer-call.ll +++ b/llvm/test/Transforms/GlobalDCE/virtual-functions-derived-pointer-call.ll @@ -67,13 +67,13 @@ entry: define hidden void @_ZN1AC2Ev(ptr nocapture %this) { entry: - store ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } define hidden void @_ZN1BC2Ev(ptr nocapture %this) { entry: - store ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1B, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV1B, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } diff --git a/llvm/test/Transforms/GlobalDCE/virtual-functions-novfe.ll b/llvm/test/Transforms/GlobalDCE/virtual-functions-novfe.ll index 01475c8911fc..04f654c5e0b9 100644 --- a/llvm/test/Transforms/GlobalDCE/virtual-functions-novfe.ll +++ b/llvm/test/Transforms/GlobalDCE/virtual-functions-novfe.ll @@ -39,8 +39,8 @@ entry: define dso_local i32 @test_A() { entry: %call = tail call ptr @_Znwm(i64 8) - store ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), ptr %call, align 8 - %0 = tail call { ptr, i1 } @llvm.type.checked.load(ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), i32 0, metadata !"_ZTS1A"), !nosanitize !9 + store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), ptr %call, align 8 + %0 = tail call { ptr, i1 } @llvm.type.checked.load(ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), i32 0, metadata !"_ZTS1A"), !nosanitize !9 %1 = extractvalue { ptr, i1 } %0, 0, !nosanitize !9 %call1 = tail call i32 %1(ptr nonnull %call) ret i32 %call1 diff --git a/llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-post-lto.ll b/llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-post-lto.ll index 0fac0fbca109..dde36d46f6b9 100644 --- a/llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-post-lto.ll +++ b/llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-post-lto.ll @@ -18,7 +18,7 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" define internal void @_ZN1AC2Ev(ptr %this) { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } @@ -43,7 +43,7 @@ entry: define internal void @_ZN1BC2Ev(ptr %this) { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1B, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1B, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } @@ -68,7 +68,7 @@ entry: define internal void @_ZN1CC2Ev(ptr %this) { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1C, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1C, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } diff --git a/llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-pre-lto.ll b/llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-pre-lto.ll index 7875d38c8c0b..ac9c362e1fd6 100644 --- a/llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-pre-lto.ll +++ b/llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-pre-lto.ll @@ -12,7 +12,7 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" define internal void @_ZN1AC2Ev(ptr %this) { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } @@ -36,7 +36,7 @@ entry: define internal void @_ZN1BC2Ev(ptr %this) { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1B, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1B, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } @@ -60,7 +60,7 @@ entry: define internal void @_ZN1CC2Ev(ptr %this) { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1C, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1C, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } diff --git a/llvm/test/Transforms/GlobalDCE/virtual-functions.ll b/llvm/test/Transforms/GlobalDCE/virtual-functions.ll index e00f8a7fdfec..0d9b51ca8c5f 100644 --- a/llvm/test/Transforms/GlobalDCE/virtual-functions.ll +++ b/llvm/test/Transforms/GlobalDCE/virtual-functions.ll @@ -38,8 +38,8 @@ entry: define dso_local i32 @test_A() { entry: %call = tail call ptr @_Znwm(i64 8) - store ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), ptr %call, align 8 - %0 = tail call { ptr, i1 } @llvm.type.checked.load(ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), i32 0, metadata !"_ZTS1A"), !nosanitize !9 + store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), ptr %call, align 8 + %0 = tail call { ptr, i1 } @llvm.type.checked.load(ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), i32 0, metadata !"_ZTS1A"), !nosanitize !9 %1 = extractvalue { ptr, i1 } %0, 0, !nosanitize !9 %call1 = tail call i32 %1(ptr nonnull %call) ret i32 %call1 diff --git a/llvm/test/Transforms/GlobalDCE/vtable-rtti.ll b/llvm/test/Transforms/GlobalDCE/vtable-rtti.ll index 2eb761e8ab1a..c4a45ffaf63a 100644 --- a/llvm/test/Transforms/GlobalDCE/vtable-rtti.ll +++ b/llvm/test/Transforms/GlobalDCE/vtable-rtti.ll @@ -16,7 +16,7 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" define internal void @_ZN1AC2Ev(ptr %this) { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } diff --git a/llvm/test/Transforms/GlobalSplit/basic.ll b/llvm/test/Transforms/GlobalSplit/basic.ll index c47bdd64e02f..eb1515741763 100644 --- a/llvm/test/Transforms/GlobalSplit/basic.ll +++ b/llvm/test/Transforms/GlobalSplit/basic.ll @@ -3,11 +3,11 @@ target datalayout = "e-p:64:64" target triple = "x86_64-unknown-linux-gnu" -; CHECK: @vtt = constant [3 x ptr] [ptr @global.0, ptr getelementptr inbounds ([2 x ptr], ptr @global.0, i32 0, i32 1), ptr @global.1] +; CHECK: @vtt = constant [3 x ptr] [ptr @global.0, ptr getelementptr inbounds (i8, ptr @global.0, i64 8), ptr @global.1] @vtt = constant [3 x ptr] [ - ptr getelementptr ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, inrange i32 0, i32 0), - ptr getelementptr ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, inrange i32 0, i32 1), - ptr getelementptr ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, inrange i32 1, i32 0) + ptr getelementptr inrange(0, 16) ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, i32 0, i32 0), + ptr getelementptr inrange(-8, 8) ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, i32 0, i32 1), + ptr getelementptr inrange(0, 8) ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, i32 1, i32 0) ] ; CHECK-NOT: @global = @@ -22,25 +22,25 @@ target triple = "x86_64-unknown-linux-gnu" ; CHECK: define ptr @f1() define ptr @f1() { ; CHECK-NEXT: ret ptr @global.0 - ret ptr getelementptr ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, inrange i32 0, i32 0) + ret ptr getelementptr inrange(0, 16) ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, i32 0, i32 0) } ; CHECK: define ptr @f2() define ptr @f2() { - ; CHECK-NEXT: ret ptr getelementptr inbounds ([2 x ptr], ptr @global.0, i32 0, i32 1) - ret ptr getelementptr ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, inrange i32 0, i32 1) + ; CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr @global.0, i64 8) + ret ptr getelementptr inrange(-8, 8) ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, i32 0, i32 1) } ; CHECK: define ptr @f3() define ptr @f3() { - ; CHECK-NEXT: ret ptr getelementptr inbounds ([2 x ptr], ptr @global.0, i64 1, i32 0) - ret ptr getelementptr ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, inrange i32 0, i32 2) + ; CHECK-NEXT: ret ptr getelementptr (i8, ptr @global.0, i64 16) + ret ptr getelementptr inrange(-16, 0) ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, i32 0, i32 2) } ; CHECK: define ptr @f4() define ptr @f4() { ; CHECK-NEXT: ret ptr @global.1 - ret ptr getelementptr ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, inrange i32 1, i32 0) + ret ptr getelementptr inrange(0, 8) ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, i32 1, i32 0) } define void @foo() { diff --git a/llvm/test/Transforms/GlobalSplit/non-beneficial.ll b/llvm/test/Transforms/GlobalSplit/non-beneficial.ll index a7c50c985c90..5e27623dd6e9 100644 --- a/llvm/test/Transforms/GlobalSplit/non-beneficial.ll +++ b/llvm/test/Transforms/GlobalSplit/non-beneficial.ll @@ -10,7 +10,7 @@ target triple = "x86_64-unknown-linux-gnu" } define ptr @f() { - ret ptr getelementptr ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, inrange i32 0, i32 0) + ret ptr getelementptr inrange(0, 16) ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, i32 0, i32 0) } define ptr @g() { diff --git a/llvm/test/Transforms/GlobalSplit/nonlocal.ll b/llvm/test/Transforms/GlobalSplit/nonlocal.ll index 38169a8bea47..0e639135feb6 100644 --- a/llvm/test/Transforms/GlobalSplit/nonlocal.ll +++ b/llvm/test/Transforms/GlobalSplit/nonlocal.ll @@ -10,7 +10,7 @@ target triple = "x86_64-unknown-linux-gnu" } define ptr @f() { - ret ptr getelementptr ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, inrange i32 0, i32 0) + ret ptr getelementptr inrange(0, 16) ({ [2 x ptr], [1 x ptr] }, ptr @global, i32 0, i32 0, i32 0) } define ptr @g() { diff --git a/llvm/test/Transforms/Inline/devirtualize-4.ll b/llvm/test/Transforms/Inline/devirtualize-4.ll index fae364313ea0..d29360f73b47 100644 --- a/llvm/test/Transforms/Inline/devirtualize-4.ll +++ b/llvm/test/Transforms/Inline/devirtualize-4.ll @@ -60,7 +60,7 @@ declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) define linkonce_odr dso_local void @_ZN4ImplC2Ev(ptr %this) unnamed_addr align 2 { entry: call void @_ZN9InterfaceC2Ev(ptr %this) - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV4Impl, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV4Impl, i64 0, i32 0, i64 2), ptr %this, align 8 %f = getelementptr inbounds %class.Impl, ptr %this, i64 0, i32 1 store i32 3, ptr %f, align 8 ret void @@ -78,7 +78,7 @@ declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) define linkonce_odr dso_local void @_ZN9InterfaceC2Ev(ptr %this) unnamed_addr align 2 { entry: - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV9Interface, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV9Interface, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } @@ -185,7 +185,7 @@ entry: define linkonce_odr void @_ZN1AC2Ev(ptr %this) align 2 { entry: - store ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, inrange i32 0, i64 2), ptr %this, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [4 x ptr] }, ptr @_ZTV1A, i64 0, i32 0, i64 2), ptr %this, align 8 ret void } diff --git a/llvm/test/Transforms/InstCombine/fmul.ll b/llvm/test/Transforms/InstCombine/fmul.ll index 7e7373e6ef5b..96e57939d285 100644 --- a/llvm/test/Transforms/InstCombine/fmul.ll +++ b/llvm/test/Transforms/InstCombine/fmul.ll @@ -1093,11 +1093,11 @@ for.body: define double @fmul_negated_constant_expression(double %x) { ; CHECK-LABEL: @fmul_negated_constant_expression( -; CHECK-NEXT: [[FSUB:%.*]] = fneg double bitcast (i64 ptrtoint (ptr getelementptr inbounds ({ [2 x ptr] }, ptr @g, i64 0, inrange i32 0, i64 2) to i64) to double) +; CHECK-NEXT: [[FSUB:%.*]] = fneg double bitcast (i64 ptrtoint (ptr getelementptr inbounds ({ [2 x ptr] }, ptr @g, i64 1, i32 0, i64 0) to i64) to double) ; CHECK-NEXT: [[R:%.*]] = fmul double [[FSUB]], [[X:%.*]] ; CHECK-NEXT: ret double [[R]] ; - %fsub = fsub double -0.000000e+00, bitcast (i64 ptrtoint (ptr getelementptr inbounds ({ [2 x ptr] }, ptr @g, i64 0, inrange i32 0, i64 2) to i64) to double) + %fsub = fsub double -0.000000e+00, bitcast (i64 ptrtoint (ptr getelementptr inbounds ({ [2 x ptr] }, ptr @g, i64 0, i32 0, i64 2) to i64) to double) %r = fmul double %x, %fsub ret double %r } diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/gep.ll b/llvm/test/Transforms/InstSimplify/ConstProp/gep.ll index 6dd34a481df1..d91349a570b7 100644 --- a/llvm/test/Transforms/InstSimplify/ConstProp/gep.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/gep.ll @@ -11,21 +11,21 @@ target triple = "x86_64-unknown-linux-gnu" define ptr @f0() { ; CHECK-LABEL: @f0( -; CHECK-NEXT: ret ptr getelementptr inbounds ([3 x ptr], ptr @vt, inrange i64 0, i64 2) +; CHECK-NEXT: ret ptr getelementptr inbounds inrange(-16, 8) ([3 x ptr], ptr @vt, i64 0, i64 2) ; - ret ptr getelementptr (ptr, ptr getelementptr inbounds ([3 x ptr], ptr @vt, inrange i64 0, i64 1), i64 1) + ret ptr getelementptr (ptr, ptr getelementptr inbounds inrange(-8, 16) ([3 x ptr], ptr @vt, i64 0, i64 1), i64 1) } define ptr @f1() { ; CHECK-LABEL: @f1( -; CHECK-NEXT: ret ptr getelementptr inbounds ([3 x ptr], ptr @vt, i64 0, i64 2) +; CHECK-NEXT: ret ptr getelementptr inbounds inrange(-8, 0) ([3 x ptr], ptr @vt, i64 0, i64 2) ; - ret ptr getelementptr (ptr, ptr getelementptr inbounds ([3 x ptr], ptr @vt, i64 0, inrange i64 1), i64 1) + ret ptr getelementptr (ptr, ptr getelementptr inbounds inrange(0, 8) ([3 x ptr], ptr @vt, i64 0, i64 1), i64 1) } define ptr @f2() { ; CHECK-LABEL: @f2( -; CHECK-NEXT: ret ptr getelementptr ([3 x ptr], ptr @vt, i64 1, i64 1) +; CHECK-NEXT: ret ptr getelementptr inrange(-24, -16) ([3 x ptr], ptr @vt, i64 1, i64 1) ; - ret ptr getelementptr (ptr, ptr getelementptr inbounds ([3 x ptr], ptr @vt, i64 0, inrange i64 1), i64 3) + ret ptr getelementptr (ptr, ptr getelementptr inbounds inrange(0, 8) ([3 x ptr], ptr @vt, i64 0, i64 1), i64 3) } diff --git a/llvm/test/Transforms/Internalize/vcall-visibility.ll b/llvm/test/Transforms/Internalize/vcall-visibility.ll index c2fe8c3a01e9..ee6753534419 100644 --- a/llvm/test/Transforms/Internalize/vcall-visibility.ll +++ b/llvm/test/Transforms/Internalize/vcall-visibility.ll @@ -42,7 +42,7 @@ entry: define hidden noalias nonnull ptr @_Z6make_dv() { entry: %call = tail call ptr @_Znwm(i64 8) #3 - store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN12_GLOBAL__N_11DE, i64 0, inrange i32 0, i64 2), ptr %call, align 8 + store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN12_GLOBAL__N_11DE, i64 0, i32 0, i64 2), ptr %call, align 8 ret ptr %call } diff --git a/llvm/test/Transforms/MergeFunc/constexpr.ll b/llvm/test/Transforms/MergeFunc/constexpr.ll index 9fb780601742..3946fd6a066f 100644 --- a/llvm/test/Transforms/MergeFunc/constexpr.ll +++ b/llvm/test/Transforms/MergeFunc/constexpr.ll @@ -66,9 +66,9 @@ define i64 @f8() unnamed_addr { define ptr @f10() unnamed_addr { ; CHECK-LABEL: define ptr @f10() unnamed_addr { -; CHECK-NEXT: ret ptr getelementptr ([4 x i32], ptr @g1, i64 0, inrange i64 1) +; CHECK-NEXT: ret ptr getelementptr inrange(0, 4) ([4 x i32], ptr @g1, i64 0, i64 1) ; - ret ptr getelementptr ([4 x i32], ptr @g1, i64 0, inrange i64 1) + ret ptr getelementptr inrange(0, 4) ([4 x i32], ptr @g1, i64 0, i64 1) } define ptr @f11() unnamed_addr { @@ -80,7 +80,7 @@ define ptr @f11() unnamed_addr { define ptr @f12() unnamed_addr { ; CHECK-LABEL: define ptr @f12() unnamed_addr { -; CHECK-NEXT: ret ptr getelementptr ([4 x i32], ptr @g1, inrange i64 0, i64 1) +; CHECK-NEXT: ret ptr getelementptr inrange(-4, 12) ([4 x i32], ptr @g1, i64 0, i64 1) ; - ret ptr getelementptr ([4 x i32], ptr @g1, inrange i64 0, i64 1) + ret ptr getelementptr inrange(-4, 12) ([4 x i32], ptr @g1, i64 0, i64 1) } diff --git a/llvm/test/Transforms/ThinLTOBitcodeWriter/pr33536.ll b/llvm/test/Transforms/ThinLTOBitcodeWriter/pr33536.ll index 8e78921c556d..a51c1d24956a 100644 --- a/llvm/test/Transforms/ThinLTOBitcodeWriter/pr33536.ll +++ b/llvm/test/Transforms/ThinLTOBitcodeWriter/pr33536.ll @@ -12,7 +12,7 @@ target triple = "x86_64-unknown-linux-gnu" ; M0: @global = local_unnamed_addr global ; M1-NOT: @global -@global = local_unnamed_addr global %struct.hoge { %struct.widget { ptr getelementptr inbounds ({ [3 x ptr] }, ptr @global.1, i32 0, inrange i32 0, i32 2) } }, align 8 +@global = local_unnamed_addr global %struct.hoge { %struct.widget { ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @global.1, i32 0, i32 0, i32 2) } }, align 8 ; M0: @global.1 = external unnamed_addr constant ; M1: @global.1 = linkonce_odr unnamed_addr constant -- GitLab From 27534d69e275eeb6669296c038bf29d8a9b163e5 Mon Sep 17 00:00:00 2001 From: Tom Eccles <tom.eccles@arm.com> Date: Wed, 20 Mar 2024 10:03:26 +0000 Subject: [PATCH 206/307] [mlir][LLVM] erase call mappings in forgetMapping() (#84955) It looks like the mappings for call instructions were forgotten here. This fixes a bug in OpenMP when in-lining a region containing call operations multiple times. OpenMP array reductions 4/6 Previous PR: https://github.com/llvm/llvm-project/pull/84954 Next PR: https://github.com/llvm/llvm-project/pull/84957 --- mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 2 + .../Target/LLVMIR/openmp-reduction-call.mlir | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 mlir/test/Target/LLVMIR/openmp-reduction-call.mlir diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index c00628a420a0..995544238e4a 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -716,6 +716,8 @@ void ModuleTranslation::forgetMapping(Region ®ion) { branchMapping.erase(&op); if (isa<LLVM::GlobalOp>(op)) globalsMapping.erase(&op); + if (isa<LLVM::CallOp>(op)) + callMapping.erase(&op); llvm::append_range( toProcess, llvm::map_range(op.getRegions(), [](Region &r) { return &r; })); diff --git a/mlir/test/Target/LLVMIR/openmp-reduction-call.mlir b/mlir/test/Target/LLVMIR/openmp-reduction-call.mlir new file mode 100644 index 000000000000..9aa9ac7e4b5a --- /dev/null +++ b/mlir/test/Target/LLVMIR/openmp-reduction-call.mlir @@ -0,0 +1,37 @@ +// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s + +// Test that we don't crash when there is a call operation in the combiner + +omp.reduction.declare @add_f32 : f32 +init { +^bb0(%arg: f32): + %0 = llvm.mlir.constant(0.0 : f32) : f32 + omp.yield (%0 : f32) +} +combiner { +^bb1(%arg0: f32, %arg1: f32): +// test this call here: + llvm.call @test_call() : () -> () + %1 = llvm.fadd %arg0, %arg1 : f32 + omp.yield (%1 : f32) +} + +llvm.func @simple_reduction(%lb : i64, %ub : i64, %step : i64) { + %c1 = llvm.mlir.constant(1 : i32) : i32 + %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr + omp.parallel reduction(@add_f32 %0 -> %prv : !llvm.ptr) { + %1 = llvm.mlir.constant(2.0 : f32) : f32 + %2 = llvm.load %prv : !llvm.ptr -> f32 + %3 = llvm.fadd %1, %2 : f32 + llvm.store %3, %prv : f32, !llvm.ptr + omp.terminator + } + llvm.return +} + +llvm.func @test_call() -> () + +// Call to the troublesome function will have been inlined twice: once into +// main and once into the outlined function +// CHECK: call void @test_call() +// CHECK: call void @test_call() -- GitLab From 56e32491526e21687ed1466a99ae39a9374e30b0 Mon Sep 17 00:00:00 2001 From: Jay Foad <jay.foad@amd.com> Date: Wed, 20 Mar 2024 10:04:22 +0000 Subject: [PATCH 207/307] [AMDGPU] Simplify GFX11/GFX12 FLAT instruction definitions. NFC. (#85819) - Give the tablegen record for the Real the same name as the tablegen record for the pseudo. This removes all cases where the same instruction name has to be mentioned more than once on the definition line. - Use multiclasses for all Real definitions, to allow suffixes to be added bit by bit, e.g. first _SADDR and then _gfx11. This is a similar approach to the one used in BUFInstructions.td. --- llvm/lib/Target/AMDGPU/FLATInstructions.td | 731 ++++++++++----------- 1 file changed, 363 insertions(+), 368 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/FLATInstructions.td b/llvm/lib/Target/AMDGPU/FLATInstructions.td index 3c0a97e3d050..6526a7f9fc41 100644 --- a/llvm/lib/Target/AMDGPU/FLATInstructions.td +++ b/llvm/lib/Target/AMDGPU/FLATInstructions.td @@ -2333,403 +2333,398 @@ defm SCRATCH_LOAD_LDS_DWORD : FLAT_Real_ScratchAllAddr_LDS_gfx10 <0x00c>; // GFX11 //===----------------------------------------------------------------------===// -class FLAT_Real_gfx11 <bits<7> op, FLAT_Pseudo ps, string opName = ps.Mnemonic> : - FLAT_Real <op, ps, opName>, - SIMCInstr <ps.PseudoInstr, SIEncodingFamily.GFX11> { - let AssemblerPredicate = isGFX11Only; - let DecoderNamespace = "GFX11"; - - let Inst{13} = !if(ps.has_dlc, cpol{CPolBit.DLC}, ps.dlcValue); - let Inst{14} = !if(ps.has_glc, cpol{CPolBit.GLC}, ps.glcValue); - let Inst{15} = cpol{CPolBit.SLC}; - let Inst{17-16} = seg; - let Inst{54-48} = !if(ps.enabled_saddr, saddr, SGPR_NULL_gfx11plus.Index); - let Inst{55} = ps.sve; +class get_FLAT_ps<string name> { + string Mnemonic = !cast<FLAT_Pseudo>(name).Mnemonic; } -multiclass FLAT_Aliases_gfx11<string ps, string opName, int renamed> { - if renamed then - def _renamed_gfx11 : MnemonicAlias<!cast<FLAT_Pseudo>(ps).Mnemonic, opName>, Requires<[isGFX11Only]>; +multiclass FLAT_Real_gfx11 <bits<7> op, + string name = get_FLAT_ps<NAME>.Mnemonic> { + defvar ps = !cast<FLAT_Pseudo>(NAME); + def _gfx11 : FLAT_Real <op, ps, name>, + SIMCInstr <ps.PseudoInstr, SIEncodingFamily.GFX11> { + let AssemblerPredicate = isGFX11Only; + let DecoderNamespace = "GFX11"; + + let Inst{13} = !if(ps.has_dlc, cpol{CPolBit.DLC}, ps.dlcValue); + let Inst{14} = !if(ps.has_glc, cpol{CPolBit.GLC}, ps.glcValue); + let Inst{15} = cpol{CPolBit.SLC}; + let Inst{17-16} = seg; + let Inst{54-48} = !if(ps.enabled_saddr, saddr, SGPR_NULL_gfx11plus.Index); + let Inst{55} = ps.sve; + } } -multiclass FLAT_Real_Base_gfx11<bits<7> op, string ps, string opName, int renamed = false> : - FLAT_Aliases_gfx11<ps, opName, renamed> { - def _gfx11 : FLAT_Real_gfx11<op, !cast<FLAT_Pseudo>(ps), opName>; +multiclass FLAT_Aliases_gfx11<string name> { + defvar ps = get_FLAT_ps<NAME>; + if !ne(ps.Mnemonic, name) then + def : MnemonicAlias<ps.Mnemonic, name>, Requires<[isGFX11Only]>; } -multiclass FLAT_Real_RTN_gfx11<bits<7> op, string ps, string opName> { - def _RTN_gfx11 : FLAT_Real_gfx11<op, !cast<FLAT_Pseudo>(ps#"_RTN"), opName>; -} +multiclass FLAT_Real_Base_gfx11<bits<7> op, + string name = get_FLAT_ps<NAME>.Mnemonic> : + FLAT_Aliases_gfx11<name>, + FLAT_Real_gfx11<op, name>; -multiclass FLAT_Real_SADDR_gfx11<bits<7> op, string ps, string opName> { - def _SADDR_gfx11 : FLAT_Real_gfx11<op, !cast<FLAT_Pseudo>(ps#"_SADDR"), opName>; +multiclass FLAT_Real_AllAddr_gfx11<bits<7> op, + string name = get_FLAT_ps<NAME>.Mnemonic> : + FLAT_Real_Base_gfx11<op, name> { + defm _SADDR : FLAT_Real_gfx11<op, name>; } -multiclass FLAT_Real_SADDR_RTN_gfx11<bits<7> op, string ps, string opName> { - def _SADDR_RTN_gfx11 : FLAT_Real_gfx11<op, !cast<FLAT_Pseudo>(ps#"_SADDR_RTN"), opName>; +multiclass FLAT_Real_Atomics_gfx11<bits<7> op, + string name = get_FLAT_ps<NAME>.Mnemonic> : + FLAT_Real_Base_gfx11<op, name> { + defm _RTN : FLAT_Real_gfx11<op, name>; } -multiclass FLAT_Real_ST_gfx11<bits<7> op, string ps, string opName> { - def _ST_gfx11 : FLAT_Real_gfx11<op, !cast<FLAT_Pseudo>(ps#"_ST"), opName>; +multiclass GLOBAL_Real_AllAddr_gfx11<bits<7> op, + string name = get_FLAT_ps<NAME>.Mnemonic> : + FLAT_Aliases_gfx11<name>, + FLAT_Real_gfx11<op, name> { + defm _SADDR : FLAT_Real_gfx11<op, name>; } -multiclass FLAT_Real_SVS_gfx11<bits<7> op, string ps, string opName> { - def _SVS_gfx11 : FLAT_Real_gfx11<op, !cast<FLAT_Pseudo>(ps#"_SVS"), opName>; +multiclass GLOBAL_Real_Atomics_gfx11<bits<7> op, + string name = get_FLAT_ps<NAME>.Mnemonic> : + GLOBAL_Real_AllAddr_gfx11<op, name> { + defm _RTN : FLAT_Real_gfx11<op, name>; + defm _SADDR_RTN : FLAT_Real_gfx11<op, name>; } -multiclass FLAT_Real_AllAddr_gfx11<bits<7> op, string ps, string opName, int renamed = false> : - FLAT_Real_Base_gfx11<op, ps, opName, renamed>, - FLAT_Real_SADDR_gfx11<op, ps, opName>; - -multiclass FLAT_Real_Atomics_gfx11<bits<7> op, string ps, string opName, int renamed = false> : - FLAT_Real_Base_gfx11<op, ps, opName, renamed>, - FLAT_Real_RTN_gfx11<op, ps, opName>; - -multiclass FLAT_Real_GlblAtomics_gfx11<bits<7> op, string ps, string opName, int renamed = false> : - FLAT_Real_AllAddr_gfx11<op, ps, opName, renamed>, - FLAT_Real_RTN_gfx11<op, ps, opName>, - FLAT_Real_SADDR_RTN_gfx11<op, ps, opName>; - -multiclass FLAT_Real_GlblAtomics_RTN_gfx11<bits<7> op, string ps, string opName, int renamed = false> : - FLAT_Aliases_gfx11<ps#"_RTN", opName, renamed>, - FLAT_Real_RTN_gfx11<op, ps, opName>, - FLAT_Real_SADDR_RTN_gfx11<op, ps, opName>; - -multiclass FLAT_Real_ScratchAllAddr_gfx11<bits<7> op, string ps, string opName, int renamed = false> : - FLAT_Real_Base_gfx11<op, ps, opName, renamed>, - FLAT_Real_SADDR_gfx11<op, ps, opName>, - FLAT_Real_ST_gfx11<op, ps, opName>, - FLAT_Real_SVS_gfx11<op, ps, opName>; +multiclass SCRATCH_Real_AllAddr_gfx11<bits<7> op, + string name = get_FLAT_ps<NAME>.Mnemonic> : + FLAT_Aliases_gfx11<name>, + FLAT_Real_gfx11<op, name> { + defm _SADDR : FLAT_Real_gfx11<op, name>; + defm _ST : FLAT_Real_gfx11<op, name>; + defm _SVS : FLAT_Real_gfx11<op, name>; +} // ENC_FLAT. -defm FLAT_LOAD_U8 : FLAT_Real_Base_gfx11<0x010, "FLAT_LOAD_UBYTE", "flat_load_u8", true>; -defm FLAT_LOAD_I8 : FLAT_Real_Base_gfx11<0x011, "FLAT_LOAD_SBYTE", "flat_load_i8", true>; -defm FLAT_LOAD_U16 : FLAT_Real_Base_gfx11<0x012, "FLAT_LOAD_USHORT", "flat_load_u16", true>; -defm FLAT_LOAD_I16 : FLAT_Real_Base_gfx11<0x013, "FLAT_LOAD_SSHORT", "flat_load_i16", true>; -defm FLAT_LOAD_B32 : FLAT_Real_Base_gfx11<0x014, "FLAT_LOAD_DWORD", "flat_load_b32", true>; -defm FLAT_LOAD_B64 : FLAT_Real_Base_gfx11<0x015, "FLAT_LOAD_DWORDX2", "flat_load_b64", true>; -defm FLAT_LOAD_B96 : FLAT_Real_Base_gfx11<0x016, "FLAT_LOAD_DWORDX3", "flat_load_b96", true>; -defm FLAT_LOAD_B128 : FLAT_Real_Base_gfx11<0x017, "FLAT_LOAD_DWORDX4", "flat_load_b128", true>; -defm FLAT_STORE_B8 : FLAT_Real_Base_gfx11<0x018, "FLAT_STORE_BYTE", "flat_store_b8", true>; -defm FLAT_STORE_B16 : FLAT_Real_Base_gfx11<0x019, "FLAT_STORE_SHORT", "flat_store_b16", true>; -defm FLAT_STORE_B32 : FLAT_Real_Base_gfx11<0x01a, "FLAT_STORE_DWORD", "flat_store_b32", true>; -defm FLAT_STORE_B64 : FLAT_Real_Base_gfx11<0x01b, "FLAT_STORE_DWORDX2", "flat_store_b64", true>; -defm FLAT_STORE_B96 : FLAT_Real_Base_gfx11<0x01c, "FLAT_STORE_DWORDX3", "flat_store_b96", true>; -defm FLAT_STORE_B128 : FLAT_Real_Base_gfx11<0x01d, "FLAT_STORE_DWORDX4", "flat_store_b128", true>; -defm FLAT_LOAD_D16_U8 : FLAT_Real_Base_gfx11<0x01e, "FLAT_LOAD_UBYTE_D16", "flat_load_d16_u8">; -defm FLAT_LOAD_D16_I8 : FLAT_Real_Base_gfx11<0x01f, "FLAT_LOAD_SBYTE_D16", "flat_load_d16_i8">; -defm FLAT_LOAD_D16_B16 : FLAT_Real_Base_gfx11<0x020, "FLAT_LOAD_SHORT_D16", "flat_load_d16_b16">; -defm FLAT_LOAD_D16_HI_U8 : FLAT_Real_Base_gfx11<0x021, "FLAT_LOAD_UBYTE_D16_HI", "flat_load_d16_hi_u8">; -defm FLAT_LOAD_D16_HI_I8 : FLAT_Real_Base_gfx11<0x022, "FLAT_LOAD_SBYTE_D16_HI", "flat_load_d16_hi_i8">; -defm FLAT_LOAD_D16_HI_B16 : FLAT_Real_Base_gfx11<0x023, "FLAT_LOAD_SHORT_D16_HI", "flat_load_d16_hi_b16">; -defm FLAT_STORE_D16_HI_B8 : FLAT_Real_Base_gfx11<0x024, "FLAT_STORE_BYTE_D16_HI", "flat_store_d16_hi_b8">; -defm FLAT_STORE_D16_HI_B16 : FLAT_Real_Base_gfx11<0x025, "FLAT_STORE_SHORT_D16_HI", "flat_store_d16_hi_b16">; -defm FLAT_ATOMIC_SWAP_B32 : FLAT_Real_Atomics_gfx11<0x033, "FLAT_ATOMIC_SWAP", "flat_atomic_swap_b32", true>; -defm FLAT_ATOMIC_CMPSWAP_B32 : FLAT_Real_Atomics_gfx11<0x034, "FLAT_ATOMIC_CMPSWAP", "flat_atomic_cmpswap_b32", true>; -defm FLAT_ATOMIC_ADD_U32 : FLAT_Real_Atomics_gfx11<0x035, "FLAT_ATOMIC_ADD", "flat_atomic_add_u32", true>; -defm FLAT_ATOMIC_SUB_U32 : FLAT_Real_Atomics_gfx11<0x036, "FLAT_ATOMIC_SUB", "flat_atomic_sub_u32", true>; -defm FLAT_ATOMIC_MIN_I32 : FLAT_Real_Atomics_gfx11<0x038, "FLAT_ATOMIC_SMIN", "flat_atomic_min_i32", true>; -defm FLAT_ATOMIC_MIN_U32 : FLAT_Real_Atomics_gfx11<0x039, "FLAT_ATOMIC_UMIN", "flat_atomic_min_u32", true>; -defm FLAT_ATOMIC_MAX_I32 : FLAT_Real_Atomics_gfx11<0x03a, "FLAT_ATOMIC_SMAX", "flat_atomic_max_i32", true>; -defm FLAT_ATOMIC_MAX_U32 : FLAT_Real_Atomics_gfx11<0x03b, "FLAT_ATOMIC_UMAX", "flat_atomic_max_u32", true>; -defm FLAT_ATOMIC_AND_B32 : FLAT_Real_Atomics_gfx11<0x03c, "FLAT_ATOMIC_AND", "flat_atomic_and_b32", true>; -defm FLAT_ATOMIC_OR_B32 : FLAT_Real_Atomics_gfx11<0x03d, "FLAT_ATOMIC_OR", "flat_atomic_or_b32", true>; -defm FLAT_ATOMIC_XOR_B32 : FLAT_Real_Atomics_gfx11<0x03e, "FLAT_ATOMIC_XOR", "flat_atomic_xor_b32", true>; -defm FLAT_ATOMIC_INC_U32 : FLAT_Real_Atomics_gfx11<0x03f, "FLAT_ATOMIC_INC", "flat_atomic_inc_u32", true>; -defm FLAT_ATOMIC_DEC_U32 : FLAT_Real_Atomics_gfx11<0x040, "FLAT_ATOMIC_DEC", "flat_atomic_dec_u32", true>; -defm FLAT_ATOMIC_SWAP_B64 : FLAT_Real_Atomics_gfx11<0x041, "FLAT_ATOMIC_SWAP_X2", "flat_atomic_swap_b64", true>; -defm FLAT_ATOMIC_CMPSWAP_B64 : FLAT_Real_Atomics_gfx11<0x042, "FLAT_ATOMIC_CMPSWAP_X2", "flat_atomic_cmpswap_b64", true>; -defm FLAT_ATOMIC_ADD_U64 : FLAT_Real_Atomics_gfx11<0x043, "FLAT_ATOMIC_ADD_X2", "flat_atomic_add_u64", true>; -defm FLAT_ATOMIC_SUB_U64 : FLAT_Real_Atomics_gfx11<0x044, "FLAT_ATOMIC_SUB_X2", "flat_atomic_sub_u64", true>; -defm FLAT_ATOMIC_MIN_I64 : FLAT_Real_Atomics_gfx11<0x045, "FLAT_ATOMIC_SMIN_X2", "flat_atomic_min_i64", true>; -defm FLAT_ATOMIC_MIN_U64 : FLAT_Real_Atomics_gfx11<0x046, "FLAT_ATOMIC_UMIN_X2", "flat_atomic_min_u64", true>; -defm FLAT_ATOMIC_MAX_I64 : FLAT_Real_Atomics_gfx11<0x047, "FLAT_ATOMIC_SMAX_X2", "flat_atomic_max_i64", true>; -defm FLAT_ATOMIC_MAX_U64 : FLAT_Real_Atomics_gfx11<0x048, "FLAT_ATOMIC_UMAX_X2", "flat_atomic_max_u64", true>; -defm FLAT_ATOMIC_AND_B64 : FLAT_Real_Atomics_gfx11<0x049, "FLAT_ATOMIC_AND_X2", "flat_atomic_and_b64", true>; -defm FLAT_ATOMIC_OR_B64 : FLAT_Real_Atomics_gfx11<0x04a, "FLAT_ATOMIC_OR_X2", "flat_atomic_or_b64", true>; -defm FLAT_ATOMIC_XOR_B64 : FLAT_Real_Atomics_gfx11<0x04b, "FLAT_ATOMIC_XOR_X2", "flat_atomic_xor_b64", true>; -defm FLAT_ATOMIC_INC_U64 : FLAT_Real_Atomics_gfx11<0x04c, "FLAT_ATOMIC_INC_X2", "flat_atomic_inc_u64", true>; -defm FLAT_ATOMIC_DEC_U64 : FLAT_Real_Atomics_gfx11<0x04d, "FLAT_ATOMIC_DEC_X2", "flat_atomic_dec_u64", true>; -defm FLAT_ATOMIC_CMPSWAP_F32 : FLAT_Real_Atomics_gfx11<0x050, "FLAT_ATOMIC_FCMPSWAP", "flat_atomic_cmpswap_f32">; -defm FLAT_ATOMIC_MIN_F32 : FLAT_Real_Atomics_gfx11<0x051, "FLAT_ATOMIC_FMIN", "flat_atomic_min_f32">; -defm FLAT_ATOMIC_MAX_F32 : FLAT_Real_Atomics_gfx11<0x052, "FLAT_ATOMIC_FMAX", "flat_atomic_max_f32">; -defm FLAT_ATOMIC_ADD_F32 : FLAT_Real_Atomics_gfx11<0x056, "FLAT_ATOMIC_ADD_F32", "flat_atomic_add_f32">; +defm FLAT_LOAD_UBYTE : FLAT_Real_Base_gfx11<0x010, "flat_load_u8">; +defm FLAT_LOAD_SBYTE : FLAT_Real_Base_gfx11<0x011, "flat_load_i8">; +defm FLAT_LOAD_USHORT : FLAT_Real_Base_gfx11<0x012, "flat_load_u16">; +defm FLAT_LOAD_SSHORT : FLAT_Real_Base_gfx11<0x013, "flat_load_i16">; +defm FLAT_LOAD_DWORD : FLAT_Real_Base_gfx11<0x014, "flat_load_b32">; +defm FLAT_LOAD_DWORDX2 : FLAT_Real_Base_gfx11<0x015, "flat_load_b64">; +defm FLAT_LOAD_DWORDX3 : FLAT_Real_Base_gfx11<0x016, "flat_load_b96">; +defm FLAT_LOAD_DWORDX4 : FLAT_Real_Base_gfx11<0x017, "flat_load_b128">; +defm FLAT_STORE_BYTE : FLAT_Real_Base_gfx11<0x018, "flat_store_b8">; +defm FLAT_STORE_SHORT : FLAT_Real_Base_gfx11<0x019, "flat_store_b16">; +defm FLAT_STORE_DWORD : FLAT_Real_Base_gfx11<0x01a, "flat_store_b32">; +defm FLAT_STORE_DWORDX2 : FLAT_Real_Base_gfx11<0x01b, "flat_store_b64">; +defm FLAT_STORE_DWORDX3 : FLAT_Real_Base_gfx11<0x01c, "flat_store_b96">; +defm FLAT_STORE_DWORDX4 : FLAT_Real_Base_gfx11<0x01d, "flat_store_b128">; +defm FLAT_LOAD_UBYTE_D16 : FLAT_Real_Base_gfx11<0x01e, "flat_load_d16_u8">; +defm FLAT_LOAD_SBYTE_D16 : FLAT_Real_Base_gfx11<0x01f, "flat_load_d16_i8">; +defm FLAT_LOAD_SHORT_D16 : FLAT_Real_Base_gfx11<0x020, "flat_load_d16_b16">; +defm FLAT_LOAD_UBYTE_D16_HI : FLAT_Real_Base_gfx11<0x021, "flat_load_d16_hi_u8">; +defm FLAT_LOAD_SBYTE_D16_HI : FLAT_Real_Base_gfx11<0x022, "flat_load_d16_hi_i8">; +defm FLAT_LOAD_SHORT_D16_HI : FLAT_Real_Base_gfx11<0x023, "flat_load_d16_hi_b16">; +defm FLAT_STORE_BYTE_D16_HI : FLAT_Real_Base_gfx11<0x024, "flat_store_d16_hi_b8">; +defm FLAT_STORE_SHORT_D16_HI : FLAT_Real_Base_gfx11<0x025, "flat_store_d16_hi_b16">; +defm FLAT_ATOMIC_SWAP : FLAT_Real_Atomics_gfx11<0x033, "flat_atomic_swap_b32">; +defm FLAT_ATOMIC_CMPSWAP : FLAT_Real_Atomics_gfx11<0x034, "flat_atomic_cmpswap_b32">; +defm FLAT_ATOMIC_ADD : FLAT_Real_Atomics_gfx11<0x035, "flat_atomic_add_u32">; +defm FLAT_ATOMIC_SUB : FLAT_Real_Atomics_gfx11<0x036, "flat_atomic_sub_u32">; +defm FLAT_ATOMIC_SMIN : FLAT_Real_Atomics_gfx11<0x038, "flat_atomic_min_i32">; +defm FLAT_ATOMIC_UMIN : FLAT_Real_Atomics_gfx11<0x039, "flat_atomic_min_u32">; +defm FLAT_ATOMIC_SMAX : FLAT_Real_Atomics_gfx11<0x03a, "flat_atomic_max_i32">; +defm FLAT_ATOMIC_UMAX : FLAT_Real_Atomics_gfx11<0x03b, "flat_atomic_max_u32">; +defm FLAT_ATOMIC_AND : FLAT_Real_Atomics_gfx11<0x03c, "flat_atomic_and_b32">; +defm FLAT_ATOMIC_OR : FLAT_Real_Atomics_gfx11<0x03d, "flat_atomic_or_b32">; +defm FLAT_ATOMIC_XOR : FLAT_Real_Atomics_gfx11<0x03e, "flat_atomic_xor_b32">; +defm FLAT_ATOMIC_INC : FLAT_Real_Atomics_gfx11<0x03f, "flat_atomic_inc_u32">; +defm FLAT_ATOMIC_DEC : FLAT_Real_Atomics_gfx11<0x040, "flat_atomic_dec_u32">; +defm FLAT_ATOMIC_SWAP_X2 : FLAT_Real_Atomics_gfx11<0x041, "flat_atomic_swap_b64">; +defm FLAT_ATOMIC_CMPSWAP_X2 : FLAT_Real_Atomics_gfx11<0x042, "flat_atomic_cmpswap_b64">; +defm FLAT_ATOMIC_ADD_X2 : FLAT_Real_Atomics_gfx11<0x043, "flat_atomic_add_u64">; +defm FLAT_ATOMIC_SUB_X2 : FLAT_Real_Atomics_gfx11<0x044, "flat_atomic_sub_u64">; +defm FLAT_ATOMIC_SMIN_X2 : FLAT_Real_Atomics_gfx11<0x045, "flat_atomic_min_i64">; +defm FLAT_ATOMIC_UMIN_X2 : FLAT_Real_Atomics_gfx11<0x046, "flat_atomic_min_u64">; +defm FLAT_ATOMIC_SMAX_X2 : FLAT_Real_Atomics_gfx11<0x047, "flat_atomic_max_i64">; +defm FLAT_ATOMIC_UMAX_X2 : FLAT_Real_Atomics_gfx11<0x048, "flat_atomic_max_u64">; +defm FLAT_ATOMIC_AND_X2 : FLAT_Real_Atomics_gfx11<0x049, "flat_atomic_and_b64">; +defm FLAT_ATOMIC_OR_X2 : FLAT_Real_Atomics_gfx11<0x04a, "flat_atomic_or_b64">; +defm FLAT_ATOMIC_XOR_X2 : FLAT_Real_Atomics_gfx11<0x04b, "flat_atomic_xor_b64">; +defm FLAT_ATOMIC_INC_X2 : FLAT_Real_Atomics_gfx11<0x04c, "flat_atomic_inc_u64">; +defm FLAT_ATOMIC_DEC_X2 : FLAT_Real_Atomics_gfx11<0x04d, "flat_atomic_dec_u64">; +defm FLAT_ATOMIC_FCMPSWAP : FLAT_Real_Atomics_gfx11<0x050, "flat_atomic_cmpswap_f32">; +defm FLAT_ATOMIC_FMIN : FLAT_Real_Atomics_gfx11<0x051, "flat_atomic_min_f32">; +defm FLAT_ATOMIC_FMAX : FLAT_Real_Atomics_gfx11<0x052, "flat_atomic_max_f32">; +defm FLAT_ATOMIC_ADD_F32 : FLAT_Real_Atomics_gfx11<0x056>; // ENC_FLAT_GLBL. -defm GLOBAL_LOAD_U8 : FLAT_Real_AllAddr_gfx11<0x010, "GLOBAL_LOAD_UBYTE", "global_load_u8", true>; -defm GLOBAL_LOAD_I8 : FLAT_Real_AllAddr_gfx11<0x011, "GLOBAL_LOAD_SBYTE", "global_load_i8", true>; -defm GLOBAL_LOAD_U16 : FLAT_Real_AllAddr_gfx11<0x012, "GLOBAL_LOAD_USHORT", "global_load_u16", true>; -defm GLOBAL_LOAD_I16 : FLAT_Real_AllAddr_gfx11<0x013, "GLOBAL_LOAD_SSHORT", "global_load_i16", true>; -defm GLOBAL_LOAD_B32 : FLAT_Real_AllAddr_gfx11<0x014, "GLOBAL_LOAD_DWORD", "global_load_b32", true>; -defm GLOBAL_LOAD_B64 : FLAT_Real_AllAddr_gfx11<0x015, "GLOBAL_LOAD_DWORDX2", "global_load_b64", true>; -defm GLOBAL_LOAD_B96 : FLAT_Real_AllAddr_gfx11<0x016, "GLOBAL_LOAD_DWORDX3", "global_load_b96", true>; -defm GLOBAL_LOAD_B128 : FLAT_Real_AllAddr_gfx11<0x017, "GLOBAL_LOAD_DWORDX4", "global_load_b128", true>; -defm GLOBAL_STORE_B8 : FLAT_Real_AllAddr_gfx11<0x018, "GLOBAL_STORE_BYTE", "global_store_b8", true>; -defm GLOBAL_STORE_B16 : FLAT_Real_AllAddr_gfx11<0x019, "GLOBAL_STORE_SHORT", "global_store_b16", true>; -defm GLOBAL_STORE_B32 : FLAT_Real_AllAddr_gfx11<0x01a, "GLOBAL_STORE_DWORD", "global_store_b32", true>; -defm GLOBAL_STORE_B64 : FLAT_Real_AllAddr_gfx11<0x01b, "GLOBAL_STORE_DWORDX2", "global_store_b64", true>; -defm GLOBAL_STORE_B96 : FLAT_Real_AllAddr_gfx11<0x01c, "GLOBAL_STORE_DWORDX3", "global_store_b96", true>; -defm GLOBAL_STORE_B128 : FLAT_Real_AllAddr_gfx11<0x01d, "GLOBAL_STORE_DWORDX4", "global_store_b128", true>; -defm GLOBAL_LOAD_D16_U8 : FLAT_Real_AllAddr_gfx11<0x01e, "GLOBAL_LOAD_UBYTE_D16", "global_load_d16_u8">; -defm GLOBAL_LOAD_D16_I8 : FLAT_Real_AllAddr_gfx11<0x01f, "GLOBAL_LOAD_SBYTE_D16", "global_load_d16_i8">; -defm GLOBAL_LOAD_D16_B16 : FLAT_Real_AllAddr_gfx11<0x020, "GLOBAL_LOAD_SHORT_D16", "global_load_d16_b16">; -defm GLOBAL_LOAD_D16_HI_U8 : FLAT_Real_AllAddr_gfx11<0x021, "GLOBAL_LOAD_UBYTE_D16_HI", "global_load_d16_hi_u8">; -defm GLOBAL_LOAD_D16_HI_I8 : FLAT_Real_AllAddr_gfx11<0x022, "GLOBAL_LOAD_SBYTE_D16_HI", "global_load_d16_hi_i8">; -defm GLOBAL_LOAD_D16_HI_B16 : FLAT_Real_AllAddr_gfx11<0x023, "GLOBAL_LOAD_SHORT_D16_HI", "global_load_d16_hi_b16">; -defm GLOBAL_STORE_D16_HI_B8 : FLAT_Real_AllAddr_gfx11<0x024, "GLOBAL_STORE_BYTE_D16_HI", "global_store_d16_hi_b8">; -defm GLOBAL_STORE_D16_HI_B16 : FLAT_Real_AllAddr_gfx11<0x025, "GLOBAL_STORE_SHORT_D16_HI", "global_store_d16_hi_b16">; -defm GLOBAL_LOAD_ADDTID_B32 : FLAT_Real_AllAddr_gfx11<0x028, "GLOBAL_LOAD_DWORD_ADDTID", "global_load_addtid_b32">; -defm GLOBAL_STORE_ADDTID_B32 : FLAT_Real_AllAddr_gfx11<0x029, "GLOBAL_STORE_DWORD_ADDTID", "global_store_addtid_b32">; -defm GLOBAL_ATOMIC_SWAP_B32 : FLAT_Real_GlblAtomics_gfx11<0x033, "GLOBAL_ATOMIC_SWAP", "global_atomic_swap_b32", true>; -defm GLOBAL_ATOMIC_CMPSWAP_B32 : FLAT_Real_GlblAtomics_gfx11<0x034, "GLOBAL_ATOMIC_CMPSWAP", "global_atomic_cmpswap_b32", true>; -defm GLOBAL_ATOMIC_ADD_U32 : FLAT_Real_GlblAtomics_gfx11<0x035, "GLOBAL_ATOMIC_ADD", "global_atomic_add_u32", true>; -defm GLOBAL_ATOMIC_SUB_U32 : FLAT_Real_GlblAtomics_gfx11<0x036, "GLOBAL_ATOMIC_SUB", "global_atomic_sub_u32", true>; -defm GLOBAL_ATOMIC_CSUB_U32 : FLAT_Real_GlblAtomics_gfx11<0x037, "GLOBAL_ATOMIC_CSUB", "global_atomic_csub_u32", true>; -defm GLOBAL_ATOMIC_MIN_I32 : FLAT_Real_GlblAtomics_gfx11<0x038, "GLOBAL_ATOMIC_SMIN", "global_atomic_min_i32", true>; -defm GLOBAL_ATOMIC_MIN_U32 : FLAT_Real_GlblAtomics_gfx11<0x039, "GLOBAL_ATOMIC_UMIN", "global_atomic_min_u32", true>; -defm GLOBAL_ATOMIC_MAX_I32 : FLAT_Real_GlblAtomics_gfx11<0x03a, "GLOBAL_ATOMIC_SMAX", "global_atomic_max_i32", true>; -defm GLOBAL_ATOMIC_MAX_U32 : FLAT_Real_GlblAtomics_gfx11<0x03b, "GLOBAL_ATOMIC_UMAX", "global_atomic_max_u32", true>; -defm GLOBAL_ATOMIC_AND_B32 : FLAT_Real_GlblAtomics_gfx11<0x03c, "GLOBAL_ATOMIC_AND", "global_atomic_and_b32", true>; -defm GLOBAL_ATOMIC_OR_B32 : FLAT_Real_GlblAtomics_gfx11<0x03d, "GLOBAL_ATOMIC_OR", "global_atomic_or_b32", true>; -defm GLOBAL_ATOMIC_XOR_B32 : FLAT_Real_GlblAtomics_gfx11<0x03e, "GLOBAL_ATOMIC_XOR", "global_atomic_xor_b32", true>; -defm GLOBAL_ATOMIC_INC_U32 : FLAT_Real_GlblAtomics_gfx11<0x03f, "GLOBAL_ATOMIC_INC", "global_atomic_inc_u32", true>; -defm GLOBAL_ATOMIC_DEC_U32 : FLAT_Real_GlblAtomics_gfx11<0x040, "GLOBAL_ATOMIC_DEC", "global_atomic_dec_u32", true>; -defm GLOBAL_ATOMIC_SWAP_B64 : FLAT_Real_GlblAtomics_gfx11<0x041, "GLOBAL_ATOMIC_SWAP_X2", "global_atomic_swap_b64", true>; -defm GLOBAL_ATOMIC_CMPSWAP_B64 : FLAT_Real_GlblAtomics_gfx11<0x042, "GLOBAL_ATOMIC_CMPSWAP_X2", "global_atomic_cmpswap_b64", true>; -defm GLOBAL_ATOMIC_ADD_U64 : FLAT_Real_GlblAtomics_gfx11<0x043, "GLOBAL_ATOMIC_ADD_X2", "global_atomic_add_u64", true>; -defm GLOBAL_ATOMIC_SUB_U64 : FLAT_Real_GlblAtomics_gfx11<0x044, "GLOBAL_ATOMIC_SUB_X2", "global_atomic_sub_u64", true>; -defm GLOBAL_ATOMIC_MIN_I64 : FLAT_Real_GlblAtomics_gfx11<0x045, "GLOBAL_ATOMIC_SMIN_X2", "global_atomic_min_i64", true>; -defm GLOBAL_ATOMIC_MIN_U64 : FLAT_Real_GlblAtomics_gfx11<0x046, "GLOBAL_ATOMIC_UMIN_X2", "global_atomic_min_u64", true>; -defm GLOBAL_ATOMIC_MAX_I64 : FLAT_Real_GlblAtomics_gfx11<0x047, "GLOBAL_ATOMIC_SMAX_X2", "global_atomic_max_i64", true>; -defm GLOBAL_ATOMIC_MAX_U64 : FLAT_Real_GlblAtomics_gfx11<0x048, "GLOBAL_ATOMIC_UMAX_X2", "global_atomic_max_u64", true>; -defm GLOBAL_ATOMIC_AND_B64 : FLAT_Real_GlblAtomics_gfx11<0x049, "GLOBAL_ATOMIC_AND_X2", "global_atomic_and_b64", true>; -defm GLOBAL_ATOMIC_OR_B64 : FLAT_Real_GlblAtomics_gfx11<0x04a, "GLOBAL_ATOMIC_OR_X2", "global_atomic_or_b64", true>; -defm GLOBAL_ATOMIC_XOR_B64 : FLAT_Real_GlblAtomics_gfx11<0x04b, "GLOBAL_ATOMIC_XOR_X2", "global_atomic_xor_b64", true>; -defm GLOBAL_ATOMIC_INC_U64 : FLAT_Real_GlblAtomics_gfx11<0x04c, "GLOBAL_ATOMIC_INC_X2", "global_atomic_inc_u64", true>; -defm GLOBAL_ATOMIC_DEC_U64 : FLAT_Real_GlblAtomics_gfx11<0x04d, "GLOBAL_ATOMIC_DEC_X2", "global_atomic_dec_u64", true>; -defm GLOBAL_ATOMIC_CMPSWAP_F32 : FLAT_Real_GlblAtomics_gfx11<0x050, "GLOBAL_ATOMIC_FCMPSWAP", "global_atomic_cmpswap_f32">; -defm GLOBAL_ATOMIC_MIN_F32 : FLAT_Real_GlblAtomics_gfx11<0x051, "GLOBAL_ATOMIC_FMIN", "global_atomic_min_f32">; -defm GLOBAL_ATOMIC_MAX_F32 : FLAT_Real_GlblAtomics_gfx11<0x052, "GLOBAL_ATOMIC_FMAX", "global_atomic_max_f32">; -defm GLOBAL_ATOMIC_ADD_F32 : FLAT_Real_GlblAtomics_gfx11<0x056, "GLOBAL_ATOMIC_ADD_F32", "global_atomic_add_f32">; +defm GLOBAL_LOAD_UBYTE : FLAT_Real_AllAddr_gfx11<0x010, "global_load_u8">; +defm GLOBAL_LOAD_SBYTE : FLAT_Real_AllAddr_gfx11<0x011, "global_load_i8">; +defm GLOBAL_LOAD_USHORT : FLAT_Real_AllAddr_gfx11<0x012, "global_load_u16">; +defm GLOBAL_LOAD_SSHORT : FLAT_Real_AllAddr_gfx11<0x013, "global_load_i16">; +defm GLOBAL_LOAD_DWORD : FLAT_Real_AllAddr_gfx11<0x014, "global_load_b32">; +defm GLOBAL_LOAD_DWORDX2 : FLAT_Real_AllAddr_gfx11<0x015, "global_load_b64">; +defm GLOBAL_LOAD_DWORDX3 : FLAT_Real_AllAddr_gfx11<0x016, "global_load_b96">; +defm GLOBAL_LOAD_DWORDX4 : FLAT_Real_AllAddr_gfx11<0x017, "global_load_b128">; +defm GLOBAL_STORE_BYTE : FLAT_Real_AllAddr_gfx11<0x018, "global_store_b8">; +defm GLOBAL_STORE_SHORT : FLAT_Real_AllAddr_gfx11<0x019, "global_store_b16">; +defm GLOBAL_STORE_DWORD : FLAT_Real_AllAddr_gfx11<0x01a, "global_store_b32">; +defm GLOBAL_STORE_DWORDX2 : FLAT_Real_AllAddr_gfx11<0x01b, "global_store_b64">; +defm GLOBAL_STORE_DWORDX3 : FLAT_Real_AllAddr_gfx11<0x01c, "global_store_b96">; +defm GLOBAL_STORE_DWORDX4 : FLAT_Real_AllAddr_gfx11<0x01d, "global_store_b128">; +defm GLOBAL_LOAD_UBYTE_D16 : FLAT_Real_AllAddr_gfx11<0x01e, "global_load_d16_u8">; +defm GLOBAL_LOAD_SBYTE_D16 : FLAT_Real_AllAddr_gfx11<0x01f, "global_load_d16_i8">; +defm GLOBAL_LOAD_SHORT_D16 : FLAT_Real_AllAddr_gfx11<0x020, "global_load_d16_b16">; +defm GLOBAL_LOAD_UBYTE_D16_HI : FLAT_Real_AllAddr_gfx11<0x021, "global_load_d16_hi_u8">; +defm GLOBAL_LOAD_SBYTE_D16_HI : FLAT_Real_AllAddr_gfx11<0x022, "global_load_d16_hi_i8">; +defm GLOBAL_LOAD_SHORT_D16_HI : FLAT_Real_AllAddr_gfx11<0x023, "global_load_d16_hi_b16">; +defm GLOBAL_STORE_BYTE_D16_HI : FLAT_Real_AllAddr_gfx11<0x024, "global_store_d16_hi_b8">; +defm GLOBAL_STORE_SHORT_D16_HI : FLAT_Real_AllAddr_gfx11<0x025, "global_store_d16_hi_b16">; +defm GLOBAL_LOAD_DWORD_ADDTID : FLAT_Real_AllAddr_gfx11<0x028, "global_load_addtid_b32">; +defm GLOBAL_STORE_DWORD_ADDTID : FLAT_Real_AllAddr_gfx11<0x029, "global_store_addtid_b32">; +defm GLOBAL_ATOMIC_SWAP : GLOBAL_Real_Atomics_gfx11<0x033, "global_atomic_swap_b32">; +defm GLOBAL_ATOMIC_CMPSWAP : GLOBAL_Real_Atomics_gfx11<0x034, "global_atomic_cmpswap_b32">; +defm GLOBAL_ATOMIC_ADD : GLOBAL_Real_Atomics_gfx11<0x035, "global_atomic_add_u32">; +defm GLOBAL_ATOMIC_SUB : GLOBAL_Real_Atomics_gfx11<0x036, "global_atomic_sub_u32">; +defm GLOBAL_ATOMIC_CSUB : GLOBAL_Real_Atomics_gfx11<0x037, "global_atomic_csub_u32">; +defm GLOBAL_ATOMIC_SMIN : GLOBAL_Real_Atomics_gfx11<0x038, "global_atomic_min_i32">; +defm GLOBAL_ATOMIC_UMIN : GLOBAL_Real_Atomics_gfx11<0x039, "global_atomic_min_u32">; +defm GLOBAL_ATOMIC_SMAX : GLOBAL_Real_Atomics_gfx11<0x03a, "global_atomic_max_i32">; +defm GLOBAL_ATOMIC_UMAX : GLOBAL_Real_Atomics_gfx11<0x03b, "global_atomic_max_u32">; +defm GLOBAL_ATOMIC_AND : GLOBAL_Real_Atomics_gfx11<0x03c, "global_atomic_and_b32">; +defm GLOBAL_ATOMIC_OR : GLOBAL_Real_Atomics_gfx11<0x03d, "global_atomic_or_b32">; +defm GLOBAL_ATOMIC_XOR : GLOBAL_Real_Atomics_gfx11<0x03e, "global_atomic_xor_b32">; +defm GLOBAL_ATOMIC_INC : GLOBAL_Real_Atomics_gfx11<0x03f, "global_atomic_inc_u32">; +defm GLOBAL_ATOMIC_DEC : GLOBAL_Real_Atomics_gfx11<0x040, "global_atomic_dec_u32">; +defm GLOBAL_ATOMIC_SWAP_X2 : GLOBAL_Real_Atomics_gfx11<0x041, "global_atomic_swap_b64">; +defm GLOBAL_ATOMIC_CMPSWAP_X2 : GLOBAL_Real_Atomics_gfx11<0x042, "global_atomic_cmpswap_b64">; +defm GLOBAL_ATOMIC_ADD_X2 : GLOBAL_Real_Atomics_gfx11<0x043, "global_atomic_add_u64">; +defm GLOBAL_ATOMIC_SUB_X2 : GLOBAL_Real_Atomics_gfx11<0x044, "global_atomic_sub_u64">; +defm GLOBAL_ATOMIC_SMIN_X2 : GLOBAL_Real_Atomics_gfx11<0x045, "global_atomic_min_i64">; +defm GLOBAL_ATOMIC_UMIN_X2 : GLOBAL_Real_Atomics_gfx11<0x046, "global_atomic_min_u64">; +defm GLOBAL_ATOMIC_SMAX_X2 : GLOBAL_Real_Atomics_gfx11<0x047, "global_atomic_max_i64">; +defm GLOBAL_ATOMIC_UMAX_X2 : GLOBAL_Real_Atomics_gfx11<0x048, "global_atomic_max_u64">; +defm GLOBAL_ATOMIC_AND_X2 : GLOBAL_Real_Atomics_gfx11<0x049, "global_atomic_and_b64">; +defm GLOBAL_ATOMIC_OR_X2 : GLOBAL_Real_Atomics_gfx11<0x04a, "global_atomic_or_b64">; +defm GLOBAL_ATOMIC_XOR_X2 : GLOBAL_Real_Atomics_gfx11<0x04b, "global_atomic_xor_b64">; +defm GLOBAL_ATOMIC_INC_X2 : GLOBAL_Real_Atomics_gfx11<0x04c, "global_atomic_inc_u64">; +defm GLOBAL_ATOMIC_DEC_X2 : GLOBAL_Real_Atomics_gfx11<0x04d, "global_atomic_dec_u64">; +defm GLOBAL_ATOMIC_FCMPSWAP : GLOBAL_Real_Atomics_gfx11<0x050, "global_atomic_cmpswap_f32">; +defm GLOBAL_ATOMIC_FMIN : GLOBAL_Real_Atomics_gfx11<0x051, "global_atomic_min_f32">; +defm GLOBAL_ATOMIC_FMAX : GLOBAL_Real_Atomics_gfx11<0x052, "global_atomic_max_f32">; +defm GLOBAL_ATOMIC_ADD_F32 : GLOBAL_Real_Atomics_gfx11<0x056>; // ENC_FLAT_SCRATCH. -defm SCRATCH_LOAD_U8 : FLAT_Real_ScratchAllAddr_gfx11<0x10, "SCRATCH_LOAD_UBYTE", "scratch_load_u8", true>; -defm SCRATCH_LOAD_I8 : FLAT_Real_ScratchAllAddr_gfx11<0x11, "SCRATCH_LOAD_SBYTE", "scratch_load_i8", true>; -defm SCRATCH_LOAD_U16 : FLAT_Real_ScratchAllAddr_gfx11<0x12, "SCRATCH_LOAD_USHORT", "scratch_load_u16", true>; -defm SCRATCH_LOAD_I16 : FLAT_Real_ScratchAllAddr_gfx11<0x13, "SCRATCH_LOAD_SSHORT", "scratch_load_i16", true>; -defm SCRATCH_LOAD_B32 : FLAT_Real_ScratchAllAddr_gfx11<0x14, "SCRATCH_LOAD_DWORD", "scratch_load_b32", true>; -defm SCRATCH_LOAD_B64 : FLAT_Real_ScratchAllAddr_gfx11<0x15, "SCRATCH_LOAD_DWORDX2", "scratch_load_b64", true>; -defm SCRATCH_LOAD_B96 : FLAT_Real_ScratchAllAddr_gfx11<0x16, "SCRATCH_LOAD_DWORDX3", "scratch_load_b96", true>; -defm SCRATCH_LOAD_B128 : FLAT_Real_ScratchAllAddr_gfx11<0x17, "SCRATCH_LOAD_DWORDX4", "scratch_load_b128", true>; -defm SCRATCH_STORE_B8 : FLAT_Real_ScratchAllAddr_gfx11<0x18, "SCRATCH_STORE_BYTE", "scratch_store_b8", true>; -defm SCRATCH_STORE_B16 : FLAT_Real_ScratchAllAddr_gfx11<0x19, "SCRATCH_STORE_SHORT", "scratch_store_b16", true>; -defm SCRATCH_STORE_B32 : FLAT_Real_ScratchAllAddr_gfx11<0x1a, "SCRATCH_STORE_DWORD", "scratch_store_b32", true>; -defm SCRATCH_STORE_B64 : FLAT_Real_ScratchAllAddr_gfx11<0x1b, "SCRATCH_STORE_DWORDX2", "scratch_store_b64", true>; -defm SCRATCH_STORE_B96 : FLAT_Real_ScratchAllAddr_gfx11<0x1c, "SCRATCH_STORE_DWORDX3", "scratch_store_b96", true>; -defm SCRATCH_STORE_B128 : FLAT_Real_ScratchAllAddr_gfx11<0x1d, "SCRATCH_STORE_DWORDX4", "scratch_store_b128", true>; -defm SCRATCH_LOAD_D16_U8 : FLAT_Real_ScratchAllAddr_gfx11<0x1e, "SCRATCH_LOAD_UBYTE_D16", "scratch_load_d16_u8">; -defm SCRATCH_LOAD_D16_I8 : FLAT_Real_ScratchAllAddr_gfx11<0x1f, "SCRATCH_LOAD_SBYTE_D16", "scratch_load_d16_i8">; -defm SCRATCH_LOAD_D16_B16 : FLAT_Real_ScratchAllAddr_gfx11<0x20, "SCRATCH_LOAD_SHORT_D16", "scratch_load_d16_b16">; -defm SCRATCH_LOAD_D16_HI_U8 : FLAT_Real_ScratchAllAddr_gfx11<0x21, "SCRATCH_LOAD_UBYTE_D16_HI", "scratch_load_d16_hi_u8">; -defm SCRATCH_LOAD_D16_HI_I8 : FLAT_Real_ScratchAllAddr_gfx11<0x22, "SCRATCH_LOAD_SBYTE_D16_HI", "scratch_load_d16_hi_i8">; -defm SCRATCH_LOAD_D16_HI_B16 : FLAT_Real_ScratchAllAddr_gfx11<0x23, "SCRATCH_LOAD_SHORT_D16_HI", "scratch_load_d16_hi_b16">; -defm SCRATCH_STORE_D16_HI_B8 : FLAT_Real_ScratchAllAddr_gfx11<0x24, "SCRATCH_STORE_BYTE_D16_HI", "scratch_store_d16_hi_b8">; -defm SCRATCH_STORE_D16_HI_B16 : FLAT_Real_ScratchAllAddr_gfx11<0x25, "SCRATCH_STORE_SHORT_D16_HI", "scratch_store_d16_hi_b16">; +defm SCRATCH_LOAD_UBYTE : SCRATCH_Real_AllAddr_gfx11<0x10, "scratch_load_u8">; +defm SCRATCH_LOAD_SBYTE : SCRATCH_Real_AllAddr_gfx11<0x11, "scratch_load_i8">; +defm SCRATCH_LOAD_USHORT : SCRATCH_Real_AllAddr_gfx11<0x12, "scratch_load_u16">; +defm SCRATCH_LOAD_SSHORT : SCRATCH_Real_AllAddr_gfx11<0x13, "scratch_load_i16">; +defm SCRATCH_LOAD_DWORD : SCRATCH_Real_AllAddr_gfx11<0x14, "scratch_load_b32">; +defm SCRATCH_LOAD_DWORDX2 : SCRATCH_Real_AllAddr_gfx11<0x15, "scratch_load_b64">; +defm SCRATCH_LOAD_DWORDX3 : SCRATCH_Real_AllAddr_gfx11<0x16, "scratch_load_b96">; +defm SCRATCH_LOAD_DWORDX4 : SCRATCH_Real_AllAddr_gfx11<0x17, "scratch_load_b128">; +defm SCRATCH_STORE_BYTE : SCRATCH_Real_AllAddr_gfx11<0x18, "scratch_store_b8">; +defm SCRATCH_STORE_SHORT : SCRATCH_Real_AllAddr_gfx11<0x19, "scratch_store_b16">; +defm SCRATCH_STORE_DWORD : SCRATCH_Real_AllAddr_gfx11<0x1a, "scratch_store_b32">; +defm SCRATCH_STORE_DWORDX2 : SCRATCH_Real_AllAddr_gfx11<0x1b, "scratch_store_b64">; +defm SCRATCH_STORE_DWORDX3 : SCRATCH_Real_AllAddr_gfx11<0x1c, "scratch_store_b96">; +defm SCRATCH_STORE_DWORDX4 : SCRATCH_Real_AllAddr_gfx11<0x1d, "scratch_store_b128">; +defm SCRATCH_LOAD_UBYTE_D16 : SCRATCH_Real_AllAddr_gfx11<0x1e, "scratch_load_d16_u8">; +defm SCRATCH_LOAD_SBYTE_D16 : SCRATCH_Real_AllAddr_gfx11<0x1f, "scratch_load_d16_i8">; +defm SCRATCH_LOAD_SHORT_D16 : SCRATCH_Real_AllAddr_gfx11<0x20, "scratch_load_d16_b16">; +defm SCRATCH_LOAD_UBYTE_D16_HI : SCRATCH_Real_AllAddr_gfx11<0x21, "scratch_load_d16_hi_u8">; +defm SCRATCH_LOAD_SBYTE_D16_HI : SCRATCH_Real_AllAddr_gfx11<0x22, "scratch_load_d16_hi_i8">; +defm SCRATCH_LOAD_SHORT_D16_HI : SCRATCH_Real_AllAddr_gfx11<0x23, "scratch_load_d16_hi_b16">; +defm SCRATCH_STORE_BYTE_D16_HI : SCRATCH_Real_AllAddr_gfx11<0x24, "scratch_store_d16_hi_b8">; +defm SCRATCH_STORE_SHORT_D16_HI : SCRATCH_Real_AllAddr_gfx11<0x25, "scratch_store_d16_hi_b16">; //===----------------------------------------------------------------------===// // GFX12 //===----------------------------------------------------------------------===// -class VFLAT_Real_gfx12 <bits<8> op, FLAT_Pseudo ps, - string opName = ps.Mnemonic> : - VFLAT_Real <op, ps, opName>, - SIMCInstr <ps.PseudoInstr, SIEncodingFamily.GFX12> { - let AssemblerPredicate = isGFX12Plus; - let DecoderNamespace = "GFX12"; +multiclass VFLAT_Real_gfx12 <bits<8> op, string name = get_FLAT_ps<NAME>.Mnemonic> { + defvar ps = !cast<FLAT_Pseudo>(NAME); + def _gfx12 : VFLAT_Real <op, ps, name>, + SIMCInstr <ps.PseudoInstr, SIEncodingFamily.GFX12> { + let AssemblerPredicate = isGFX12Only; + let DecoderNamespace = "GFX12"; - let Inst{25-24} = {ps.is_flat_global, ps.is_flat_scratch}; + let Inst{25-24} = {ps.is_flat_global, ps.is_flat_scratch}; + } } -multiclass VFLAT_Aliases_gfx12<string ps, string opName, int renamed, string alias> { - if renamed then - def _renamed_gfx12 : MnemonicAlias<!cast<FLAT_Pseudo>(ps).Mnemonic, opName>, Requires<[isGFX12Plus]>; - if !not(!empty(alias)) then - def _alias_gfx12 : MnemonicAlias<alias, opName>, Requires<[isGFX12Plus]>; +multiclass VFLAT_Aliases_gfx12<string name, string alias = name> { + defvar ps = get_FLAT_ps<NAME>; + if !ne(ps.Mnemonic, name) then + def : MnemonicAlias<ps.Mnemonic, name>, Requires<[isGFX12Only]>; + if !ne(alias, name) then + def : MnemonicAlias<alias, name>, Requires<[isGFX12Only]>; } -multiclass VFLAT_Real_Base_gfx12<bits<8> op, string ps = NAME, string opName = !tolower(NAME), - int renamed = false, string alias = ""> : - VFLAT_Aliases_gfx12<ps, opName, renamed, alias> { - def _gfx12 : VFLAT_Real_gfx12<op, !cast<FLAT_Pseudo>(ps), opName>; -} +multiclass VFLAT_Real_Base_gfx12<bits<8> op, + string name = get_FLAT_ps<NAME>.Mnemonic, + string alias = name> : + VFLAT_Aliases_gfx12<name, alias>, + VFLAT_Real_gfx12<op, name>; -multiclass VFLAT_Real_RTN_gfx12<bits<8> op, string ps, string opName> { - def _RTN_gfx12 : VFLAT_Real_gfx12<op, !cast<FLAT_Pseudo>(ps#"_RTN"), opName>; +multiclass VFLAT_Real_Atomics_gfx12<bits<8> op, + string name = get_FLAT_ps<NAME>.Mnemonic, + string alias = ""> : + VFLAT_Real_Base_gfx12<op, name, alias> { + defm _RTN : VFLAT_Real_gfx12<op, name>; } -multiclass VFLAT_Real_SADDR_gfx12<bits<8> op, string ps, string opName> { - def _SADDR_gfx12 : VFLAT_Real_gfx12<op, !cast<FLAT_Pseudo>(ps#"_SADDR"), opName>; +multiclass VGLOBAL_Real_AllAddr_gfx12<bits<8> op, + string name = get_FLAT_ps<NAME>.Mnemonic, + string alias = name> : + VFLAT_Aliases_gfx12<name, alias>, + VFLAT_Real_gfx12<op, name> { + defm _SADDR : VFLAT_Real_gfx12<op, name>; } -multiclass VFLAT_Real_SADDR_RTN_gfx12<bits<8> op, string ps, string opName> { - def _SADDR_RTN_gfx12 : VFLAT_Real_gfx12<op, !cast<FLAT_Pseudo>(ps#"_SADDR_RTN"), opName>; +multiclass VGLOBAL_Real_AllAddr_gfx12_w64<bits<8> op, + string name = get_FLAT_ps<NAME>.Mnemonic> : + VFLAT_Aliases_gfx12<name> { + let DecoderNamespace = "GFX12W64" in { + defm "" : VFLAT_Real_gfx12<op, name>; + defm _SADDR : VFLAT_Real_gfx12<op, name>; + } } -multiclass VFLAT_Real_ST_gfx12<bits<8> op, string ps, string opName> { - def _ST_gfx12 : VFLAT_Real_gfx12<op, !cast<FLAT_Pseudo>(ps#"_ST"), opName>; +multiclass VGLOBAL_Real_Atomics_gfx12<bits<8> op, + string name = get_FLAT_ps<NAME>.Mnemonic, + string alias = ""> : + VGLOBAL_Real_AllAddr_gfx12<op, name, alias> { + defm _RTN : VFLAT_Real_gfx12<op, name>; + defm _SADDR_RTN : VFLAT_Real_gfx12<op, name>; } -multiclass VFLAT_Real_SVS_gfx12<bits<8> op, string ps, string opName> { - def _SVS_gfx12 : VFLAT_Real_gfx12<op, !cast<FLAT_Pseudo>(ps#"_SVS"), opName>; +multiclass VSCRATCH_Real_AllAddr_gfx12<bits<8> op, + string name = get_FLAT_ps<NAME>.Mnemonic> : + VFLAT_Aliases_gfx12<name>, + VFLAT_Real_gfx12<op, name> { + defm _SADDR : VFLAT_Real_gfx12<op, name>; + defm _ST : VFLAT_Real_gfx12<op, name>; + defm _SVS : VFLAT_Real_gfx12<op, name>; } -multiclass VFLAT_Real_Atomics_gfx12<bits<8> op, string ps = NAME, string opName = !tolower(NAME), - int renamed = false, string alias = ""> : - VFLAT_Real_Base_gfx12<op, ps, opName, renamed, alias>, - VFLAT_Real_RTN_gfx12<op, ps, opName>; - -multiclass VGLOBAL_Real_AllAddr_gfx12<bits<8> op, string ps = NAME, string opName = !tolower(NAME), - int renamed = false, string alias = ""> : - VFLAT_Real_Base_gfx12<op, ps, opName, renamed, alias>, - VFLAT_Real_SADDR_gfx12<op, ps, opName>; - -multiclass VGLOBAL_Real_Atomics_gfx12<bits<8> op, string ps = NAME, string opName = !tolower(NAME), - int renamed = false, string alias = ""> : - VGLOBAL_Real_AllAddr_gfx12<op, ps, opName, renamed, alias>, - VFLAT_Real_RTN_gfx12<op, ps, opName>, - VFLAT_Real_SADDR_RTN_gfx12<op, ps, opName>; - -multiclass VSCRATCH_Real_AllAddr_gfx12<bits<8> op, string ps = NAME, string opName = !tolower(NAME), - int renamed = false> : - VFLAT_Real_Base_gfx12<op, ps, opName, renamed>, - VFLAT_Real_SADDR_gfx12<op, ps, opName>, - VFLAT_Real_ST_gfx12<op, ps, opName>, - VFLAT_Real_SVS_gfx12<op, ps, opName>; - // ENC_VFLAT. -defm FLAT_LOAD_U8 : VFLAT_Real_Base_gfx12<0x010, "FLAT_LOAD_UBYTE", "flat_load_u8", true>; -defm FLAT_LOAD_I8 : VFLAT_Real_Base_gfx12<0x011, "FLAT_LOAD_SBYTE", "flat_load_i8", true>; -defm FLAT_LOAD_U16 : VFLAT_Real_Base_gfx12<0x012, "FLAT_LOAD_USHORT", "flat_load_u16", true>; -defm FLAT_LOAD_I16 : VFLAT_Real_Base_gfx12<0x013, "FLAT_LOAD_SSHORT", "flat_load_i16", true>; -defm FLAT_LOAD_B32 : VFLAT_Real_Base_gfx12<0x014, "FLAT_LOAD_DWORD", "flat_load_b32", true>; -defm FLAT_LOAD_B64 : VFLAT_Real_Base_gfx12<0x015, "FLAT_LOAD_DWORDX2", "flat_load_b64", true>; -defm FLAT_LOAD_B96 : VFLAT_Real_Base_gfx12<0x016, "FLAT_LOAD_DWORDX3", "flat_load_b96", true>; -defm FLAT_LOAD_B128 : VFLAT_Real_Base_gfx12<0x017, "FLAT_LOAD_DWORDX4", "flat_load_b128", true>; -defm FLAT_STORE_B8 : VFLAT_Real_Base_gfx12<0x018, "FLAT_STORE_BYTE", "flat_store_b8", true>; -defm FLAT_STORE_B16 : VFLAT_Real_Base_gfx12<0x019, "FLAT_STORE_SHORT", "flat_store_b16", true>; -defm FLAT_STORE_B32 : VFLAT_Real_Base_gfx12<0x01a, "FLAT_STORE_DWORD", "flat_store_b32", true>; -defm FLAT_STORE_B64 : VFLAT_Real_Base_gfx12<0x01b, "FLAT_STORE_DWORDX2", "flat_store_b64", true>; -defm FLAT_STORE_B96 : VFLAT_Real_Base_gfx12<0x01c, "FLAT_STORE_DWORDX3", "flat_store_b96", true>; -defm FLAT_STORE_B128 : VFLAT_Real_Base_gfx12<0x01d, "FLAT_STORE_DWORDX4", "flat_store_b128", true>; -defm FLAT_LOAD_D16_U8 : VFLAT_Real_Base_gfx12<0x01e, "FLAT_LOAD_UBYTE_D16">; -defm FLAT_LOAD_D16_I8 : VFLAT_Real_Base_gfx12<0x01f, "FLAT_LOAD_SBYTE_D16">; -defm FLAT_LOAD_D16_B16 : VFLAT_Real_Base_gfx12<0x020, "FLAT_LOAD_SHORT_D16">; -defm FLAT_LOAD_D16_HI_U8 : VFLAT_Real_Base_gfx12<0x021, "FLAT_LOAD_UBYTE_D16_HI">; -defm FLAT_LOAD_D16_HI_I8 : VFLAT_Real_Base_gfx12<0x022, "FLAT_LOAD_SBYTE_D16_HI">; -defm FLAT_LOAD_D16_HI_B16 : VFLAT_Real_Base_gfx12<0x023, "FLAT_LOAD_SHORT_D16_HI">; -defm FLAT_STORE_D16_HI_B8 : VFLAT_Real_Base_gfx12<0x024, "FLAT_STORE_BYTE_D16_HI">; -defm FLAT_STORE_D16_HI_B16 : VFLAT_Real_Base_gfx12<0x025, "FLAT_STORE_SHORT_D16_HI">; -defm FLAT_ATOMIC_SWAP_B32 : VFLAT_Real_Atomics_gfx12<0x033, "FLAT_ATOMIC_SWAP", "flat_atomic_swap_b32", true>; -defm FLAT_ATOMIC_CMPSWAP_B32 : VFLAT_Real_Atomics_gfx12<0x034, "FLAT_ATOMIC_CMPSWAP", "flat_atomic_cmpswap_b32", true>; -defm FLAT_ATOMIC_ADD_U32 : VFLAT_Real_Atomics_gfx12<0x035, "FLAT_ATOMIC_ADD", "flat_atomic_add_u32", true>; -defm FLAT_ATOMIC_SUB_U32 : VFLAT_Real_Atomics_gfx12<0x036, "FLAT_ATOMIC_SUB", "flat_atomic_sub_u32", true>; -defm FLAT_ATOMIC_SUB_CLAMP_U32 : VFLAT_Real_Atomics_gfx12<0x037, "FLAT_ATOMIC_CSUB_U32", "flat_atomic_sub_clamp_u32", true>; -defm FLAT_ATOMIC_MIN_I32 : VFLAT_Real_Atomics_gfx12<0x038, "FLAT_ATOMIC_SMIN", "flat_atomic_min_i32", true>; -defm FLAT_ATOMIC_MIN_U32 : VFLAT_Real_Atomics_gfx12<0x039, "FLAT_ATOMIC_UMIN", "flat_atomic_min_u32", true>; -defm FLAT_ATOMIC_MAX_I32 : VFLAT_Real_Atomics_gfx12<0x03a, "FLAT_ATOMIC_SMAX", "flat_atomic_max_i32", true>; -defm FLAT_ATOMIC_MAX_U32 : VFLAT_Real_Atomics_gfx12<0x03b, "FLAT_ATOMIC_UMAX", "flat_atomic_max_u32", true>; -defm FLAT_ATOMIC_AND_B32 : VFLAT_Real_Atomics_gfx12<0x03c, "FLAT_ATOMIC_AND", "flat_atomic_and_b32", true>; -defm FLAT_ATOMIC_OR_B32 : VFLAT_Real_Atomics_gfx12<0x03d, "FLAT_ATOMIC_OR", "flat_atomic_or_b32", true>; -defm FLAT_ATOMIC_XOR_B32 : VFLAT_Real_Atomics_gfx12<0x03e, "FLAT_ATOMIC_XOR", "flat_atomic_xor_b32", true>; -defm FLAT_ATOMIC_INC_U32 : VFLAT_Real_Atomics_gfx12<0x03f, "FLAT_ATOMIC_INC", "flat_atomic_inc_u32", true>; -defm FLAT_ATOMIC_DEC_U32 : VFLAT_Real_Atomics_gfx12<0x040, "FLAT_ATOMIC_DEC", "flat_atomic_dec_u32", true>; -defm FLAT_ATOMIC_SWAP_B64 : VFLAT_Real_Atomics_gfx12<0x041, "FLAT_ATOMIC_SWAP_X2", "flat_atomic_swap_b64", true>; -defm FLAT_ATOMIC_CMPSWAP_B64 : VFLAT_Real_Atomics_gfx12<0x042, "FLAT_ATOMIC_CMPSWAP_X2", "flat_atomic_cmpswap_b64", true>; -defm FLAT_ATOMIC_ADD_U64 : VFLAT_Real_Atomics_gfx12<0x043, "FLAT_ATOMIC_ADD_X2", "flat_atomic_add_u64", true>; -defm FLAT_ATOMIC_SUB_U64 : VFLAT_Real_Atomics_gfx12<0x044, "FLAT_ATOMIC_SUB_X2", "flat_atomic_sub_u64", true>; -defm FLAT_ATOMIC_MIN_I64 : VFLAT_Real_Atomics_gfx12<0x045, "FLAT_ATOMIC_SMIN_X2", "flat_atomic_min_i64", true>; -defm FLAT_ATOMIC_MIN_U64 : VFLAT_Real_Atomics_gfx12<0x046, "FLAT_ATOMIC_UMIN_X2", "flat_atomic_min_u64", true>; -defm FLAT_ATOMIC_MAX_I64 : VFLAT_Real_Atomics_gfx12<0x047, "FLAT_ATOMIC_SMAX_X2", "flat_atomic_max_i64", true>; -defm FLAT_ATOMIC_MAX_U64 : VFLAT_Real_Atomics_gfx12<0x048, "FLAT_ATOMIC_UMAX_X2", "flat_atomic_max_u64", true>; -defm FLAT_ATOMIC_AND_B64 : VFLAT_Real_Atomics_gfx12<0x049, "FLAT_ATOMIC_AND_X2", "flat_atomic_and_b64", true>; -defm FLAT_ATOMIC_OR_B64 : VFLAT_Real_Atomics_gfx12<0x04a, "FLAT_ATOMIC_OR_X2", "flat_atomic_or_b64", true>; -defm FLAT_ATOMIC_XOR_B64 : VFLAT_Real_Atomics_gfx12<0x04b, "FLAT_ATOMIC_XOR_X2", "flat_atomic_xor_b64", true>; -defm FLAT_ATOMIC_INC_U64 : VFLAT_Real_Atomics_gfx12<0x04c, "FLAT_ATOMIC_INC_X2", "flat_atomic_inc_u64", true>; -defm FLAT_ATOMIC_DEC_U64 : VFLAT_Real_Atomics_gfx12<0x04d, "FLAT_ATOMIC_DEC_X2", "flat_atomic_dec_u64", true>; -defm FLAT_ATOMIC_COND_SUB_U32 : VFLAT_Real_Atomics_gfx12<0x050, "FLAT_ATOMIC_COND_SUB_U32", "flat_atomic_cond_sub_u32">; -defm FLAT_ATOMIC_MIN_NUM_F32 : VFLAT_Real_Atomics_gfx12<0x051, "FLAT_ATOMIC_FMIN", "flat_atomic_min_num_f32", true, "flat_atomic_min_f32">; -defm FLAT_ATOMIC_MAX_NUM_F32 : VFLAT_Real_Atomics_gfx12<0x052, "FLAT_ATOMIC_FMAX", "flat_atomic_max_num_f32", true, "flat_atomic_max_f32">; +defm FLAT_LOAD_UBYTE : VFLAT_Real_Base_gfx12<0x010, "flat_load_u8">; +defm FLAT_LOAD_SBYTE : VFLAT_Real_Base_gfx12<0x011, "flat_load_i8">; +defm FLAT_LOAD_USHORT : VFLAT_Real_Base_gfx12<0x012, "flat_load_u16">; +defm FLAT_LOAD_SSHORT : VFLAT_Real_Base_gfx12<0x013, "flat_load_i16">; +defm FLAT_LOAD_DWORD : VFLAT_Real_Base_gfx12<0x014, "flat_load_b32">; +defm FLAT_LOAD_DWORDX2 : VFLAT_Real_Base_gfx12<0x015, "flat_load_b64">; +defm FLAT_LOAD_DWORDX3 : VFLAT_Real_Base_gfx12<0x016, "flat_load_b96">; +defm FLAT_LOAD_DWORDX4 : VFLAT_Real_Base_gfx12<0x017, "flat_load_b128">; +defm FLAT_STORE_BYTE : VFLAT_Real_Base_gfx12<0x018, "flat_store_b8">; +defm FLAT_STORE_SHORT : VFLAT_Real_Base_gfx12<0x019, "flat_store_b16">; +defm FLAT_STORE_DWORD : VFLAT_Real_Base_gfx12<0x01a, "flat_store_b32">; +defm FLAT_STORE_DWORDX2 : VFLAT_Real_Base_gfx12<0x01b, "flat_store_b64">; +defm FLAT_STORE_DWORDX3 : VFLAT_Real_Base_gfx12<0x01c, "flat_store_b96">; +defm FLAT_STORE_DWORDX4 : VFLAT_Real_Base_gfx12<0x01d, "flat_store_b128">; +defm FLAT_LOAD_UBYTE_D16 : VFLAT_Real_Base_gfx12<0x01e, "flat_load_d16_u8">; +defm FLAT_LOAD_SBYTE_D16 : VFLAT_Real_Base_gfx12<0x01f, "flat_load_d16_i8">; +defm FLAT_LOAD_SHORT_D16 : VFLAT_Real_Base_gfx12<0x020, "flat_load_d16_b16">; +defm FLAT_LOAD_UBYTE_D16_HI : VFLAT_Real_Base_gfx12<0x021, "flat_load_d16_hi_u8">; +defm FLAT_LOAD_SBYTE_D16_HI : VFLAT_Real_Base_gfx12<0x022, "flat_load_d16_hi_i8">; +defm FLAT_LOAD_SHORT_D16_HI : VFLAT_Real_Base_gfx12<0x023, "flat_load_d16_hi_b16">; +defm FLAT_STORE_BYTE_D16_HI : VFLAT_Real_Base_gfx12<0x024, "flat_store_d16_hi_b8">; +defm FLAT_STORE_SHORT_D16_HI : VFLAT_Real_Base_gfx12<0x025, "flat_store_d16_hi_b16">; +defm FLAT_ATOMIC_SWAP : VFLAT_Real_Atomics_gfx12<0x033, "flat_atomic_swap_b32">; +defm FLAT_ATOMIC_CMPSWAP : VFLAT_Real_Atomics_gfx12<0x034, "flat_atomic_cmpswap_b32">; +defm FLAT_ATOMIC_ADD : VFLAT_Real_Atomics_gfx12<0x035, "flat_atomic_add_u32">; +defm FLAT_ATOMIC_SUB : VFLAT_Real_Atomics_gfx12<0x036, "flat_atomic_sub_u32">; +defm FLAT_ATOMIC_CSUB_U32 : VFLAT_Real_Atomics_gfx12<0x037, "flat_atomic_sub_clamp_u32">; +defm FLAT_ATOMIC_SMIN : VFLAT_Real_Atomics_gfx12<0x038, "flat_atomic_min_i32">; +defm FLAT_ATOMIC_UMIN : VFLAT_Real_Atomics_gfx12<0x039, "flat_atomic_min_u32">; +defm FLAT_ATOMIC_SMAX : VFLAT_Real_Atomics_gfx12<0x03a, "flat_atomic_max_i32">; +defm FLAT_ATOMIC_UMAX : VFLAT_Real_Atomics_gfx12<0x03b, "flat_atomic_max_u32">; +defm FLAT_ATOMIC_AND : VFLAT_Real_Atomics_gfx12<0x03c, "flat_atomic_and_b32">; +defm FLAT_ATOMIC_OR : VFLAT_Real_Atomics_gfx12<0x03d, "flat_atomic_or_b32">; +defm FLAT_ATOMIC_XOR : VFLAT_Real_Atomics_gfx12<0x03e, "flat_atomic_xor_b32">; +defm FLAT_ATOMIC_INC : VFLAT_Real_Atomics_gfx12<0x03f, "flat_atomic_inc_u32">; +defm FLAT_ATOMIC_DEC : VFLAT_Real_Atomics_gfx12<0x040, "flat_atomic_dec_u32">; +defm FLAT_ATOMIC_SWAP_X2 : VFLAT_Real_Atomics_gfx12<0x041, "flat_atomic_swap_b64">; +defm FLAT_ATOMIC_CMPSWAP_X2 : VFLAT_Real_Atomics_gfx12<0x042, "flat_atomic_cmpswap_b64">; +defm FLAT_ATOMIC_ADD_X2 : VFLAT_Real_Atomics_gfx12<0x043, "flat_atomic_add_u64">; +defm FLAT_ATOMIC_SUB_X2 : VFLAT_Real_Atomics_gfx12<0x044, "flat_atomic_sub_u64">; +defm FLAT_ATOMIC_SMIN_X2 : VFLAT_Real_Atomics_gfx12<0x045, "flat_atomic_min_i64">; +defm FLAT_ATOMIC_UMIN_X2 : VFLAT_Real_Atomics_gfx12<0x046, "flat_atomic_min_u64">; +defm FLAT_ATOMIC_SMAX_X2 : VFLAT_Real_Atomics_gfx12<0x047, "flat_atomic_max_i64">; +defm FLAT_ATOMIC_UMAX_X2 : VFLAT_Real_Atomics_gfx12<0x048, "flat_atomic_max_u64">; +defm FLAT_ATOMIC_AND_X2 : VFLAT_Real_Atomics_gfx12<0x049, "flat_atomic_and_b64">; +defm FLAT_ATOMIC_OR_X2 : VFLAT_Real_Atomics_gfx12<0x04a, "flat_atomic_or_b64">; +defm FLAT_ATOMIC_XOR_X2 : VFLAT_Real_Atomics_gfx12<0x04b, "flat_atomic_xor_b64">; +defm FLAT_ATOMIC_INC_X2 : VFLAT_Real_Atomics_gfx12<0x04c, "flat_atomic_inc_u64">; +defm FLAT_ATOMIC_DEC_X2 : VFLAT_Real_Atomics_gfx12<0x04d, "flat_atomic_dec_u64">; +defm FLAT_ATOMIC_COND_SUB_U32 : VFLAT_Real_Atomics_gfx12<0x050>; +defm FLAT_ATOMIC_FMIN : VFLAT_Real_Atomics_gfx12<0x051, "flat_atomic_min_num_f32", "flat_atomic_min_f32">; +defm FLAT_ATOMIC_FMAX : VFLAT_Real_Atomics_gfx12<0x052, "flat_atomic_max_num_f32", "flat_atomic_max_f32">; defm FLAT_ATOMIC_ADD_F32 : VFLAT_Real_Atomics_gfx12<0x056>; defm FLAT_ATOMIC_PK_ADD_F16 : VFLAT_Real_Atomics_gfx12<0x059>; defm FLAT_ATOMIC_PK_ADD_BF16 : VFLAT_Real_Atomics_gfx12<0x05a>; // ENC_VGLOBAL. -defm GLOBAL_LOAD_U8 : VGLOBAL_Real_AllAddr_gfx12<0x010, "GLOBAL_LOAD_UBYTE", "global_load_u8", true>; -defm GLOBAL_LOAD_I8 : VGLOBAL_Real_AllAddr_gfx12<0x011, "GLOBAL_LOAD_SBYTE", "global_load_i8", true>; -defm GLOBAL_LOAD_U16 : VGLOBAL_Real_AllAddr_gfx12<0x012, "GLOBAL_LOAD_USHORT", "global_load_u16", true>; -defm GLOBAL_LOAD_I16 : VGLOBAL_Real_AllAddr_gfx12<0x013, "GLOBAL_LOAD_SSHORT", "global_load_i16", true>; -defm GLOBAL_LOAD_B32 : VGLOBAL_Real_AllAddr_gfx12<0x014, "GLOBAL_LOAD_DWORD", "global_load_b32", true>; -defm GLOBAL_LOAD_B64 : VGLOBAL_Real_AllAddr_gfx12<0x015, "GLOBAL_LOAD_DWORDX2", "global_load_b64", true>; -defm GLOBAL_LOAD_B96 : VGLOBAL_Real_AllAddr_gfx12<0x016, "GLOBAL_LOAD_DWORDX3", "global_load_b96", true>; -defm GLOBAL_LOAD_B128 : VGLOBAL_Real_AllAddr_gfx12<0x017, "GLOBAL_LOAD_DWORDX4", "global_load_b128", true>; -defm GLOBAL_STORE_B8 : VGLOBAL_Real_AllAddr_gfx12<0x018, "GLOBAL_STORE_BYTE", "global_store_b8", true>; -defm GLOBAL_STORE_B16 : VGLOBAL_Real_AllAddr_gfx12<0x019, "GLOBAL_STORE_SHORT", "global_store_b16", true>; -defm GLOBAL_STORE_B32 : VGLOBAL_Real_AllAddr_gfx12<0x01a, "GLOBAL_STORE_DWORD", "global_store_b32", true>; -defm GLOBAL_STORE_B64 : VGLOBAL_Real_AllAddr_gfx12<0x01b, "GLOBAL_STORE_DWORDX2", "global_store_b64", true>; -defm GLOBAL_STORE_B96 : VGLOBAL_Real_AllAddr_gfx12<0x01c, "GLOBAL_STORE_DWORDX3", "global_store_b96", true>; -defm GLOBAL_STORE_B128 : VGLOBAL_Real_AllAddr_gfx12<0x01d, "GLOBAL_STORE_DWORDX4", "global_store_b128", true>; -defm GLOBAL_LOAD_D16_U8 : VGLOBAL_Real_AllAddr_gfx12<0x01e, "GLOBAL_LOAD_UBYTE_D16">; -defm GLOBAL_LOAD_D16_I8 : VGLOBAL_Real_AllAddr_gfx12<0x01f, "GLOBAL_LOAD_SBYTE_D16">; -defm GLOBAL_LOAD_D16_B16 : VGLOBAL_Real_AllAddr_gfx12<0x020, "GLOBAL_LOAD_SHORT_D16">; -defm GLOBAL_LOAD_D16_HI_U8 : VGLOBAL_Real_AllAddr_gfx12<0x021, "GLOBAL_LOAD_UBYTE_D16_HI">; -defm GLOBAL_LOAD_D16_HI_I8 : VGLOBAL_Real_AllAddr_gfx12<0x022, "GLOBAL_LOAD_SBYTE_D16_HI">; -defm GLOBAL_LOAD_D16_HI_B16 : VGLOBAL_Real_AllAddr_gfx12<0x023, "GLOBAL_LOAD_SHORT_D16_HI">; -defm GLOBAL_STORE_D16_HI_B8 : VGLOBAL_Real_AllAddr_gfx12<0x024, "GLOBAL_STORE_BYTE_D16_HI">; -defm GLOBAL_STORE_D16_HI_B16 : VGLOBAL_Real_AllAddr_gfx12<0x025, "GLOBAL_STORE_SHORT_D16_HI">; -defm GLOBAL_LOAD_ADDTID_B32 : VGLOBAL_Real_AllAddr_gfx12<0x028, "GLOBAL_LOAD_DWORD_ADDTID">; -defm GLOBAL_STORE_ADDTID_B32 : VGLOBAL_Real_AllAddr_gfx12<0x029, "GLOBAL_STORE_DWORD_ADDTID">; - -defm GLOBAL_ATOMIC_SWAP_B32 : VGLOBAL_Real_Atomics_gfx12<0x033, "GLOBAL_ATOMIC_SWAP", "global_atomic_swap_b32", true>; -defm GLOBAL_ATOMIC_CMPSWAP_B32 : VGLOBAL_Real_Atomics_gfx12<0x034, "GLOBAL_ATOMIC_CMPSWAP", "global_atomic_cmpswap_b32", true>; -defm GLOBAL_ATOMIC_ADD_U32 : VGLOBAL_Real_Atomics_gfx12<0x035, "GLOBAL_ATOMIC_ADD", "global_atomic_add_u32", true>; -defm GLOBAL_ATOMIC_SUB_U32 : VGLOBAL_Real_Atomics_gfx12<0x036, "GLOBAL_ATOMIC_SUB", "global_atomic_sub_u32", true>; -defm GLOBAL_ATOMIC_SUB_CLAMP_U32 : VGLOBAL_Real_Atomics_gfx12<0x037, "GLOBAL_ATOMIC_CSUB", "global_atomic_sub_clamp_u32", true, "global_atomic_csub_u32">; -defm GLOBAL_ATOMIC_MIN_I32 : VGLOBAL_Real_Atomics_gfx12<0x038, "GLOBAL_ATOMIC_SMIN", "global_atomic_min_i32", true>; -defm GLOBAL_ATOMIC_MIN_U32 : VGLOBAL_Real_Atomics_gfx12<0x039, "GLOBAL_ATOMIC_UMIN", "global_atomic_min_u32", true>; -defm GLOBAL_ATOMIC_MAX_I32 : VGLOBAL_Real_Atomics_gfx12<0x03a, "GLOBAL_ATOMIC_SMAX", "global_atomic_max_i32", true>; -defm GLOBAL_ATOMIC_MAX_U32 : VGLOBAL_Real_Atomics_gfx12<0x03b, "GLOBAL_ATOMIC_UMAX", "global_atomic_max_u32", true>; -defm GLOBAL_ATOMIC_AND_B32 : VGLOBAL_Real_Atomics_gfx12<0x03c, "GLOBAL_ATOMIC_AND", "global_atomic_and_b32", true>; -defm GLOBAL_ATOMIC_OR_B32 : VGLOBAL_Real_Atomics_gfx12<0x03d, "GLOBAL_ATOMIC_OR", "global_atomic_or_b32", true>; -defm GLOBAL_ATOMIC_XOR_B32 : VGLOBAL_Real_Atomics_gfx12<0x03e, "GLOBAL_ATOMIC_XOR", "global_atomic_xor_b32", true>; -defm GLOBAL_ATOMIC_INC_U32 : VGLOBAL_Real_Atomics_gfx12<0x03f, "GLOBAL_ATOMIC_INC", "global_atomic_inc_u32", true>; -defm GLOBAL_ATOMIC_DEC_U32 : VGLOBAL_Real_Atomics_gfx12<0x040, "GLOBAL_ATOMIC_DEC", "global_atomic_dec_u32", true>; -defm GLOBAL_ATOMIC_SWAP_B64 : VGLOBAL_Real_Atomics_gfx12<0x041, "GLOBAL_ATOMIC_SWAP_X2", "global_atomic_swap_b64", true>; -defm GLOBAL_ATOMIC_CMPSWAP_B64 : VGLOBAL_Real_Atomics_gfx12<0x042, "GLOBAL_ATOMIC_CMPSWAP_X2", "global_atomic_cmpswap_b64", true>; -defm GLOBAL_ATOMIC_ADD_U64 : VGLOBAL_Real_Atomics_gfx12<0x043, "GLOBAL_ATOMIC_ADD_X2", "global_atomic_add_u64", true>; -defm GLOBAL_ATOMIC_SUB_U64 : VGLOBAL_Real_Atomics_gfx12<0x044, "GLOBAL_ATOMIC_SUB_X2", "global_atomic_sub_u64", true>; -defm GLOBAL_ATOMIC_MIN_I64 : VGLOBAL_Real_Atomics_gfx12<0x045, "GLOBAL_ATOMIC_SMIN_X2", "global_atomic_min_i64", true>; -defm GLOBAL_ATOMIC_MIN_U64 : VGLOBAL_Real_Atomics_gfx12<0x046, "GLOBAL_ATOMIC_UMIN_X2", "global_atomic_min_u64", true>; -defm GLOBAL_ATOMIC_MAX_I64 : VGLOBAL_Real_Atomics_gfx12<0x047, "GLOBAL_ATOMIC_SMAX_X2", "global_atomic_max_i64", true>; -defm GLOBAL_ATOMIC_MAX_U64 : VGLOBAL_Real_Atomics_gfx12<0x048, "GLOBAL_ATOMIC_UMAX_X2", "global_atomic_max_u64", true>; -defm GLOBAL_ATOMIC_AND_B64 : VGLOBAL_Real_Atomics_gfx12<0x049, "GLOBAL_ATOMIC_AND_X2", "global_atomic_and_b64", true>; -defm GLOBAL_ATOMIC_OR_B64 : VGLOBAL_Real_Atomics_gfx12<0x04a, "GLOBAL_ATOMIC_OR_X2", "global_atomic_or_b64", true>; -defm GLOBAL_ATOMIC_XOR_B64 : VGLOBAL_Real_Atomics_gfx12<0x04b, "GLOBAL_ATOMIC_XOR_X2", "global_atomic_xor_b64", true>; -defm GLOBAL_ATOMIC_INC_U64 : VGLOBAL_Real_Atomics_gfx12<0x04c, "GLOBAL_ATOMIC_INC_X2", "global_atomic_inc_u64", true>; -defm GLOBAL_ATOMIC_DEC_U64 : VGLOBAL_Real_Atomics_gfx12<0x04d, "GLOBAL_ATOMIC_DEC_X2", "global_atomic_dec_u64", true>; -defm GLOBAL_ATOMIC_COND_SUB_U32 : VGLOBAL_Real_Atomics_gfx12<0x050, "GLOBAL_ATOMIC_COND_SUB_U32", "global_atomic_cond_sub_u32">; -defm GLOBAL_ATOMIC_MIN_NUM_F32 : VGLOBAL_Real_Atomics_gfx12<0x051, "GLOBAL_ATOMIC_FMIN", "global_atomic_min_num_f32", true, "global_atomic_min_f32">; -defm GLOBAL_ATOMIC_MAX_NUM_F32 : VGLOBAL_Real_Atomics_gfx12<0x052, "GLOBAL_ATOMIC_FMAX", "global_atomic_max_num_f32", true, "global_atomic_max_f32">; +defm GLOBAL_LOAD_UBYTE : VGLOBAL_Real_AllAddr_gfx12<0x010, "global_load_u8">; +defm GLOBAL_LOAD_SBYTE : VGLOBAL_Real_AllAddr_gfx12<0x011, "global_load_i8">; +defm GLOBAL_LOAD_USHORT : VGLOBAL_Real_AllAddr_gfx12<0x012, "global_load_u16">; +defm GLOBAL_LOAD_SSHORT : VGLOBAL_Real_AllAddr_gfx12<0x013, "global_load_i16">; +defm GLOBAL_LOAD_DWORD : VGLOBAL_Real_AllAddr_gfx12<0x014, "global_load_b32">; +defm GLOBAL_LOAD_DWORDX2 : VGLOBAL_Real_AllAddr_gfx12<0x015, "global_load_b64">; +defm GLOBAL_LOAD_DWORDX3 : VGLOBAL_Real_AllAddr_gfx12<0x016, "global_load_b96">; +defm GLOBAL_LOAD_DWORDX4 : VGLOBAL_Real_AllAddr_gfx12<0x017, "global_load_b128">; +defm GLOBAL_STORE_BYTE : VGLOBAL_Real_AllAddr_gfx12<0x018, "global_store_b8">; +defm GLOBAL_STORE_SHORT : VGLOBAL_Real_AllAddr_gfx12<0x019, "global_store_b16">; +defm GLOBAL_STORE_DWORD : VGLOBAL_Real_AllAddr_gfx12<0x01a, "global_store_b32">; +defm GLOBAL_STORE_DWORDX2 : VGLOBAL_Real_AllAddr_gfx12<0x01b, "global_store_b64">; +defm GLOBAL_STORE_DWORDX3 : VGLOBAL_Real_AllAddr_gfx12<0x01c, "global_store_b96">; +defm GLOBAL_STORE_DWORDX4 : VGLOBAL_Real_AllAddr_gfx12<0x01d, "global_store_b128">; +defm GLOBAL_LOAD_UBYTE_D16 : VGLOBAL_Real_AllAddr_gfx12<0x01e, "global_load_d16_u8">; +defm GLOBAL_LOAD_SBYTE_D16 : VGLOBAL_Real_AllAddr_gfx12<0x01f, "global_load_d16_i8">; +defm GLOBAL_LOAD_SHORT_D16 : VGLOBAL_Real_AllAddr_gfx12<0x020, "global_load_d16_b16">; +defm GLOBAL_LOAD_UBYTE_D16_HI : VGLOBAL_Real_AllAddr_gfx12<0x021, "global_load_d16_hi_u8">; +defm GLOBAL_LOAD_SBYTE_D16_HI : VGLOBAL_Real_AllAddr_gfx12<0x022, "global_load_d16_hi_i8">; +defm GLOBAL_LOAD_SHORT_D16_HI : VGLOBAL_Real_AllAddr_gfx12<0x023, "global_load_d16_hi_b16">; +defm GLOBAL_STORE_BYTE_D16_HI : VGLOBAL_Real_AllAddr_gfx12<0x024, "global_store_d16_hi_b8">; +defm GLOBAL_STORE_SHORT_D16_HI : VGLOBAL_Real_AllAddr_gfx12<0x025, "global_store_d16_hi_b16">; +defm GLOBAL_LOAD_DWORD_ADDTID : VGLOBAL_Real_AllAddr_gfx12<0x028, "global_load_addtid_b32">; +defm GLOBAL_STORE_DWORD_ADDTID : VGLOBAL_Real_AllAddr_gfx12<0x029, "global_store_addtid_b32">; + +defm GLOBAL_ATOMIC_SWAP : VGLOBAL_Real_Atomics_gfx12<0x033, "global_atomic_swap_b32">; +defm GLOBAL_ATOMIC_CMPSWAP : VGLOBAL_Real_Atomics_gfx12<0x034, "global_atomic_cmpswap_b32">; +defm GLOBAL_ATOMIC_ADD : VGLOBAL_Real_Atomics_gfx12<0x035, "global_atomic_add_u32">; +defm GLOBAL_ATOMIC_SUB : VGLOBAL_Real_Atomics_gfx12<0x036, "global_atomic_sub_u32">; +defm GLOBAL_ATOMIC_CSUB : VGLOBAL_Real_Atomics_gfx12<0x037, "global_atomic_sub_clamp_u32", "global_atomic_csub_u32">; +defm GLOBAL_ATOMIC_SMIN : VGLOBAL_Real_Atomics_gfx12<0x038, "global_atomic_min_i32">; +defm GLOBAL_ATOMIC_UMIN : VGLOBAL_Real_Atomics_gfx12<0x039, "global_atomic_min_u32">; +defm GLOBAL_ATOMIC_SMAX : VGLOBAL_Real_Atomics_gfx12<0x03a, "global_atomic_max_i32">; +defm GLOBAL_ATOMIC_UMAX : VGLOBAL_Real_Atomics_gfx12<0x03b, "global_atomic_max_u32">; +defm GLOBAL_ATOMIC_AND : VGLOBAL_Real_Atomics_gfx12<0x03c, "global_atomic_and_b32">; +defm GLOBAL_ATOMIC_OR : VGLOBAL_Real_Atomics_gfx12<0x03d, "global_atomic_or_b32">; +defm GLOBAL_ATOMIC_XOR : VGLOBAL_Real_Atomics_gfx12<0x03e, "global_atomic_xor_b32">; +defm GLOBAL_ATOMIC_INC : VGLOBAL_Real_Atomics_gfx12<0x03f, "global_atomic_inc_u32">; +defm GLOBAL_ATOMIC_DEC : VGLOBAL_Real_Atomics_gfx12<0x040, "global_atomic_dec_u32">; +defm GLOBAL_ATOMIC_SWAP_X2 : VGLOBAL_Real_Atomics_gfx12<0x041, "global_atomic_swap_b64">; +defm GLOBAL_ATOMIC_CMPSWAP_X2 : VGLOBAL_Real_Atomics_gfx12<0x042, "global_atomic_cmpswap_b64">; +defm GLOBAL_ATOMIC_ADD_X2 : VGLOBAL_Real_Atomics_gfx12<0x043, "global_atomic_add_u64">; +defm GLOBAL_ATOMIC_SUB_X2 : VGLOBAL_Real_Atomics_gfx12<0x044, "global_atomic_sub_u64">; +defm GLOBAL_ATOMIC_SMIN_X2 : VGLOBAL_Real_Atomics_gfx12<0x045, "global_atomic_min_i64">; +defm GLOBAL_ATOMIC_UMIN_X2 : VGLOBAL_Real_Atomics_gfx12<0x046, "global_atomic_min_u64">; +defm GLOBAL_ATOMIC_SMAX_X2 : VGLOBAL_Real_Atomics_gfx12<0x047, "global_atomic_max_i64">; +defm GLOBAL_ATOMIC_UMAX_X2 : VGLOBAL_Real_Atomics_gfx12<0x048, "global_atomic_max_u64">; +defm GLOBAL_ATOMIC_AND_X2 : VGLOBAL_Real_Atomics_gfx12<0x049, "global_atomic_and_b64">; +defm GLOBAL_ATOMIC_OR_X2 : VGLOBAL_Real_Atomics_gfx12<0x04a, "global_atomic_or_b64">; +defm GLOBAL_ATOMIC_XOR_X2 : VGLOBAL_Real_Atomics_gfx12<0x04b, "global_atomic_xor_b64">; +defm GLOBAL_ATOMIC_INC_X2 : VGLOBAL_Real_Atomics_gfx12<0x04c, "global_atomic_inc_u64">; +defm GLOBAL_ATOMIC_DEC_X2 : VGLOBAL_Real_Atomics_gfx12<0x04d, "global_atomic_dec_u64">; +defm GLOBAL_ATOMIC_COND_SUB_U32 : VGLOBAL_Real_Atomics_gfx12<0x050>; +defm GLOBAL_ATOMIC_FMIN : VGLOBAL_Real_Atomics_gfx12<0x051, "global_atomic_min_num_f32", "global_atomic_min_f32">; +defm GLOBAL_ATOMIC_FMAX : VGLOBAL_Real_Atomics_gfx12<0x052, "global_atomic_max_num_f32", "global_atomic_max_f32">; defm GLOBAL_ATOMIC_ADD_F32 : VGLOBAL_Real_Atomics_gfx12<0x056>; -let DecoderNamespace = "GFX12" in { - defm GLOBAL_LOAD_TR_B128_w32 : VGLOBAL_Real_AllAddr_gfx12<0x057, "GLOBAL_LOAD_TR_B128_w32", "global_load_tr_b128">; - defm GLOBAL_LOAD_TR_B64_w32 : VGLOBAL_Real_AllAddr_gfx12<0x058, "GLOBAL_LOAD_TR_B64_w32", "global_load_tr_b64">; -} +defm GLOBAL_LOAD_TR_B128_w32 : VGLOBAL_Real_AllAddr_gfx12<0x057, "global_load_tr_b128">; +defm GLOBAL_LOAD_TR_B64_w32 : VGLOBAL_Real_AllAddr_gfx12<0x058, "global_load_tr_b64">; -let DecoderNamespace = "GFX12W64" in { - defm GLOBAL_LOAD_TR_B128_w64 : VGLOBAL_Real_AllAddr_gfx12<0x057, "GLOBAL_LOAD_TR_B128_w64", "global_load_tr_b128">; - defm GLOBAL_LOAD_TR_B64_w64 : VGLOBAL_Real_AllAddr_gfx12<0x058, "GLOBAL_LOAD_TR_B64_w64", "global_load_tr_b64">; -} +defm GLOBAL_LOAD_TR_B128_w64 : VGLOBAL_Real_AllAddr_gfx12_w64<0x057, "global_load_tr_b128">; +defm GLOBAL_LOAD_TR_B64_w64 : VGLOBAL_Real_AllAddr_gfx12_w64<0x058, "global_load_tr_b64">; defm GLOBAL_ATOMIC_ORDERED_ADD_B64 : VGLOBAL_Real_Atomics_gfx12<0x073>; defm GLOBAL_ATOMIC_PK_ADD_F16 : VGLOBAL_Real_Atomics_gfx12<0x059>; @@ -2740,25 +2735,25 @@ defm GLOBAL_WB : VFLAT_Real_Base_gfx12<0x02c>; defm GLOBAL_WBINV : VFLAT_Real_Base_gfx12<0x04f>; // ENC_VSCRATCH. -defm SCRATCH_LOAD_U8 : VSCRATCH_Real_AllAddr_gfx12<0x10, "SCRATCH_LOAD_UBYTE", "scratch_load_u8", true>; -defm SCRATCH_LOAD_I8 : VSCRATCH_Real_AllAddr_gfx12<0x11, "SCRATCH_LOAD_SBYTE", "scratch_load_i8", true>; -defm SCRATCH_LOAD_U16 : VSCRATCH_Real_AllAddr_gfx12<0x12, "SCRATCH_LOAD_USHORT", "scratch_load_u16", true>; -defm SCRATCH_LOAD_I16 : VSCRATCH_Real_AllAddr_gfx12<0x13, "SCRATCH_LOAD_SSHORT", "scratch_load_i16", true>; -defm SCRATCH_LOAD_B32 : VSCRATCH_Real_AllAddr_gfx12<0x14, "SCRATCH_LOAD_DWORD", "scratch_load_b32", true>; -defm SCRATCH_LOAD_B64 : VSCRATCH_Real_AllAddr_gfx12<0x15, "SCRATCH_LOAD_DWORDX2", "scratch_load_b64", true>; -defm SCRATCH_LOAD_B96 : VSCRATCH_Real_AllAddr_gfx12<0x16, "SCRATCH_LOAD_DWORDX3", "scratch_load_b96", true>; -defm SCRATCH_LOAD_B128 : VSCRATCH_Real_AllAddr_gfx12<0x17, "SCRATCH_LOAD_DWORDX4", "scratch_load_b128", true>; -defm SCRATCH_STORE_B8 : VSCRATCH_Real_AllAddr_gfx12<0x18, "SCRATCH_STORE_BYTE", "scratch_store_b8", true>; -defm SCRATCH_STORE_B16 : VSCRATCH_Real_AllAddr_gfx12<0x19, "SCRATCH_STORE_SHORT", "scratch_store_b16", true>; -defm SCRATCH_STORE_B32 : VSCRATCH_Real_AllAddr_gfx12<0x1a, "SCRATCH_STORE_DWORD", "scratch_store_b32", true>; -defm SCRATCH_STORE_B64 : VSCRATCH_Real_AllAddr_gfx12<0x1b, "SCRATCH_STORE_DWORDX2", "scratch_store_b64", true>; -defm SCRATCH_STORE_B96 : VSCRATCH_Real_AllAddr_gfx12<0x1c, "SCRATCH_STORE_DWORDX3", "scratch_store_b96", true>; -defm SCRATCH_STORE_B128 : VSCRATCH_Real_AllAddr_gfx12<0x1d, "SCRATCH_STORE_DWORDX4", "scratch_store_b128", true>; -defm SCRATCH_LOAD_D16_U8 : VSCRATCH_Real_AllAddr_gfx12<0x1e, "SCRATCH_LOAD_UBYTE_D16">; -defm SCRATCH_LOAD_D16_I8 : VSCRATCH_Real_AllAddr_gfx12<0x1f, "SCRATCH_LOAD_SBYTE_D16">; -defm SCRATCH_LOAD_D16_B16 : VSCRATCH_Real_AllAddr_gfx12<0x20, "SCRATCH_LOAD_SHORT_D16">; -defm SCRATCH_LOAD_D16_HI_U8 : VSCRATCH_Real_AllAddr_gfx12<0x21, "SCRATCH_LOAD_UBYTE_D16_HI">; -defm SCRATCH_LOAD_D16_HI_I8 : VSCRATCH_Real_AllAddr_gfx12<0x22, "SCRATCH_LOAD_SBYTE_D16_HI">; -defm SCRATCH_LOAD_D16_HI_B16 : VSCRATCH_Real_AllAddr_gfx12<0x23, "SCRATCH_LOAD_SHORT_D16_HI">; -defm SCRATCH_STORE_D16_HI_B8 : VSCRATCH_Real_AllAddr_gfx12<0x24, "SCRATCH_STORE_BYTE_D16_HI">; -defm SCRATCH_STORE_D16_HI_B16 : VSCRATCH_Real_AllAddr_gfx12<0x25, "SCRATCH_STORE_SHORT_D16_HI">; +defm SCRATCH_LOAD_UBYTE : VSCRATCH_Real_AllAddr_gfx12<0x10, "scratch_load_u8">; +defm SCRATCH_LOAD_SBYTE : VSCRATCH_Real_AllAddr_gfx12<0x11, "scratch_load_i8">; +defm SCRATCH_LOAD_USHORT : VSCRATCH_Real_AllAddr_gfx12<0x12, "scratch_load_u16">; +defm SCRATCH_LOAD_SSHORT : VSCRATCH_Real_AllAddr_gfx12<0x13, "scratch_load_i16">; +defm SCRATCH_LOAD_DWORD : VSCRATCH_Real_AllAddr_gfx12<0x14, "scratch_load_b32">; +defm SCRATCH_LOAD_DWORDX2 : VSCRATCH_Real_AllAddr_gfx12<0x15, "scratch_load_b64">; +defm SCRATCH_LOAD_DWORDX3 : VSCRATCH_Real_AllAddr_gfx12<0x16, "scratch_load_b96">; +defm SCRATCH_LOAD_DWORDX4 : VSCRATCH_Real_AllAddr_gfx12<0x17, "scratch_load_b128">; +defm SCRATCH_STORE_BYTE : VSCRATCH_Real_AllAddr_gfx12<0x18, "scratch_store_b8">; +defm SCRATCH_STORE_SHORT : VSCRATCH_Real_AllAddr_gfx12<0x19, "scratch_store_b16">; +defm SCRATCH_STORE_DWORD : VSCRATCH_Real_AllAddr_gfx12<0x1a, "scratch_store_b32">; +defm SCRATCH_STORE_DWORDX2 : VSCRATCH_Real_AllAddr_gfx12<0x1b, "scratch_store_b64">; +defm SCRATCH_STORE_DWORDX3 : VSCRATCH_Real_AllAddr_gfx12<0x1c, "scratch_store_b96">; +defm SCRATCH_STORE_DWORDX4 : VSCRATCH_Real_AllAddr_gfx12<0x1d, "scratch_store_b128">; +defm SCRATCH_LOAD_UBYTE_D16 : VSCRATCH_Real_AllAddr_gfx12<0x1e, "scratch_load_d16_u8">; +defm SCRATCH_LOAD_SBYTE_D16 : VSCRATCH_Real_AllAddr_gfx12<0x1f, "scratch_load_d16_i8">; +defm SCRATCH_LOAD_SHORT_D16 : VSCRATCH_Real_AllAddr_gfx12<0x20, "scratch_load_d16_b16">; +defm SCRATCH_LOAD_UBYTE_D16_HI : VSCRATCH_Real_AllAddr_gfx12<0x21, "scratch_load_d16_hi_u8">; +defm SCRATCH_LOAD_SBYTE_D16_HI : VSCRATCH_Real_AllAddr_gfx12<0x22, "scratch_load_d16_hi_i8">; +defm SCRATCH_LOAD_SHORT_D16_HI : VSCRATCH_Real_AllAddr_gfx12<0x23, "scratch_load_d16_hi_b16">; +defm SCRATCH_STORE_BYTE_D16_HI : VSCRATCH_Real_AllAddr_gfx12<0x24, "scratch_store_d16_hi_b8">; +defm SCRATCH_STORE_SHORT_D16_HI : VSCRATCH_Real_AllAddr_gfx12<0x25, "scratch_store_d16_hi_b16">; -- GitLab From eefef900c6a24f2acd724726bc52884e058575da Mon Sep 17 00:00:00 2001 From: Nikita Popov <npopov@redhat.com> Date: Wed, 20 Mar 2024 11:08:52 +0100 Subject: [PATCH 208/307] Revert "Enable exp10 libcall on linux (#68736)" This reverts commit 9848fa4aa2a83b0fc3a93e5f905ef09c8dd85226. Causes buildbot failures. --- llvm/lib/Analysis/TargetLibraryInfo.cpp | 19 +++---- .../InstCombine/double-float-shrink-1.ll | 19 ++----- llvm/test/Transforms/InstCombine/pow-1.ll | 53 +++---------------- llvm/test/Transforms/InstCombine/pow-exp.ll | 39 +++++++------- 4 files changed, 42 insertions(+), 88 deletions(-) diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index a0f6fa8f1ae9..c8195584ade3 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -560,12 +560,16 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, break; case Triple::Linux: // exp10, exp10f, exp10l is available on Linux (GLIBC) but are extremely - // buggy prior to glibc version 2.18. As this version is so old, we - // don't really need to worry about using exp10 on Linux. - TLI.setAvailableWithName(LibFunc_exp10, "__exp10"); - TLI.setAvailableWithName(LibFunc_exp10f, "__exp10f"); - TLI.setAvailableWithName(LibFunc_exp10l, "__exp10l"); - break; + // buggy prior to glibc version 2.18. Until this version is widely deployed + // or we have a reasonable detection strategy, we cannot use exp10 reliably + // on Linux. + // + // Fall through to disable all of them. + [[fallthrough]]; + default: + TLI.setUnavailable(LibFunc_exp10); + TLI.setUnavailable(LibFunc_exp10f); + TLI.setUnavailable(LibFunc_exp10l); } // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and @@ -837,9 +841,6 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, TLI.setUnavailable(LibFunc_strndup); TLI.setUnavailable(LibFunc_strnlen); TLI.setUnavailable(LibFunc_toascii); - TLI.setUnavailable(LibFunc_exp10); - TLI.setUnavailable(LibFunc_exp10f); - TLI.setUnavailable(LibFunc_exp10l); } // As currently implemented in clang, NVPTX code has no standard library to diff --git a/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll b/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll index 693730256b6b..85c9a01e5fab 100644 --- a/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll +++ b/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll @@ -224,20 +224,11 @@ define double @expm1_test2(float %f) { ; exp10f() doesn't exist for this triple, so it doesn't shrink. define float @exp10_test1(float %f) { -; LINUX-LABEL: define float @exp10_test1( -; LINUX-SAME: float [[F:%.*]]) { -; LINUX-NEXT: [[EXP10F:%.*]] = call fast float @__exp10f(float [[F]]) -; LINUX-NEXT: ret float [[EXP10F]] -; -; MS64-LABEL: define float @exp10_test1( -; MS64-SAME: float [[F:%.*]]) { -; MS64-NEXT: [[EXP10F:%.*]] = call fast float @exp10f(float [[F]]) -; MS64-NEXT: ret float [[EXP10F]] -; -; MS32-LABEL: define float @exp10_test1( -; MS32-SAME: float [[F:%.*]]) { -; MS32-NEXT: [[EXP10F:%.*]] = call fast float @exp10f(float [[F]]) -; MS32-NEXT: ret float [[EXP10F]] +; CHECK-LABEL: @exp10_test1( +; CHECK-NEXT: [[CONV:%.*]] = fpext float [[F:%.*]] to double +; CHECK-NEXT: [[CALL:%.*]] = call fast double @exp10(double [[CONV]]) +; CHECK-NEXT: [[CONV1:%.*]] = fptrunc double [[CALL]] to float +; CHECK-NEXT: ret float [[CONV1]] ; %conv = fpext float %f to double %call = call fast double @exp10(double %conv) diff --git a/llvm/test/Transforms/InstCombine/pow-1.ll b/llvm/test/Transforms/InstCombine/pow-1.ll index 5024d152bddf..7a72902126f8 100644 --- a/llvm/test/Transforms/InstCombine/pow-1.ll +++ b/llvm/test/Transforms/InstCombine/pow-1.ll @@ -870,30 +870,10 @@ define float @test_simplify18(float %x) { ; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @__exp10f(float [[X]]) ; CHECK-EXP10-NEXT: ret float [[__EXP10F]] ; -; VC32-LABEL: define float @test_simplify18( -; VC32-SAME: float [[X:%.*]]) { -; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) -; VC32-NEXT: ret float [[RETVAL]] -; -; VC51-LABEL: define float @test_simplify18( -; VC51-SAME: float [[X:%.*]]) { -; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) -; VC51-NEXT: ret float [[RETVAL]] -; -; VC64-LABEL: define float @test_simplify18( -; VC64-SAME: float [[X:%.*]]) { -; VC64-NEXT: [[EXP10F:%.*]] = call float @exp10f(float [[X]]) -; VC64-NEXT: ret float [[EXP10F]] -; -; VC83-LABEL: define float @test_simplify18( -; VC83-SAME: float [[X:%.*]]) { -; VC83-NEXT: [[EXP10F:%.*]] = call float @exp10f(float [[X]]) -; VC83-NEXT: ret float [[EXP10F]] -; -; NOLIB-LABEL: define float @test_simplify18( -; NOLIB-SAME: float [[X:%.*]]) { -; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) -; NOLIB-NEXT: ret float [[RETVAL]] +; CHECK-NO-EXP10-LABEL: define float @test_simplify18( +; CHECK-NO-EXP10-SAME: float [[X:%.*]]) { +; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) +; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]] ; %retval = call float @powf(float 10.0, float %x) ret float %retval @@ -905,28 +885,11 @@ define double @test_simplify19(double %x) { ; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @__exp10(double [[X]]) ; CHECK-EXP10-NEXT: ret double [[__EXP10]] ; -; VC32-LABEL: define double @test_simplify19( -; VC32-SAME: double [[X:%.*]]) { -; VC32-NEXT: [[EXP10:%.*]] = call double @exp10(double [[X]]) -; VC32-NEXT: ret double [[EXP10]] -; -; VC19-LABEL: define double @test_simplify19( -; VC19-SAME: double [[X:%.*]]) { -; VC19-NEXT: [[EXP10:%.*]] = call double @exp10(double [[X]]) -; VC19-NEXT: ret double [[EXP10]] -; -; VC64-LABEL: define double @test_simplify19( -; VC64-SAME: double [[X:%.*]]) { -; VC64-NEXT: [[EXP10:%.*]] = call double @exp10(double [[X]]) -; VC64-NEXT: ret double [[EXP10]] -; -; NOLIB-LABEL: define double @test_simplify19( -; NOLIB-SAME: double [[X:%.*]]) { -; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) -; NOLIB-NEXT: ret double [[RETVAL]] +; CHECK-NO-EXP10-LABEL: define double @test_simplify19( +; CHECK-NO-EXP10-SAME: double [[X:%.*]]) { +; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) +; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]] ; %retval = call double @pow(double 10.0, double %x) ret double %retval } -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK-NO-EXP10: {{.*}} diff --git a/llvm/test/Transforms/InstCombine/pow-exp.ll b/llvm/test/Transforms/InstCombine/pow-exp.ll index 177dd9885827..9d91ad2402eb 100644 --- a/llvm/test/Transforms/InstCombine/pow-exp.ll +++ b/llvm/test/Transforms/InstCombine/pow-exp.ll @@ -136,11 +136,12 @@ define fp128 @powl_exp2l_not_fast(fp128 %x, fp128 %y) { ret fp128 %pow } +; TODO: exp10() is not widely enabled by many targets yet. + define float @powf_exp10f(float %x, float %y) { -; CHECK-LABEL: define float @powf_exp10f( -; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) { -; CHECK-NEXT: [[CALL:%.*]] = call fast float @exp10f(float [[X]]) #[[ATTR1:[0-9]+]] -; CHECK-NEXT: [[POW:%.*]] = call fast float @llvm.pow.f32(float [[CALL]], float [[Y]]) +; CHECK-LABEL: @powf_exp10f( +; CHECK-NEXT: [[CALL:%.*]] = call fast float @exp10f(float [[X:%.*]]) #[[ATTR1:[0-9]+]] +; CHECK-NEXT: [[POW:%.*]] = call fast float @llvm.pow.f32(float [[CALL]], float [[Y:%.*]]) ; CHECK-NEXT: ret float [[POW]] ; %call = call fast float @exp10f(float %x) nounwind readnone @@ -149,10 +150,9 @@ define float @powf_exp10f(float %x, float %y) { } define double @pow_exp10(double %x, double %y) { -; CHECK-LABEL: define double @pow_exp10( -; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) { -; CHECK-NEXT: [[CALL:%.*]] = call fast double @exp10(double [[X]]) #[[ATTR1]] -; CHECK-NEXT: [[POW:%.*]] = call fast double @llvm.pow.f64(double [[CALL]], double [[Y]]) +; CHECK-LABEL: @pow_exp10( +; CHECK-NEXT: [[CALL:%.*]] = call fast double @exp10(double [[X:%.*]]) #[[ATTR1]] +; CHECK-NEXT: [[POW:%.*]] = call fast double @llvm.pow.f64(double [[CALL]], double [[Y:%.*]]) ; CHECK-NEXT: ret double [[POW]] ; %call = call fast double @exp10(double %x) nounwind readnone @@ -161,10 +161,9 @@ define double @pow_exp10(double %x, double %y) { } define fp128 @pow_exp10l(fp128 %x, fp128 %y) { -; CHECK-LABEL: define fp128 @pow_exp10l( -; CHECK-SAME: fp128 [[X:%.*]], fp128 [[Y:%.*]]) { -; CHECK-NEXT: [[CALL:%.*]] = call fast fp128 @exp10l(fp128 [[X]]) #[[ATTR1]] -; CHECK-NEXT: [[POW:%.*]] = call fast fp128 @llvm.pow.f128(fp128 [[CALL]], fp128 [[Y]]) +; CHECK-LABEL: @pow_exp10l( +; CHECK-NEXT: [[CALL:%.*]] = call fast fp128 @exp10l(fp128 [[X:%.*]]) #[[ATTR1]] +; CHECK-NEXT: [[POW:%.*]] = call fast fp128 @llvm.pow.f128(fp128 [[CALL]], fp128 [[Y:%.*]]) ; CHECK-NEXT: ret fp128 [[POW]] ; %call = call fast fp128 @exp10l(fp128 %x) nounwind readnone @@ -256,10 +255,10 @@ define double @pow_ok_base3(double %e) { } define double @pow_ok_ten_base(double %e) { -; CHECK-LABEL: define double @pow_ok_ten_base( -; CHECK-SAME: double [[E:%.*]]) { -; CHECK-NEXT: [[EXP10:%.*]] = tail call nnan ninf afn double @exp10(double [[E]]) -; CHECK-NEXT: ret double [[EXP10]] +; CHECK-LABEL: @pow_ok_ten_base( +; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn double [[E:%.*]], 0x400A934F{{.*}} +; CHECK-NEXT: [[EXP2:%.*]] = tail call nnan ninf afn double @exp2(double [[MUL]]) +; CHECK-NEXT: ret double [[EXP2]] ; %call = tail call afn nnan ninf double @pow(double 1.000000e+01, double %e) ret double %call @@ -306,10 +305,10 @@ define float @powf_ok_base3(float %e) { } define float @powf_ok_ten_base(float %e) { -; CHECK-LABEL: define float @powf_ok_ten_base( -; CHECK-SAME: float [[E:%.*]]) { -; CHECK-NEXT: [[EXP10F:%.*]] = tail call nnan ninf afn float @exp10f(float [[E]]) -; CHECK-NEXT: ret float [[EXP10F]] +; CHECK-LABEL: @powf_ok_ten_base( +; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn float [[E:%.*]], 0x400A934{{.*}} +; CHECK-NEXT: [[EXP2F:%.*]] = tail call nnan ninf afn float @exp2f(float [[MUL]]) +; CHECK-NEXT: ret float [[EXP2F]] ; %call = tail call afn nnan ninf float @powf(float 1.000000e+01, float %e) ret float %call -- GitLab From 3b0a426b3fbe99e128b718a4761ea30b394ce9bb Mon Sep 17 00:00:00 2001 From: Tom Eccles <tom.eccles@arm.com> Date: Wed, 20 Mar 2024 10:09:50 +0000 Subject: [PATCH 209/307] [flang][NFC] move extractSequenceType helper out of OpenACC to share code (#84957) Moving extractSequenceType to FIRType.h so that this can also be used from OpenMP. OpenMP array reductions 5/6 Previous PR: https://github.com/llvm/llvm-project/pull/84955 Next PR: https://github.com/llvm/llvm-project/pull/84958 --- .../include/flang/Optimizer/Dialect/FIRType.h | 3 +++ flang/lib/Lower/OpenACC.cpp | 21 ++++--------------- flang/lib/Optimizer/Dialect/FIRType.cpp | 12 +++++++++++ 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h index a526b4ddf3b9..7fcd9c1babf2 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRType.h +++ b/flang/include/flang/Optimizer/Dialect/FIRType.h @@ -237,6 +237,9 @@ inline mlir::Type unwrapSequenceType(mlir::Type t) { return t; } +/// Return the nested sequence type if any. +mlir::Type extractSequenceType(mlir::Type ty); + inline mlir::Type unwrapRefType(mlir::Type t) { if (auto eleTy = dyn_cast_ptrEleTy(t)) return eleTy; diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index d2c6006ecf91..6539de4d8830 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -406,19 +406,6 @@ fir::ShapeOp genShapeOp(mlir::OpBuilder &builder, fir::SequenceType seqTy, return builder.create<fir::ShapeOp>(loc, extents); } -/// Return the nested sequence type if any. -static mlir::Type extractSequenceType(mlir::Type ty) { - if (mlir::isa<fir::SequenceType>(ty)) - return ty; - if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(ty)) - return extractSequenceType(boxTy.getEleTy()); - if (auto heapTy = mlir::dyn_cast<fir::HeapType>(ty)) - return extractSequenceType(heapTy.getEleTy()); - if (auto ptrTy = mlir::dyn_cast<fir::PointerType>(ty)) - return extractSequenceType(ptrTy.getEleTy()); - return mlir::Type{}; -} - template <typename RecipeOp> static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe, mlir::Type ty, mlir::Location loc) { @@ -454,7 +441,7 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe, } } } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(ty)) { - mlir::Type innerTy = extractSequenceType(boxTy); + mlir::Type innerTy = fir::extractSequenceType(boxTy); if (!innerTy) TODO(loc, "Unsupported boxed type in OpenACC privatization"); fir::FirOpBuilder firBuilder{builder, recipe.getOperation()}; @@ -688,7 +675,7 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe( } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(ty)) { fir::FirOpBuilder firBuilder{builder, recipe.getOperation()}; llvm::SmallVector<mlir::Value> tripletArgs; - mlir::Type innerTy = extractSequenceType(boxTy); + mlir::Type innerTy = fir::extractSequenceType(boxTy); fir::SequenceType seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(innerTy); if (!seqTy) @@ -1018,7 +1005,7 @@ static mlir::Value genReductionInitRegion(fir::FirOpBuilder &builder, return declareOp.getBase(); } } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(ty)) { - mlir::Type innerTy = extractSequenceType(boxTy); + mlir::Type innerTy = fir::extractSequenceType(boxTy); if (!mlir::isa<fir::SequenceType>(innerTy)) TODO(loc, "Unsupported boxed type for reduction"); // Create the private copy from the initial fir.box. @@ -1230,7 +1217,7 @@ static void genCombiner(fir::FirOpBuilder &builder, mlir::Location loc, builder.create<fir::StoreOp>(loc, res, addr1); builder.setInsertionPointAfter(loops[0]); } else if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(ty)) { - mlir::Type innerTy = extractSequenceType(boxTy); + mlir::Type innerTy = fir::extractSequenceType(boxTy); fir::SequenceType seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(innerTy); if (!seqTy) diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp index 8a2c681d9586..5c4cad6d2083 100644 --- a/flang/lib/Optimizer/Dialect/FIRType.cpp +++ b/flang/lib/Optimizer/Dialect/FIRType.cpp @@ -254,6 +254,18 @@ bool hasDynamicSize(mlir::Type t) { return false; } +mlir::Type extractSequenceType(mlir::Type ty) { + if (mlir::isa<fir::SequenceType>(ty)) + return ty; + if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(ty)) + return extractSequenceType(boxTy.getEleTy()); + if (auto heapTy = mlir::dyn_cast<fir::HeapType>(ty)) + return extractSequenceType(heapTy.getEleTy()); + if (auto ptrTy = mlir::dyn_cast<fir::PointerType>(ty)) + return extractSequenceType(ptrTy.getEleTy()); + return mlir::Type{}; +} + bool isPointerType(mlir::Type ty) { if (auto refTy = fir::dyn_cast_ptrEleTy(ty)) ty = refTy; -- GitLab From 260ac8e52f6dac02958aca874ba46dea0b99fef3 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme <thomas.preudhomme@arm.com> Date: Wed, 20 Mar 2024 10:12:03 +0000 Subject: [PATCH 210/307] [MLIR] Remove unneeded FuncOps.h include in AffineAnalysis (#85912) This fixes the following failure when doing a clean build (in particular no .ninja* lying around) of lib/libMLIRAffineAnalysis.a only: In file included from mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp:20: mlir/include/mlir/Dialect/Func/IR/FuncOps.h:29:10: fatal error: mlir/Dialect/Func/IR/FuncOps.h.inc: No such file or directory --- mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp b/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp index 1ba0bc8b6bfb..61244921bc38 100644 --- a/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp +++ b/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp @@ -17,7 +17,6 @@ #include "mlir/Dialect/Affine/Analysis/Utils.h" #include "mlir/Dialect/Affine/IR/AffineOps.h" #include "mlir/Dialect/Affine/IR/AffineValueMap.h" -#include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/IR/AffineExprVisitor.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/IntegerSet.h" -- GitLab From fe1341248d7dd9abd0545ddb48373756645c3f9f Mon Sep 17 00:00:00 2001 From: Ulrich Weigand <ulrich.weigand@de.ibm.com> Date: Wed, 20 Mar 2024 11:10:19 +0100 Subject: [PATCH 211/307] [OpenMP] Disable workshare_chunk.c test case on SystemZ The test added by https://github.com/llvm/llvm-project/pull/83261 has been consistently failing. Mark as UNSUPPORTED just like on x86_64 and aarch64. --- openmp/libomptarget/test/offloading/workshare_chunk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openmp/libomptarget/test/offloading/workshare_chunk.c b/openmp/libomptarget/test/offloading/workshare_chunk.c index c2248547605b..a8c60c009779 100644 --- a/openmp/libomptarget/test/offloading/workshare_chunk.c +++ b/openmp/libomptarget/test/offloading/workshare_chunk.c @@ -5,6 +5,8 @@ // UNSUPPORTED: aarch64-unknown-linux-gnu-LTO // UNSUPPORTED: x86_64-pc-linux-gnu // UNSUPPORTED: x86_64-pc-linux-gnu-LTO +// UNSUPPORTED: s390x-ibm-linux-gnu +// UNSUPPORTED: s390x-ibm-linux-gnu-LTO // clang-format off -- GitLab From cd768ec9837afed4d226a5abc8035a1559c18bc5 Mon Sep 17 00:00:00 2001 From: Graham Hunter <graham.hunter@arm.com> Date: Wed, 20 Mar 2024 10:13:20 +0000 Subject: [PATCH 212/307] [AArch64] Support scalable offsets with isLegalAddressingMode (#83255) Allows us to indicate that an addressing mode featuring a vscale-relative immediate offset is supported. --- .../llvm/Analysis/TargetTransformInfo.h | 15 ++++-- .../llvm/Analysis/TargetTransformInfoImpl.h | 3 +- llvm/include/llvm/CodeGen/BasicTTIImpl.h | 6 ++- llvm/include/llvm/CodeGen/TargetLowering.h | 4 +- llvm/lib/Analysis/TargetTransformInfo.cpp | 5 +- llvm/lib/CodeGen/TargetLoweringBase.cpp | 4 ++ .../Target/AArch64/AArch64ISelLowering.cpp | 18 ++++++- .../Target/AArch64/AddressingModes.cpp | 50 ++++++++++++++++++- 8 files changed, 91 insertions(+), 14 deletions(-) diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h index c43a1b5c1b2a..3a57b7bdb2d4 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfo.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -707,11 +707,15 @@ public: /// The type may be VoidTy, in which case only return true if the addressing /// mode is legal for a load/store of any legal type. /// If target returns true in LSRWithInstrQueries(), I may be valid. + /// \param ScalableOffset represents a quantity of bytes multiplied by vscale, + /// an invariant value known only at runtime. Most targets should not accept + /// a scalable offset. + /// /// TODO: Handle pre/postinc as well. bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, - unsigned AddrSpace = 0, - Instruction *I = nullptr) const; + unsigned AddrSpace = 0, Instruction *I = nullptr, + int64_t ScalableOffset = 0) const; /// Return true if LSR cost of C1 is lower than C2. bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1, @@ -1842,7 +1846,8 @@ public: virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, - Instruction *I) = 0; + Instruction *I, + int64_t ScalableOffset) = 0; virtual bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1, const TargetTransformInfo::LSRCost &C2) = 0; virtual bool isNumRegsMajorCostOfLSR() = 0; @@ -2303,9 +2308,9 @@ public: } bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, - Instruction *I) override { + Instruction *I, int64_t ScalableOffset) override { return Impl.isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale, - AddrSpace, I); + AddrSpace, I, ScalableOffset); } bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1, const TargetTransformInfo::LSRCost &C2) override { diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h index 7f661bb4a1df..07eeceeeaa22 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -220,7 +220,8 @@ public: bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, - Instruction *I = nullptr) const { + Instruction *I = nullptr, + int64_t ScalableOffset = 0) const { // Guess that only reg and reg+reg addressing is allowed. This heuristic is // taken from the implementation of LSR. return !BaseGV && BaseOffset == 0 && (Scale == 0 || Scale == 1); diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h index 61f6564e8cd7..721900038ddd 100644 --- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -333,13 +333,15 @@ public: } bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale, - unsigned AddrSpace, Instruction *I = nullptr) { + bool HasBaseReg, int64_t Scale, unsigned AddrSpace, + Instruction *I = nullptr, + int64_t ScalableOffset = 0) { TargetLoweringBase::AddrMode AM; AM.BaseGV = BaseGV; AM.BaseOffs = BaseOffset; AM.HasBaseReg = HasBaseReg; AM.Scale = Scale; + AM.ScalableOffset = ScalableOffset; return getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace, I); } diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 2f164a460db8..4753d8e8a512 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -2722,17 +2722,19 @@ public: } /// This represents an addressing mode of: - /// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + /// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*vscale /// If BaseGV is null, there is no BaseGV. /// If BaseOffs is zero, there is no base offset. /// If HasBaseReg is false, there is no base register. /// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with /// no scale. + /// If ScalableOffset is zero, there is no scalable offset. struct AddrMode { GlobalValue *BaseGV = nullptr; int64_t BaseOffs = 0; bool HasBaseReg = false; int64_t Scale = 0; + int64_t ScalableOffset = 0; AddrMode() = default; }; diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp index 2e0bd8433965..414da85209c1 100644 --- a/llvm/lib/Analysis/TargetTransformInfo.cpp +++ b/llvm/lib/Analysis/TargetTransformInfo.cpp @@ -404,9 +404,10 @@ bool TargetTransformInfo::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, - Instruction *I) const { + Instruction *I, + int64_t ScalableOffset) const { return TTIImpl->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, - Scale, AddrSpace, I); + Scale, AddrSpace, I, ScalableOffset); } bool TargetTransformInfo::isLSRCostLess(const LSRCost &C1, diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 8ac55ee6a5d0..9990556f89ed 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -2011,6 +2011,10 @@ bool TargetLoweringBase::isLegalAddressingMode(const DataLayout &DL, // The default implementation of this implements a conservative RISCy, r+r and // r+i addr mode. + // Scalable offsets not supported + if (AM.ScalableOffset) + return false; + // Allows a sign-extended 16-bit immediate field. if (AM.BaseOffs <= -(1LL << 16) || AM.BaseOffs >= (1LL << 16)-1) return false; diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 92f59dbf1e9e..512e35fad8fe 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -16692,15 +16692,29 @@ bool AArch64TargetLowering::isLegalAddressingMode(const DataLayout &DL, if (Ty->isScalableTy()) { if (isa<ScalableVectorType>(Ty)) { + // See if we have a foldable vscale-based offset, for vector types which + // are either legal or smaller than the minimum; more work will be + // required if we need to consider addressing for types which need + // legalization by splitting. + uint64_t VecNumBytes = DL.getTypeSizeInBits(Ty).getKnownMinValue() / 8; + if (AM.HasBaseReg && !AM.BaseOffs && AM.ScalableOffset && !AM.Scale && + (AM.ScalableOffset % VecNumBytes == 0) && VecNumBytes <= 16 && + isPowerOf2_64(VecNumBytes)) + return isInt<4>(AM.ScalableOffset / (int64_t)VecNumBytes); + uint64_t VecElemNumBytes = DL.getTypeSizeInBits(cast<VectorType>(Ty)->getElementType()) / 8; - return AM.HasBaseReg && !AM.BaseOffs && + return AM.HasBaseReg && !AM.BaseOffs && !AM.ScalableOffset && (AM.Scale == 0 || (uint64_t)AM.Scale == VecElemNumBytes); } - return AM.HasBaseReg && !AM.BaseOffs && !AM.Scale; + return AM.HasBaseReg && !AM.BaseOffs && !AM.ScalableOffset && !AM.Scale; } + // No scalable offsets allowed for non-scalable types. + if (AM.ScalableOffset) + return false; + // check reg + imm case: // i.e., reg + 0, reg + imm9, reg + SIZE_IN_BYTES * uimm12 uint64_t NumBytes = 0; diff --git a/llvm/unittests/Target/AArch64/AddressingModes.cpp b/llvm/unittests/Target/AArch64/AddressingModes.cpp index 284ea7ae9233..0af18d886791 100644 --- a/llvm/unittests/Target/AArch64/AddressingModes.cpp +++ b/llvm/unittests/Target/AArch64/AddressingModes.cpp @@ -13,11 +13,13 @@ using namespace llvm; namespace { struct AddrMode : public TargetLowering::AddrMode { - constexpr AddrMode(GlobalValue *GV, int64_t Offs, bool HasBase, int64_t S) { + constexpr AddrMode(GlobalValue *GV, int64_t Offs, bool HasBase, int64_t S, + int64_t SOffs = 0) { BaseGV = GV; BaseOffs = Offs; HasBaseReg = HasBase; Scale = S; + ScalableOffset = SOffs; } }; struct TestCase { @@ -153,6 +155,45 @@ const std::initializer_list<TestCase> Tests = { {{nullptr, 4096 + 1, true, 0}, 8, false}, }; + +struct SVETestCase { + AddrMode AM; + unsigned TypeBits; + unsigned NumElts; + bool Result; +}; + +const std::initializer_list<SVETestCase> SVETests = { + // {BaseGV, BaseOffs, HasBaseReg, Scale, SOffs}, EltBits, Count, Result + // Test immediate range -- [-8,7] vector's worth. + // <vscale x 16 x i8>, increment by one vector + {{nullptr, 0, true, 0, 16}, 8, 16, true}, + // <vscale x 4 x i32>, increment by eight vectors + {{nullptr, 0, true, 0, 128}, 32, 4, false}, + // <vscale x 8 x i16>, increment by seven vectors + {{nullptr, 0, true, 0, 112}, 16, 8, true}, + // <vscale x 2 x i64>, decrement by eight vectors + {{nullptr, 0, true, 0, -128}, 64, 2, true}, + // <vscale x 16 x i8>, decrement by nine vectors + {{nullptr, 0, true, 0, -144}, 8, 16, false}, + + // Half the size of a vector register, but allowable with extending + // loads and truncating stores + // <vscale x 8 x i8>, increment by three vectors + {{nullptr, 0, true, 0, 24}, 8, 8, true}, + + // Test invalid types or offsets + // <vscale x 5 x i32>, increment by one vector (base size > 16B) + {{nullptr, 0, true, 0, 20}, 32, 5, false}, + // <vscale x 8 x i16>, increment by half a vector + {{nullptr, 0, true, 0, 8}, 16, 8, false}, + // <vscale x 3 x i8>, increment by 3 vectors (non-power-of-two) + {{nullptr, 0, true, 0, 9}, 8, 3, false}, + + // Scalable and fixed offsets + // <vscale x 16 x i8>, increment by 32 then decrement by vscale x 16 + {{nullptr, 32, true, 0, -16}, 8, 16, false}, +}; } // namespace TEST(AddressingModes, AddressingModes) { @@ -179,4 +220,11 @@ TEST(AddressingModes, AddressingModes) { Type *Typ = Type::getIntNTy(Ctx, Test.TypeBits); ASSERT_EQ(TLI->isLegalAddressingMode(DL, Test.AM, Typ, 0), Test.Result); } + + for (const auto &SVETest : SVETests) { + Type *Ty = VectorType::get(Type::getIntNTy(Ctx, SVETest.TypeBits), + ElementCount::getScalable(SVETest.NumElts)); + ASSERT_EQ(TLI->isLegalAddressingMode(DL, SVETest.AM, Ty, 0), + SVETest.Result); + } } -- GitLab From 0247564c14ffc7f6a13ed9d127e32bfdfbf93a19 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme <thomas.preudhomme@arm.com> Date: Wed, 20 Mar 2024 10:13:54 +0000 Subject: [PATCH 213/307] [MLIR] Add missing MLIRGPUDialect dep to MLIRSPIRVDialect (#84554) This fixes the following failure when doing a clean build (in particular no .ninja* lying around) of lib/libMLIRSPIRVDialect.a only: ``` mlir/lib/Dialect/SPIRV/IR/SPIRVDialect.cpp:17: mlir/include/mlir/Dialect/GPU/IR/CompilationInterfaces.h:120:10: fatal error: mlir/Dialect/GPU/IR/CompilationAttrInterfaces.h.inc: No such file or directory ``` --- mlir/lib/Dialect/SPIRV/IR/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/mlir/lib/Dialect/SPIRV/IR/CMakeLists.txt b/mlir/lib/Dialect/SPIRV/IR/CMakeLists.txt index 2b5cedafae1e..b18526421147 100644 --- a/mlir/lib/Dialect/SPIRV/IR/CMakeLists.txt +++ b/mlir/lib/Dialect/SPIRV/IR/CMakeLists.txt @@ -27,6 +27,7 @@ add_mlir_dialect_library(MLIRSPIRVDialect ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/SPIRV DEPENDS + MLIRGPUDialect MLIRSPIRVAttributeIncGen MLIRSPIRVAttrUtilsGen MLIRSPIRVAvailabilityIncGen -- GitLab From b7975cae7b18485e704a86ed4690a621e5064e13 Mon Sep 17 00:00:00 2001 From: Alexandros Lamprineas <alexandros.lamprineas@arm.com> Date: Wed, 20 Mar 2024 10:16:26 +0000 Subject: [PATCH 214/307] Revert "[FMV] Emit the resolver along with the default version definition." (#85914) Reverts llvm/llvm-project#84405 In between of passing the precommit tests on github and being merged some change (perhaps in the AArch64 backend?) landed which resulted in altering the generated resolver. I will regenerate the tests perhaps using a less sensitive runline to such changes. --- clang/lib/CodeGen/CodeGenModule.cpp | 55 +- clang/lib/CodeGen/CodeGenModule.h | 5 - clang/test/CodeGen/attr-target-version.c | 546 ++++++------------ clang/test/CodeGenCXX/attr-target-version.cpp | 261 ++------- 4 files changed, 238 insertions(+), 629 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index cb153066b28d..bb26bfcddaeb 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3449,9 +3449,6 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) { // Implicit template instantiations may change linkage if they are later // explicitly instantiated, so they should not be emitted eagerly. return false; - // Defer until all versions have been semantically checked. - if (FD->hasAttr<TargetVersionAttr>() && !FD->isMultiVersion()) - return false; } if (const auto *VD = dyn_cast<VarDecl>(Global)) { if (Context.getInlineVariableDefinitionKind(VD) == @@ -4000,13 +3997,10 @@ void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD, EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr); // Ensure that the resolver function is also emitted. GetOrCreateMultiVersionResolver(GD); + } else if (FD->hasAttr<TargetVersionAttr>()) { + GetOrCreateMultiVersionResolver(GD); } else EmitGlobalFunctionDefinition(GD, GV); - - // Defer the resolver emission until we can reason whether the TU - // contains a default target version implementation. - if (FD->isTargetVersionMultiVersion()) - AddDeferredMultiVersionResolverToEmit(GD); } void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { @@ -4099,11 +4093,10 @@ void CodeGenModule::emitMultiVersionFunctions() { const auto *FD = cast<FunctionDecl>(GD.getDecl()); assert(FD && "Expected a FunctionDecl"); - bool EmitResolver = !FD->isTargetVersionMultiVersion(); SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options; if (FD->isTargetMultiVersion()) { getContext().forEachMultiversionedFunctionVersion( - FD, [this, &GD, &Options, &EmitResolver](const FunctionDecl *CurFD) { + FD, [this, &GD, &Options](const FunctionDecl *CurFD) { GlobalDecl CurGD{ (CurFD->isDefined() ? CurFD->getDefinition() : CurFD)}; StringRef MangledName = getMangledName(CurGD); @@ -4129,9 +4122,6 @@ void CodeGenModule::emitMultiVersionFunctions() { TA->getArchitecture(), Feats); } else { const auto *TVA = CurFD->getAttr<TargetVersionAttr>(); - if (CurFD->isUsed() || (TVA->isDefaultVersion() && - CurFD->doesThisDeclarationHaveABody())) - EmitResolver = true; llvm::SmallVector<StringRef, 8> Feats; TVA->getFeatures(Feats); Options.emplace_back(cast<llvm::Function>(Func), @@ -4187,27 +4177,22 @@ void CodeGenModule::emitMultiVersionFunctions() { continue; } - if (!EmitResolver) - continue; - llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver(GD); if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) { ResolverConstant = IFunc->getResolver(); if (FD->isTargetClonesMultiVersion() || FD->isTargetVersionMultiVersion()) { + const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); + llvm::FunctionType *DeclTy = getTypes().GetFunctionType(FI); std::string MangledName = getMangledNameImpl( *this, GD, FD, /*OmitMultiVersionMangling=*/true); - if (!GetGlobalValue(MangledName + ".ifunc")) { - const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); - llvm::FunctionType *DeclTy = getTypes().GetFunctionType(FI); - // In prior versions of Clang, the mangling for ifuncs incorrectly - // included an .ifunc suffix. This alias is generated for backward - // compatibility. It is deprecated, and may be removed in the future. - auto *Alias = llvm::GlobalAlias::create( - DeclTy, 0, getMultiversionLinkage(*this, GD), - MangledName + ".ifunc", IFunc, &getModule()); - SetCommonAttributes(FD, Alias); - } + // In prior versions of Clang, the mangling for ifuncs incorrectly + // included an .ifunc suffix. This alias is generated for backward + // compatibility. It is deprecated, and may be removed in the future. + auto *Alias = llvm::GlobalAlias::create( + DeclTy, 0, getMultiversionLinkage(*this, GD), + MangledName + ".ifunc", IFunc, &getModule()); + SetCommonAttributes(FD, Alias); } } llvm::Function *ResolverFunc = cast<llvm::Function>(ResolverConstant); @@ -4364,20 +4349,6 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { } } -/// Adds a declaration to the list of multi version functions if not present. -void CodeGenModule::AddDeferredMultiVersionResolverToEmit(GlobalDecl GD) { - const auto *FD = cast<FunctionDecl>(GD.getDecl()); - assert(FD && "Not a FunctionDecl?"); - - if (FD->isTargetVersionMultiVersion()) { - std::string MangledName = - getMangledNameImpl(*this, GD, FD, /*OmitMultiVersionMangling=*/true); - if (!DeferredResolversToEmit.insert(MangledName).second) - return; - } - MultiVersionFuncs.push_back(GD); -} - /// If a dispatcher for the specified mangled name is not in the module, create /// and return an llvm Function with the specified type. llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { @@ -4417,7 +4388,7 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { // The resolver needs to be created. For target and target_clones, defer // creation until the end of the TU. if (FD->isTargetMultiVersion() || FD->isTargetClonesMultiVersion()) - AddDeferredMultiVersionResolverToEmit(GD); + MultiVersionFuncs.push_back(GD); // For cpu_specific, don't create an ifunc yet because we don't know if the // cpu_dispatch will be emitted in this translation unit. diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 1cc447765e2c..ec34680fd3f7 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -348,8 +348,6 @@ private: /// yet. llvm::DenseMap<StringRef, GlobalDecl> DeferredDecls; - llvm::StringSet<llvm::BumpPtrAllocator> DeferredResolversToEmit; - /// This is a list of deferred decls which we have seen that *are* actually /// referenced. These get code generated when the module is done. std::vector<GlobalDecl> DeferredDeclsToEmit; @@ -1590,9 +1588,6 @@ private: llvm::AttributeList ExtraAttrs = llvm::AttributeList(), ForDefinition_t IsForDefinition = NotForDefinition); - // Adds a declaration to the list of multi version functions if not present. - void AddDeferredMultiVersionResolverToEmit(GlobalDecl GD); - // References to multiversion functions are resolved through an implicitly // defined resolver function. This function is responsible for creating // the resolver symbol for the provided declaration. The value returned diff --git a/clang/test/CodeGen/attr-target-version.c b/clang/test/CodeGen/attr-target-version.c index fc8bb680fe43..b7112c783da9 100644 --- a/clang/test/CodeGen/attr-target-version.c +++ b/clang/test/CodeGen/attr-target-version.c @@ -1,5 +1,5 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals --include-generated-funcs -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -v9.5a -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +ls64 -target-feature +fullfp16 -S -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fmv -S -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NOFMV int __attribute__((target_version("rng+flagm+fp16fml"))) fmv(void) { return 1; } @@ -11,15 +11,15 @@ int __attribute__((target_version("fp+aes"))) fmv(void) { return 6; } int __attribute__((target_version("crc+ls64_v"))) fmv(void) { return 7; } int __attribute__((target_version("bti"))) fmv(void) { return 8; } int __attribute__((target_version("sme2"))) fmv(void) { return 9; } -int __attribute__((target_version("default"))) fmv(void); +int __attribute__((target_version("default"))) fmv(void) { return 0; } int __attribute__((target_version("ls64+simd"))) fmv_one(void) { return 1; } int __attribute__((target_version("dpb"))) fmv_one(void) { return 2; } -int __attribute__((target_version("default"))) fmv_one(void); +int __attribute__((target_version("default"))) fmv_one(void) { return 0; } int __attribute__((target_version("fp"))) fmv_two(void) { return 1; } int __attribute__((target_version("simd"))) fmv_two(void) { return 2; } int __attribute__((target_version("dgh"))) fmv_two(void) { return 3; } int __attribute__((target_version("fp16+simd"))) fmv_two(void) { return 4; } -int __attribute__((target_version("default"))) fmv_two(void); +int __attribute__((target_version("default"))) fmv_two(void) { return 0; } int foo() { return fmv()+fmv_one()+fmv_two(); } @@ -84,33 +84,9 @@ int hoo(void) { return fp1() + fp2(); } -// This should generate one target version but no resolver. -__attribute__((target_version("default"))) int unused_with_forward_default_decl(void); -__attribute__((target_version("mops"))) int unused_with_forward_default_decl(void) { return 0; } -// This should also generate one target version but no resolver. -extern int unused_with_implicit_extern_forward_default_decl(void); -__attribute__((target_version("dotprod"))) -int unused_with_implicit_extern_forward_default_decl(void) { return 0; } -// This should also generate one target version but no resolver. -__attribute__((target_version("aes"))) int unused_with_default_decl(void) { return 0; } -__attribute__((target_version("default"))) int unused_with_default_decl(void); -// This should generate two target versions and the resolver. -__attribute__((target_version("sve"))) int unused_with_default_def(void) { return 0; } -__attribute__((target_version("default"))) int unused_with_default_def(void) { return 1; } - -// This should also generate two target versions and the resolver. -__attribute__((target_version("fp16"))) int unused_with_implicit_default_def(void) { return 0; } -int unused_with_implicit_default_def(void) { return 1; } - -// This should also generate two target versions and the resolver. -int unused_with_implicit_forward_default_def(void) { return 0; } -__attribute__((target_version("lse"))) int unused_with_implicit_forward_default_def(void) { return 1; } - -// This should generate a normal function. -__attribute__((target_version("rdm"))) int unused_without_default(void) { return 0; } //. // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } @@ -121,107 +97,38 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // CHECK: @fmv_c.ifunc = weak_odr alias void (), ptr @fmv_c // CHECK: @fmv_inline.ifunc = weak_odr alias i32 (), ptr @fmv_inline // CHECK: @fmv_d.ifunc = internal alias i32 (), ptr @fmv_d -// CHECK: @unused_with_default_def.ifunc = weak_odr alias i32 (), ptr @unused_with_default_def -// CHECK: @unused_with_implicit_default_def.ifunc = weak_odr alias i32 (), ptr @unused_with_implicit_default_def -// CHECK: @unused_with_implicit_forward_default_def.ifunc = weak_odr alias i32 (), ptr @unused_with_implicit_forward_default_def // CHECK: @fmv = weak_odr ifunc i32 (), ptr @fmv.resolver // CHECK: @fmv_one = weak_odr ifunc i32 (), ptr @fmv_one.resolver // CHECK: @fmv_two = weak_odr ifunc i32 (), ptr @fmv_two.resolver -// CHECK: @fmv_inline = weak_odr ifunc i32 (), ptr @fmv_inline.resolver // CHECK: @fmv_e = weak_odr ifunc i32 (), ptr @fmv_e.resolver -// CHECK: @fmv_d = internal ifunc i32 (), ptr @fmv_d.resolver // CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver -// CHECK: @unused_with_default_def = weak_odr ifunc i32 (), ptr @unused_with_default_def.resolver -// CHECK: @unused_with_implicit_default_def = weak_odr ifunc i32 (), ptr @unused_with_implicit_default_def.resolver -// CHECK: @unused_with_implicit_forward_default_def = weak_odr ifunc i32 (), ptr @unused_with_implicit_forward_default_def.resolver +// CHECK: @fmv_inline = weak_odr ifunc i32 (), ptr @fmv_inline.resolver +// CHECK: @fmv_d = internal ifunc i32 (), ptr @fmv_d.resolver //. // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Mflagm2Msme-i16i64 +// CHECK-LABEL: define {{[^@]+}}@fmv._MflagmMfp16fmlMrng // CHECK-SAME: () #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MlseMsha2 +// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mls64Msimd // CHECK-SAME: () #[[ATTR1:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 3 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MdotprodMls64_accdata -// CHECK-SAME: () #[[ATTR2:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 4 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Mfp16fmlMmemtag -// CHECK-SAME: () #[[ATTR3:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 5 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MaesMfp -// CHECK-SAME: () #[[ATTR4:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 6 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._McrcMls64_v -// CHECK-SAME: () #[[ATTR5:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 7 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Mbti -// CHECK-SAME: () #[[ATTR6:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 8 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Msme2 -// CHECK-SAME: () #[[ATTR7:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 9 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mdpb -// CHECK-SAME: () #[[ATTR8:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Msimd -// CHECK-SAME: () #[[ATTR4]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mdgh -// CHECK-SAME: () #[[ATTR9:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 3 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp16Msimd -// CHECK-SAME: () #[[ATTR10:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp +// CHECK-SAME: () #[[ATTR1]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 4 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@foo -// CHECK-SAME: () #[[ATTR9]] { +// CHECK-SAME: () #[[ATTR2:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv() // CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_one() @@ -251,16 +158,16 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // CHECK-NEXT: ret ptr @fmv._Mflagm2Msme-i16i64 // CHECK: resolver_else2: // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 9007199254741008 -// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 9007199254741008 +// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 16 +// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16 // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] // CHECK: resolver_return3: // CHECK-NEXT: ret ptr @fmv._MdotprodMls64_accdata // CHECK: resolver_else4: // CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 4503599627371520 -// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 4503599627371520 +// CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 1024 +// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 1024 // CHECK-NEXT: [[TMP15:%.*]] = and i1 true, [[TMP14]] // CHECK-NEXT: br i1 [[TMP15]], label [[RESOLVER_RETURN5:%.*]], label [[RESOLVER_ELSE6:%.*]] // CHECK: resolver_return5: @@ -275,8 +182,8 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // CHECK-NEXT: ret ptr @fmv._Mfp16fmlMmemtag // CHECK: resolver_else8: // CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 16640 -// CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 16640 +// CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 16384 +// CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 16384 // CHECK-NEXT: [[TMP23:%.*]] = and i1 true, [[TMP22]] // CHECK-NEXT: br i1 [[TMP23]], label [[RESOLVER_RETURN9:%.*]], label [[RESOLVER_ELSE10:%.*]] // CHECK: resolver_return9: @@ -311,95 +218,43 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // // CHECK-LABEL: define {{[^@]+}}@fmv_one.resolver() comdat { // CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2251799813685760 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2251799813685760 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: // CHECK-NEXT: ret ptr @fmv_one._Mls64Msimd -// CHECK: resolver_else: -// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 262144 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 262144 -// CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] -// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] -// CHECK: resolver_return1: -// CHECK-NEXT: ret ptr @fmv_one._Mdpb -// CHECK: resolver_else2: -// CHECK-NEXT: ret ptr @fmv_one.default // // // CHECK-LABEL: define {{[^@]+}}@fmv_two.resolver() comdat { // CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 66048 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 66048 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: // CHECK-NEXT: ret ptr @fmv_two._Mfp16Msimd -// CHECK: resolver_else: -// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 33554432 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 33554432 -// CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] -// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] -// CHECK: resolver_return1: -// CHECK-NEXT: ret ptr @fmv_two._Mdgh -// CHECK: resolver_else2: -// CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 512 -// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 512 -// CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] -// CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] -// CHECK: resolver_return3: -// CHECK-NEXT: ret ptr @fmv_two._Msimd -// CHECK: resolver_else4: -// CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 256 -// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 256 -// CHECK-NEXT: [[TMP15:%.*]] = and i1 true, [[TMP14]] -// CHECK-NEXT: br i1 [[TMP15]], label [[RESOLVER_RETURN5:%.*]], label [[RESOLVER_ELSE6:%.*]] -// CHECK: resolver_return5: -// CHECK-NEXT: ret ptr @fmv_two._Mfp -// CHECK: resolver_else6: -// CHECK-NEXT: ret ptr @fmv_two.default // // -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_e.default -// CHECK-SAME: () #[[ATTR9]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 20 +// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: ret ptr @fmv_e._Mls64 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_default -// CHECK-SAME: () #[[ATTR9]] { +// CHECK-SAME: () #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 111 // // -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs -// CHECK-SAME: () #[[ATTR9]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret void -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_c.default -// CHECK-SAME: () #[[ATTR9]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret void +// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @fmv_c._Mssbs +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @fmv_c.default // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@goo -// CHECK-SAME: () #[[ATTR9]] { +// CHECK-SAME: () #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv_inline() // CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_e() @@ -413,8 +268,8 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398048673856 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398048673856 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398048608320 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398048608320 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: @@ -509,8 +364,8 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // CHECK-NEXT: ret ptr @fmv_inline._Mdpb2Mjscvt // CHECK: resolver_else22: // CHECK-NEXT: [[TMP48:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP49:%.*]] = and i64 [[TMP48]], 520 -// CHECK-NEXT: [[TMP50:%.*]] = icmp eq i64 [[TMP49]], 520 +// CHECK-NEXT: [[TMP49:%.*]] = and i64 [[TMP48]], 8 +// CHECK-NEXT: [[TMP50:%.*]] = icmp eq i64 [[TMP49]], 8 // CHECK-NEXT: [[TMP51:%.*]] = and i1 true, [[TMP50]] // CHECK-NEXT: br i1 [[TMP51]], label [[RESOLVER_RETURN23:%.*]], label [[RESOLVER_ELSE24:%.*]] // CHECK: resolver_return23: @@ -533,8 +388,8 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // CHECK-NEXT: ret ptr @fmv_inline._MlseMrdm // CHECK: resolver_else28: // CHECK-NEXT: [[TMP60:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP61:%.*]] = and i64 [[TMP60]], 288 -// CHECK-NEXT: [[TMP62:%.*]] = icmp eq i64 [[TMP61]], 288 +// CHECK-NEXT: [[TMP61:%.*]] = and i64 [[TMP60]], 32 +// CHECK-NEXT: [[TMP62:%.*]] = icmp eq i64 [[TMP61]], 32 // CHECK-NEXT: [[TMP63:%.*]] = and i1 true, [[TMP62]] // CHECK-NEXT: br i1 [[TMP63]], label [[RESOLVER_RETURN29:%.*]], label [[RESOLVER_ELSE30:%.*]] // CHECK: resolver_return29: @@ -543,20 +398,6 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // CHECK-NEXT: ret ptr @fmv_inline.default // // -// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2251799813685248 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2251799813685248 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: -// CHECK-NEXT: ret ptr @fmv_e._Mls64 -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @fmv_e.default -// -// // CHECK-LABEL: define {{[^@]+}}@fmv_d.resolver() { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -571,23 +412,9 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // CHECK-NEXT: ret ptr @fmv_d.default // // -// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: -// CHECK-NEXT: ret ptr @fmv_c._Mssbs -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @fmv_c.default -// -// // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@recur -// CHECK-SAME: () #[[ATTR9]] { +// CHECK-SAME: () #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: call void @reca() // CHECK-NEXT: ret void @@ -595,7 +422,7 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@main -// CHECK-SAME: () #[[ATTR9]] { +// CHECK-SAME: () #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 @@ -606,7 +433,7 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@hoo -// CHECK-SAME: () #[[ATTR9]] { +// CHECK-SAME: () #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FP1:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[FP2:%.*]] = alloca ptr, align 8 @@ -622,274 +449,288 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_forward_default_decl._Mmops -// CHECK-SAME: () #[[ATTR12:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._Mflagm2Msme-i16i64 +// CHECK-SAME: () #[[ATTR4:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 +// CHECK-NEXT: ret i32 2 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_extern_forward_default_decl._Mdotprod -// CHECK-SAME: () #[[ATTR13:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._MlseMsha2 +// CHECK-SAME: () #[[ATTR5:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 +// CHECK-NEXT: ret i32 3 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def.default -// CHECK-SAME: () #[[ATTR9]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._MdotprodMls64_accdata +// CHECK-SAME: () #[[ATTR6:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 4 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def.default -// CHECK-SAME: () #[[ATTR9]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._Mfp16fmlMmemtag +// CHECK-SAME: () #[[ATTR7:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 5 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def.default -// CHECK-SAME: () #[[ATTR9]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._MaesMfp +// CHECK-SAME: () #[[ATTR1]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 +// CHECK-NEXT: ret i32 6 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def._Mlse -// CHECK-SAME: () #[[ATTR14:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._McrcMls64_v +// CHECK-SAME: () #[[ATTR8:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 7 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MflagmMfp16fmlMrng -// CHECK-SAME: () #[[ATTR15:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._Mbti +// CHECK-SAME: () #[[ATTR9:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 8 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mls64Msimd -// CHECK-SAME: () #[[ATTR4]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._Msme2 +// CHECK-SAME: () #[[ATTR10:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 9 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp -// CHECK-SAME: () #[[ATTR4]] { +// CHECK-LABEL: define {{[^@]+}}@fmv.default +// CHECK-SAME: () #[[ATTR2]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_default_decl._Maes -// CHECK-SAME: () #[[ATTR4]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mdpb +// CHECK-SAME: () #[[ATTR11:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 +// CHECK-NEXT: ret i32 2 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def._Msve -// CHECK-SAME: () #[[ATTR16:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_one.default +// CHECK-SAME: () #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def._Mfp16 -// CHECK-SAME: () #[[ATTR10]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Msimd +// CHECK-SAME: () #[[ATTR1]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 2 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mdgh +// CHECK-SAME: () #[[ATTR2]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 +// CHECK-NEXT: ret i32 3 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@unused_without_default -// CHECK-SAME: () #[[ATTR17:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp16Msimd +// CHECK-SAME: () #[[ATTR1]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 4 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_two.default +// CHECK-SAME: () #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_e.default +// CHECK-SAME: () #[[ATTR2]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 20 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_c.default +// CHECK-SAME: () #[[ATTR2]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret void +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs +// CHECK-SAME: () #[[ATTR2]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret void +// +// +// CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mf64mmMpmullMsha1 -// CHECK-SAME: () #[[ATTR18:[0-9]+]] { +// CHECK-SAME: () #[[ATTR12:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfcmaMfp16MrdmMsme -// CHECK-SAME: () #[[ATTR19:[0-9]+]] { +// CHECK-SAME: () #[[ATTR13:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 2 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mf32mmMi8mmMsha3 -// CHECK-SAME: () #[[ATTR20:[0-9]+]] { +// CHECK-SAME: () #[[ATTR14:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 12 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MditMsve-ebf16 -// CHECK-SAME: () #[[ATTR21:[0-9]+]] { +// CHECK-SAME: () #[[ATTR15:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 8 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MdpbMrcpc2 -// CHECK-SAME: () #[[ATTR22:[0-9]+]] { +// CHECK-SAME: () #[[ATTR16:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 6 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mdpb2Mjscvt -// CHECK-SAME: () #[[ATTR23:[0-9]+]] { +// CHECK-SAME: () #[[ATTR17:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 7 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfrinttsMrcpc -// CHECK-SAME: () #[[ATTR24:[0-9]+]] { +// CHECK-SAME: () #[[ATTR18:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 3 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MsveMsve-bf16 -// CHECK-SAME: () #[[ATTR25:[0-9]+]] { +// CHECK-SAME: () #[[ATTR19:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 4 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Msve2-aesMsve2-sha3 -// CHECK-SAME: () #[[ATTR26:[0-9]+]] { +// CHECK-SAME: () #[[ATTR20:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 5 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Msve2Msve2-bitpermMsve2-pmull128 -// CHECK-SAME: () #[[ATTR27:[0-9]+]] { +// CHECK-SAME: () #[[ATTR21:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 9 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mmemtag2Msve2-sm4 -// CHECK-SAME: () #[[ATTR28:[0-9]+]] { +// CHECK-SAME: () #[[ATTR22:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 10 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mmemtag3MmopsMrcpc3 -// CHECK-SAME: () #[[ATTR29:[0-9]+]] { +// CHECK-SAME: () #[[ATTR23:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 11 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MaesMdotprod -// CHECK-SAME: () #[[ATTR13]] { +// CHECK-SAME: () #[[ATTR6]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 13 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mfp16fmlMsimd -// CHECK-SAME: () #[[ATTR3]] { +// CHECK-SAME: () #[[ATTR7]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 14 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfpMsm4 -// CHECK-SAME: () #[[ATTR30:[0-9]+]] { +// CHECK-SAME: () #[[ATTR24:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 15 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MlseMrdm -// CHECK-SAME: () #[[ATTR31:[0-9]+]] { +// CHECK-SAME: () #[[ATTR25:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 16 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline.default -// CHECK-SAME: () #[[ATTR9]] { +// CHECK-SAME: () #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 3 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_d._Msb -// CHECK-SAME: () #[[ATTR32:[0-9]+]] { +// CHECK-SAME: () #[[ATTR26:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_d.default -// CHECK-SAME: () #[[ATTR9]] { +// CHECK-SAME: () #[[ATTR2]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: -// CHECK-NEXT: ret ptr @unused_with_default_def._Msve -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @unused_with_default_def.default +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv +// CHECK-NOFMV-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 0 // // -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65536 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65536 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: -// CHECK-NEXT: ret ptr @unused_with_implicit_default_def._Mfp16 -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @unused_with_implicit_default_def.default +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_one +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 0 // // -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 128 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 128 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: -// CHECK-NEXT: ret ptr @unused_with_implicit_forward_default_def._Mlse -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @unused_with_implicit_forward_default_def.default +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_two +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 0 // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone // CHECK-NOFMV-LABEL: define {{[^@]+}}@foo -// CHECK-NOFMV-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK-NOFMV-SAME: () #[[ATTR0]] { // CHECK-NOFMV-NEXT: entry: // CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 @fmv() // CHECK-NOFMV-NEXT: [[CALL1:%.*]] = call i32 @fmv_one() @@ -974,61 +815,34 @@ __attribute__((target_version("rdm"))) int unused_without_default(void) { return // CHECK-NOFMV-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] // CHECK-NOFMV-NEXT: ret i32 [[ADD]] // -// -// CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_default_def -// CHECK-NOFMV-SAME: () #[[ATTR0]] { -// CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 1 -// -// -// CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_implicit_default_def -// CHECK-NOFMV-SAME: () #[[ATTR0]] { -// CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 1 -// -// -// CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def -// CHECK-NOFMV-SAME: () #[[ATTR0]] { -// CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 0 -// //. -// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+altnzcv,+bf16,+flagm,+sme,+sme-i16i64,-v9.5a" } -// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon,+sha2,-v9.5a" } -// CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+ls64,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR3]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fp16fml,+fullfp16,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,-v9.5a" } -// CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti,-v9.5a" } -// CHECK: attributes #[[ATTR7]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme2,-v9.5a" } -// CHECK: attributes #[[ATTR8]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,-v9.5a" } -// CHECK: attributes #[[ATTR9]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-v9.5a" } -// CHECK: attributes #[[ATTR10]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR11:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-v9.5a" } -// CHECK: attributes #[[ATTR12]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops,-v9.5a" } -// CHECK: attributes #[[ATTR13]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR14]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-v9.5a" } -// CHECK: attributes #[[ATTR15]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+flagm,+fp-armv8,+fp16fml,+fullfp16,+neon,+rand,-v9.5a" } -// CHECK: attributes #[[ATTR16]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } -// CHECK: attributes #[[ATTR17]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm,-v9.5a" } -// CHECK: attributes #[[ATTR18]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+aes,+f64mm,+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } -// CHECK: attributes #[[ATTR19]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+complxnum,+fp-armv8,+fullfp16,+neon,+rdm,+sme,-v9.5a" } -// CHECK: attributes #[[ATTR20]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+f32mm,+fp-armv8,+fullfp16,+i8mm,+neon,+sha2,+sha3,+sve,-v9.5a" } -// CHECK: attributes #[[ATTR21]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+dit,+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } -// CHECK: attributes #[[ATTR22]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+rcpc,-v9.5a" } -// CHECK: attributes #[[ATTR23]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccdp,+ccpp,+fp-armv8,+jsconv,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR24]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint,+rcpc,-v9.5a" } -// CHECK: attributes #[[ATTR25]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+fullfp16,+neon,+sve,-v9.5a" } -// CHECK: attributes #[[ATTR26]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-aes,+sve2-sha3,-v9.5a" } -// CHECK: attributes #[[ATTR27]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-aes,+sve2-bitperm,-v9.5a" } -// CHECK: attributes #[[ATTR28]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+mte,+neon,+sve,+sve2,+sve2-sm4,-v9.5a" } -// CHECK: attributes #[[ATTR29]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops,+mte,+rcpc,+rcpc3,-v9.5a" } -// CHECK: attributes #[[ATTR30]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+sm4,-v9.5a" } -// CHECK: attributes #[[ATTR31]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon,+rdm,-v9.5a" } -// CHECK: attributes #[[ATTR32]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+sb,-v9.5a" } +// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+flagm,+fp-armv8,+fp16fml,+fullfp16,+ls64,+neon,+rand" } +// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon" } +// CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } +// CHECK: attributes #[[ATTR3:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } +// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+altnzcv,+bf16,+flagm,+fullfp16,+ls64,+sme,+sme-i16i64" } +// CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+lse,+neon,+sha2" } +// CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+fullfp16,+ls64,+neon" } +// CHECK: attributes #[[ATTR7]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fp16fml,+fullfp16,+ls64,+neon" } +// CHECK: attributes #[[ATTR8]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,+fullfp16,+ls64" } +// CHECK: attributes #[[ATTR9]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti,+fullfp16,+ls64" } +// CHECK: attributes #[[ATTR10]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fullfp16,+ls64,+sme,+sme2" } +// CHECK: attributes #[[ATTR11]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+fullfp16,+ls64" } +// CHECK: attributes #[[ATTR12]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+aes,+f64mm,+fp-armv8,+fullfp16,+ls64,+neon,+sve" } +// CHECK: attributes #[[ATTR13]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+complxnum,+fp-armv8,+fullfp16,+ls64,+neon,+rdm,+sme" } +// CHECK: attributes #[[ATTR14]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+f32mm,+fp-armv8,+fullfp16,+i8mm,+ls64,+neon,+sha2,+sha3,+sve" } +// CHECK: attributes #[[ATTR15]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+dit,+fp-armv8,+fullfp16,+ls64,+neon,+sve" } +// CHECK: attributes #[[ATTR16]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+fullfp16,+ls64,+rcpc" } +// CHECK: attributes #[[ATTR17]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccdp,+ccpp,+fp-armv8,+fullfp16,+jsconv,+ls64,+neon" } +// CHECK: attributes #[[ATTR18]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint,+fullfp16,+ls64,+rcpc" } +// CHECK: attributes #[[ATTR19]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+fullfp16,+ls64,+neon,+sve" } +// CHECK: attributes #[[ATTR20]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon,+sve,+sve2,+sve2-aes,+sve2-sha3" } +// CHECK: attributes #[[ATTR21]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon,+sve,+sve2,+sve2-aes,+sve2-bitperm" } +// CHECK: attributes #[[ATTR22]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+mte,+neon,+sve,+sve2,+sve2-sm4" } +// CHECK: attributes #[[ATTR23]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64,+mops,+mte,+rcpc,+rcpc3" } +// CHECK: attributes #[[ATTR24]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon,+sm4" } +// CHECK: attributes #[[ATTR25]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+lse,+neon,+rdm" } +// CHECK: attributes #[[ATTR26]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64,+sb" } //. // CHECK-NOFMV: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" } // CHECK-NOFMV: attributes #[[ATTR1:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" } diff --git a/clang/test/CodeGenCXX/attr-target-version.cpp b/clang/test/CodeGenCXX/attr-target-version.cpp index e06121d1a719..82a928a385e1 100644 --- a/clang/test/CodeGenCXX/attr-target-version.cpp +++ b/clang/test/CodeGenCXX/attr-target-version.cpp @@ -10,196 +10,41 @@ struct MyClass { int __attribute__((target_version("dotprod"))) goo(int); int __attribute__((target_version("crc"))) goo(int); int __attribute__((target_version("default"))) goo(int); - - // This should generate one target version but no resolver. - int __attribute__((target_version("default"))) unused_with_forward_default_decl(void); - int __attribute__((target_version("mops"))) unused_with_forward_default_decl(void); - - // This should also generate one target version but no resolver. - int unused_with_implicit_forward_default_decl(void); - int __attribute__((target_version("dotprod"))) unused_with_implicit_forward_default_decl(void); - - // This should also generate one target version but no resolver. - int __attribute__((target_version("aes"))) unused_with_default_decl(void); - int __attribute__((target_version("default"))) unused_with_default_decl(void); - - // This should generate two target versions and the resolver. - int __attribute__((target_version("sve"))) unused_with_default_def(void); - int __attribute__((target_version("default"))) unused_with_default_def(void); - - // This should also generate two target versions and the resolver. - int __attribute__((target_version("fp16"))) unused_with_implicit_default_def(void); - int unused_with_implicit_default_def(void); - - // This should also generate two target versions and the resolver. - int unused_with_implicit_forward_default_def(void); - int __attribute__((target_version("lse"))) unused_with_implicit_forward_default_def(void); - - // This should generate a normal function. - int __attribute__((target_version("rdm"))) unused_without_default(void); }; int __attribute__((target_version("default"))) MyClass::goo(int) { return 1; } int __attribute__((target_version("crc"))) MyClass::goo(int) { return 2; } int __attribute__((target_version("dotprod"))) MyClass::goo(int) { return 3; } -int __attribute__((target_version("mops"))) MyClass::unused_with_forward_default_decl(void) { return 0; } -int __attribute__((target_version("dotprod"))) MyClass::unused_with_implicit_forward_default_decl(void) { return 0; } -int __attribute__((target_version("aes"))) MyClass::unused_with_default_decl(void) { return 0; } -int __attribute__((target_version("sve"))) MyClass::unused_with_default_def(void) { return 0; } -int __attribute__((target_version("default"))) MyClass::unused_with_default_def(void) { return 1; } -int __attribute__((target_version("fp16"))) MyClass::unused_with_implicit_default_def(void) { return 0; } -int MyClass::unused_with_implicit_default_def(void) { return 1; } -int MyClass::unused_with_implicit_forward_default_def(void) { return 0; } -int __attribute__((target_version("lse"))) MyClass::unused_with_implicit_forward_default_def(void) { return 1; } -int __attribute__((target_version("rdm"))) MyClass::unused_without_default(void) { return 0; } - int bar() { MyClass m; return m.goo(1) + foo(1) + foo(); } + + //. // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } +// CHECK: @_ZN7MyClass3gooEi.ifunc = weak_odr alias i32 (ptr, i32), ptr @_ZN7MyClass3gooEi // CHECK: @_Z3fooi.ifunc = weak_odr alias i32 (i32), ptr @_Z3fooi // CHECK: @_Z3foov.ifunc = weak_odr alias i32 (), ptr @_Z3foov -// CHECK: @_ZN7MyClass3gooEi.ifunc = weak_odr alias i32 (ptr, i32), ptr @_ZN7MyClass3gooEi -// CHECK: @_ZN7MyClass23unused_with_default_defEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN7MyClass23unused_with_default_defEv -// CHECK: @_ZN7MyClass32unused_with_implicit_default_defEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN7MyClass32unused_with_implicit_default_defEv -// CHECK: @_ZN7MyClass40unused_with_implicit_forward_default_defEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv // CHECK: @_ZN7MyClass3gooEi = weak_odr ifunc i32 (ptr, i32), ptr @_ZN7MyClass3gooEi.resolver // CHECK: @_Z3fooi = weak_odr ifunc i32 (i32), ptr @_Z3fooi.resolver // CHECK: @_Z3foov = weak_odr ifunc i32 (), ptr @_Z3foov.resolver -// CHECK: @_ZN7MyClass23unused_with_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass23unused_with_default_defEv.resolver -// CHECK: @_ZN7MyClass32unused_with_implicit_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass32unused_with_implicit_default_defEv.resolver -// CHECK: @_ZN7MyClass40unused_with_implicit_forward_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver //. -// CHECK-LABEL: @_Z3fooi.default( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 -// CHECK-NEXT: ret i32 2 -// -// -// CHECK-LABEL: @_Z3foov.default( -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 4 -// -// -// CHECK-LABEL: @_ZN7MyClass3gooEi.default( +// CHECK-LABEL: @_Z3fooi._Mbf16Msme-f64f64( // CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_ZN7MyClass3gooEi._Mcrc( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 2 -// -// -// CHECK-LABEL: @_ZN7MyClass3gooEi._Mdotprod( +// CHECK-LABEL: @_Z3foov._Mebf16Msm4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 3 // // -// CHECK-LABEL: @_ZN7MyClass32unused_with_forward_default_declEv._Mmops( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 0 -// -// -// CHECK-LABEL: @_ZN7MyClass41unused_with_implicit_forward_default_declEv._Mdotprod( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 0 -// -// -// CHECK-LABEL: @_ZN7MyClass24unused_with_default_declEv._Maes( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 0 -// -// -// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv._Msve( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 0 -// -// -// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv.default( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 1 -// -// -// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv._Mfp16( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 0 -// -// -// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv.default( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 1 -// -// -// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv.default( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 0 -// -// -// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv._Mlse( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 1 -// -// -// CHECK-LABEL: @_Z3barv( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[M:%.*]] = alloca [[STRUCT_MYCLASS:%.*]], align 1 -// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN7MyClass3gooEi(ptr noundef nonnull align 1 dereferenceable(1) [[M]], i32 noundef 1) -// CHECK-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z3fooi(i32 noundef 1) -// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] -// CHECK-NEXT: [[CALL2:%.*]] = call noundef i32 @_Z3foov() -// CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]] -// CHECK-NEXT: ret i32 [[ADD3]] -// -// // CHECK-LABEL: @_ZN7MyClass3gooEi.resolver( // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -222,6 +67,17 @@ int bar() { // CHECK-NEXT: ret ptr @_ZN7MyClass3gooEi.default // // +// CHECK-LABEL: @_Z3barv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[M:%.*]] = alloca [[STRUCT_MYCLASS:%.*]], align 1 +// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN7MyClass3gooEi(ptr noundef nonnull align 1 dereferenceable(1) [[M]], i32 noundef 1) +// CHECK-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z3fooi(i32 noundef 1) +// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] +// CHECK-NEXT: [[CALL2:%.*]] = call noundef i32 @_Z3foov() +// CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]] +// CHECK-NEXT: ret i32 [[ADD3]] +// +// // CHECK-LABEL: @_Z3fooi.resolver( // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -250,80 +106,53 @@ int bar() { // CHECK-NEXT: ret ptr @_Z3foov.default // // -// CHECK-LABEL: @_Z3fooi._Mbf16Msme-f64f64( +// CHECK-LABEL: @_ZN7MyClass3gooEi._Mdotprod( // CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 -// CHECK-NEXT: ret i32 1 -// -// -// CHECK-LABEL: @_Z3foov._Mebf16Msm4( -// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 3 // // -// CHECK-LABEL: @_ZN7MyClass22unused_without_defaultEv( +// CHECK-LABEL: @_ZN7MyClass3gooEi._Mcrc( // CHECK-NEXT: entry: // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 // CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 0 +// CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv.resolver( -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: -// CHECK-NEXT: ret ptr @_ZN7MyClass23unused_with_default_defEv._Msve -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @_ZN7MyClass23unused_with_default_defEv.default +// CHECK-LABEL: @_ZN7MyClass3gooEi.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv.resolver( -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65536 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65536 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: -// CHECK-NEXT: ret ptr @_ZN7MyClass32unused_with_implicit_default_defEv._Mfp16 -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @_ZN7MyClass32unused_with_implicit_default_defEv.default +// CHECK-LABEL: @_Z3fooi.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver( -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 128 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 128 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: -// CHECK-NEXT: ret ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv._Mlse -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.default +// CHECK-LABEL: @_Z3foov.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 4 // //. -// CHECK: attributes #[[ATTR0:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -// CHECK: attributes #[[ATTR1:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc" } -// CHECK: attributes #[[ATTR2:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon" } -// CHECK: attributes #[[ATTR3:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops" } -// CHECK: attributes #[[ATTR4:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon" } -// CHECK: attributes #[[ATTR5:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } -// CHECK: attributes #[[ATTR6:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" } -// CHECK: attributes #[[ATTR7:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse" } -// CHECK: attributes #[[ATTR8:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } -// CHECK: attributes #[[ATTR9:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+neon,+sm4" } -// CHECK: attributes #[[ATTR10:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm" } -// CHECK: attributes #[[ATTR11:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR0:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } +// CHECK: attributes #[[ATTR1:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+neon,+sm4" } +// CHECK: attributes #[[ATTR2:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR3:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon" } +// CHECK: attributes #[[ATTR4:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc" } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} -- GitLab From d93cfd8dab577b09a8d01ef10a279b02572e4814 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Wed, 20 Mar 2024 11:16:35 +0100 Subject: [PATCH 215/307] [bazel] Add a missing dependency for aa95aa69b96f51a3c19a24a0387ebc1fb7e6e52c --- utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 1d98b986f481..59b0bbbda2f5 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -67,6 +67,7 @@ config_setting( libc_support_library( name = "llvm_libc_macros_math_macros", hdrs = ["include/llvm-libc-macros/math-macros.h"], + deps = [":llvm_libc_macros_limits_macros"], ) libc_support_library( -- GitLab From 7227ec98ad9a5e8e973d0c831e6f8bc0f7029f9f Mon Sep 17 00:00:00 2001 From: Nikolas Klauser <nikolasklauser@berlin.de> Date: Wed, 20 Mar 2024 11:23:48 +0100 Subject: [PATCH 216/307] [libc++][NFC] Remove uses of add_{const,cv,volatile} (#85635) These traits can be expressed without having to instantiate any classes, reducing compile times slightly. --- libcxx/include/__iterator/iterator_traits.h | 5 ++--- libcxx/include/__iterator/ranges_iterator_traits.h | 4 +--- libcxx/include/__tuple/tuple_element.h | 9 +++------ libcxx/include/__type_traits/copy_cv.h | 9 +++------ libcxx/include/__type_traits/is_assignable.h | 6 ++---- libcxx/include/__type_traits/is_constructible.h | 4 +--- libcxx/include/__type_traits/is_nothrow_assignable.h | 7 +++---- libcxx/include/__type_traits/is_nothrow_constructible.h | 7 ++----- libcxx/include/__type_traits/is_trivially_assignable.h | 6 +++--- 9 files changed, 20 insertions(+), 37 deletions(-) diff --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h index 2cd82525ba06..11af9e301842 100644 --- a/libcxx/include/__iterator/iterator_traits.h +++ b/libcxx/include/__iterator/iterator_traits.h @@ -21,7 +21,6 @@ #include <__fwd/pair.h> #include <__iterator/incrementable_traits.h> #include <__iterator/readable_traits.h> -#include <__type_traits/add_const.h> #include <__type_traits/common_reference.h> #include <__type_traits/conditional.h> #include <__type_traits/disjunction.h> @@ -493,8 +492,8 @@ using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type: template <class _InputIterator> using __iter_to_alloc_type = - pair< typename add_const<typename iterator_traits<_InputIterator>::value_type::first_type>::type, - typename iterator_traits<_InputIterator>::value_type::second_type>; + pair<const typename iterator_traits<_InputIterator>::value_type::first_type, + typename iterator_traits<_InputIterator>::value_type::second_type>; template <class _Iter> using __iterator_category_type = typename iterator_traits<_Iter>::iterator_category; diff --git a/libcxx/include/__iterator/ranges_iterator_traits.h b/libcxx/include/__iterator/ranges_iterator_traits.h index a30864199df7..859e7082048a 100644 --- a/libcxx/include/__iterator/ranges_iterator_traits.h +++ b/libcxx/include/__iterator/ranges_iterator_traits.h @@ -13,7 +13,6 @@ #include <__config> #include <__fwd/pair.h> #include <__ranges/concepts.h> -#include <__type_traits/add_const.h> #include <__type_traits/remove_const.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -32,8 +31,7 @@ using __range_mapped_type = typename ranges::range_value_t<_Range>::second_type; template <ranges::input_range _Range> using __range_to_alloc_type = - pair<add_const_t<typename ranges::range_value_t<_Range>::first_type>, - typename ranges::range_value_t<_Range>::second_type>; + pair<const typename ranges::range_value_t<_Range>::first_type, typename ranges::range_value_t<_Range>::second_type>; #endif diff --git a/libcxx/include/__tuple/tuple_element.h b/libcxx/include/__tuple/tuple_element.h index 2b9ac6696ca4..55b3b47619f6 100644 --- a/libcxx/include/__tuple/tuple_element.h +++ b/libcxx/include/__tuple/tuple_element.h @@ -12,9 +12,6 @@ #include <__config> #include <__tuple/tuple_indices.h> #include <__tuple/tuple_types.h> -#include <__type_traits/add_const.h> -#include <__type_traits/add_cv.h> -#include <__type_traits/add_volatile.h> #include <cstddef> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -28,17 +25,17 @@ struct _LIBCPP_TEMPLATE_VIS tuple_element; template <size_t _Ip, class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp> { - typedef _LIBCPP_NODEBUG typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type; + typedef _LIBCPP_NODEBUG const typename tuple_element<_Ip, _Tp>::type type; }; template <size_t _Ip, class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp> { - typedef _LIBCPP_NODEBUG typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type; + typedef _LIBCPP_NODEBUG volatile typename tuple_element<_Ip, _Tp>::type type; }; template <size_t _Ip, class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp> { - typedef _LIBCPP_NODEBUG typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type; + typedef _LIBCPP_NODEBUG const volatile typename tuple_element<_Ip, _Tp>::type type; }; #ifndef _LIBCPP_CXX03_LANG diff --git a/libcxx/include/__type_traits/copy_cv.h b/libcxx/include/__type_traits/copy_cv.h index 3c4ee857f7bc..b1c057ff778b 100644 --- a/libcxx/include/__type_traits/copy_cv.h +++ b/libcxx/include/__type_traits/copy_cv.h @@ -10,9 +10,6 @@ #define _LIBCPP___TYPE_TRAITS_COPY_CV_H #include <__config> -#include <__type_traits/add_const.h> -#include <__type_traits/add_cv.h> -#include <__type_traits/add_volatile.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -29,17 +26,17 @@ struct __copy_cv { template <class _From, class _To> struct __copy_cv<const _From, _To> { - using type = typename add_const<_To>::type; + using type = const _To; }; template <class _From, class _To> struct __copy_cv<volatile _From, _To> { - using type = typename add_volatile<_To>::type; + using type = volatile _To; }; template <class _From, class _To> struct __copy_cv<const volatile _From, _To> { - using type = typename add_cv<_To>::type; + using type = const volatile _To; }; template <class _From, class _To> diff --git a/libcxx/include/__type_traits/is_assignable.h b/libcxx/include/__type_traits/is_assignable.h index 1398d42e7546..cfb469977787 100644 --- a/libcxx/include/__type_traits/is_assignable.h +++ b/libcxx/include/__type_traits/is_assignable.h @@ -10,7 +10,6 @@ #define _LIBCPP___TYPE_TRAITS_IS_ASSIGNABLE_H #include <__config> -#include <__type_traits/add_const.h> #include <__type_traits/add_lvalue_reference.h> #include <__type_traits/add_rvalue_reference.h> #include <__type_traits/integral_constant.h> @@ -31,9 +30,8 @@ inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Arg); template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_copy_assignable - : public integral_constant< - bool, - __is_assignable(__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {}; + : public integral_constant<bool, + __is_assignable(__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<const _Tp>)> {}; #if _LIBCPP_STD_VER >= 17 template <class _Tp> diff --git a/libcxx/include/__type_traits/is_constructible.h b/libcxx/include/__type_traits/is_constructible.h index e2753156709e..567bd165c715 100644 --- a/libcxx/include/__type_traits/is_constructible.h +++ b/libcxx/include/__type_traits/is_constructible.h @@ -10,7 +10,6 @@ #define _LIBCPP___TYPE_IS_CONSTRUCTIBLE_H #include <__config> -#include <__type_traits/add_const.h> #include <__type_traits/add_lvalue_reference.h> #include <__type_traits/add_rvalue_reference.h> #include <__type_traits/integral_constant.h> @@ -31,8 +30,7 @@ inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...); template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_copy_constructible - : public integral_constant<bool, __is_constructible(_Tp, __add_lvalue_reference_t<typename add_const<_Tp>::type>)> { -}; + : public integral_constant<bool, __is_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)> {}; #if _LIBCPP_STD_VER >= 17 template <class _Tp> diff --git a/libcxx/include/__type_traits/is_nothrow_assignable.h b/libcxx/include/__type_traits/is_nothrow_assignable.h index adbf0cde9348..7e00c741f83e 100644 --- a/libcxx/include/__type_traits/is_nothrow_assignable.h +++ b/libcxx/include/__type_traits/is_nothrow_assignable.h @@ -10,7 +10,6 @@ #define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_ASSIGNABLE_H #include <__config> -#include <__type_traits/add_const.h> #include <__type_traits/add_lvalue_reference.h> #include <__type_traits/add_rvalue_reference.h> #include <__type_traits/integral_constant.h> @@ -32,9 +31,9 @@ inline constexpr bool is_nothrow_assignable_v = __is_nothrow_assignable(_Tp, _Ar template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_assignable - : public integral_constant<bool, - __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>, - __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {}; + : public integral_constant< + bool, + __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<const _Tp>)> {}; #if _LIBCPP_STD_VER >= 17 template <class _Tp> diff --git a/libcxx/include/__type_traits/is_nothrow_constructible.h b/libcxx/include/__type_traits/is_nothrow_constructible.h index fdf23c4dabfe..2f7ed8487e76 100644 --- a/libcxx/include/__type_traits/is_nothrow_constructible.h +++ b/libcxx/include/__type_traits/is_nothrow_constructible.h @@ -10,7 +10,6 @@ #define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_CONSTRUCTIBLE_H #include <__config> -#include <__type_traits/add_const.h> #include <__type_traits/add_lvalue_reference.h> #include <__type_traits/add_rvalue_reference.h> #include <__type_traits/integral_constant.h> @@ -74,15 +73,13 @@ inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<_Tp, template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible - : public is_nothrow_constructible<_Tp, __add_lvalue_reference_t<typename add_const<_Tp>::type> > {}; + : public is_nothrow_constructible<_Tp, __add_lvalue_reference_t<const _Tp> > {}; #else // _LIBCPP_COMPILER_GCC template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible - : public integral_constant< - bool, - __is_nothrow_constructible(_Tp, typename add_lvalue_reference<typename add_const<_Tp>::type>::type)> {}; + : public integral_constant< bool, __is_nothrow_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)> {}; #endif // _LIBCPP_COMPILER_GCC diff --git a/libcxx/include/__type_traits/is_trivially_assignable.h b/libcxx/include/__type_traits/is_trivially_assignable.h index c0b8deed93f6..201333b0fa0b 100644 --- a/libcxx/include/__type_traits/is_trivially_assignable.h +++ b/libcxx/include/__type_traits/is_trivially_assignable.h @@ -31,9 +31,9 @@ inline constexpr bool is_trivially_assignable_v = __is_trivially_assignable(_Tp, template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_assignable - : public integral_constant<bool, - __is_trivially_assignable(__add_lvalue_reference_t<_Tp>, - __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {}; + : public integral_constant< + bool, + __is_trivially_assignable(__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<const _Tp>)> {}; #if _LIBCPP_STD_VER >= 17 template <class _Tp> -- GitLab From 36a3f8f6471ba04b7ebf32a3393708b8fb32aecf Mon Sep 17 00:00:00 2001 From: Graham Hunter <graham.hunter@arm.com> Date: Wed, 20 Mar 2024 10:28:46 +0000 Subject: [PATCH 217/307] [TTI][TLI][AArch64] Support scalable immediates with isLegalAddImmediate (#84173) Adds a second parameter (default to 0) to isLegalAddImmediate, to represent a scalable immediate. Extends the AArch64 implementation to match immediates based on what addvl and inc[h|w|d] support. --- .../llvm/Analysis/TargetTransformInfo.h | 10 ++ .../llvm/Analysis/TargetTransformInfoImpl.h | 2 + llvm/include/llvm/CodeGen/BasicTTIImpl.h | 4 + llvm/include/llvm/CodeGen/TargetLowering.h | 6 + llvm/lib/Analysis/TargetTransformInfo.cpp | 4 + .../Target/AArch64/AArch64ISelLowering.cpp | 32 ++++++ llvm/lib/Target/AArch64/AArch64ISelLowering.h | 1 + llvm/unittests/Target/AArch64/CMakeLists.txt | 1 + llvm/unittests/Target/AArch64/Immediates.cpp | 106 ++++++++++++++++++ 9 files changed, 166 insertions(+) create mode 100644 llvm/unittests/Target/AArch64/Immediates.cpp diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h index 3a57b7bdb2d4..bad0a77b0f2d 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfo.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -696,6 +696,12 @@ public: /// immediate without having to materialize the immediate into a register. bool isLegalAddImmediate(int64_t Imm) const; + /// Return true if adding the specified scalable immediate is legal, that is + /// the target has add instructions which can add a register with the + /// immediate (multiplied by vscale) without having to materialize the + /// immediate into a register. + bool isLegalAddScalableImmediate(int64_t Imm) const; + /// Return true if the specified immediate is legal icmp immediate, /// that is the target has icmp instructions which can compare a register /// against the immediate without having to materialize the immediate into a @@ -1842,6 +1848,7 @@ public: std::function<void(Instruction *, unsigned, APInt, APInt &)> SimplifyAndSetOp) = 0; virtual bool isLegalAddImmediate(int64_t Imm) = 0; + virtual bool isLegalAddScalableImmediate(int64_t Imm) = 0; virtual bool isLegalICmpImmediate(int64_t Imm) = 0; virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, @@ -2303,6 +2310,9 @@ public: bool isLegalAddImmediate(int64_t Imm) override { return Impl.isLegalAddImmediate(Imm); } + bool isLegalAddScalableImmediate(int64_t Imm) override { + return Impl.isLegalAddScalableImmediate(Imm); + } bool isLegalICmpImmediate(int64_t Imm) override { return Impl.isLegalICmpImmediate(Imm); } diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h index 07eeceeeaa22..7c47d3c2338a 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -216,6 +216,8 @@ public: bool isLegalAddImmediate(int64_t Imm) const { return false; } + bool isLegalAddScalableImmediate(int64_t Imm) const { return false; } + bool isLegalICmpImmediate(int64_t Imm) const { return false; } bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h index 721900038ddd..92fa726c31df 100644 --- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -328,6 +328,10 @@ public: return getTLI()->isLegalAddImmediate(imm); } + bool isLegalAddScalableImmediate(int64_t Imm) { + return getTLI()->isLegalAddScalableImmediate(Imm); + } + bool isLegalICmpImmediate(int64_t imm) { return getTLI()->isLegalICmpImmediate(imm); } diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 4753d8e8a512..59fad88f91b1 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -2772,6 +2772,12 @@ public: return true; } + /// Return true if adding the specified scalable immediate is legal, that is + /// the target has add instructions which can add a register with the + /// immediate (multiplied by vscale) without having to materialize the + /// immediate into a register. + virtual bool isLegalAddScalableImmediate(int64_t) const { return false; } + /// Return true if the specified immediate is legal for the value input of a /// store instruction. virtual bool isLegalStoreImmediate(int64_t Value) const { diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp index 414da85209c1..5f933b458784 100644 --- a/llvm/lib/Analysis/TargetTransformInfo.cpp +++ b/llvm/lib/Analysis/TargetTransformInfo.cpp @@ -396,6 +396,10 @@ bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const { return TTIImpl->isLegalAddImmediate(Imm); } +bool TargetTransformInfo::isLegalAddScalableImmediate(int64_t Imm) const { + return TTIImpl->isLegalAddScalableImmediate(Imm); +} + bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const { return TTIImpl->isLegalICmpImmediate(Imm); } diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 512e35fad8fe..7fab274ab957 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -16616,6 +16616,38 @@ bool AArch64TargetLowering::isLegalAddImmediate(int64_t Immed) const { return IsLegal; } +bool AArch64TargetLowering::isLegalAddScalableImmediate(int64_t Imm) const { + // We will only emit addvl/inc* instructions for SVE2 + if (!Subtarget->hasSVE2()) + return false; + + // addvl's immediates are in terms of the number of bytes in a register. + // Since there are 16 in the base supported size (128bits), we need to + // divide the immediate by that much to give us a useful immediate to + // multiply by vscale. We can't have a remainder as a result of this. + if (Imm % 16 == 0) + return isInt<6>(Imm / 16); + + // Inc[b|h|w|d] instructions take a pattern and a positive immediate + // multiplier. For now, assume a pattern of 'all'. Incb would be a subset + // of addvl as a result, so only take h|w|d into account. + // Dec[h|w|d] will cover subtractions. + // Immediates are in the range [1,16], so we can't do a 2's complement check. + // FIXME: Can we make use of other patterns to cover other immediates? + + // inch|dech + if (Imm % 8 == 0) + return std::labs(Imm / 8) <= 16; + // incw|decw + if (Imm % 4 == 0) + return std::labs(Imm / 4) <= 16; + // incd|decd + if (Imm % 2 == 0) + return std::labs(Imm / 2) <= 16; + + return false; +} + // Return false to prevent folding // (mul (add x, c1), c2) -> (add (mul x, c2), c2*c1) in DAGCombine, // if the folding leads to worse code. diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h index 89016cbf56e3..3465f3be8875 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -689,6 +689,7 @@ public: StoreInst *SI) const override; bool isLegalAddImmediate(int64_t) const override; + bool isLegalAddScalableImmediate(int64_t) const override; bool isLegalICmpImmediate(int64_t) const override; bool isMulAddWithConstProfitable(SDValue AddNode, diff --git a/llvm/unittests/Target/AArch64/CMakeLists.txt b/llvm/unittests/Target/AArch64/CMakeLists.txt index dacd919ba1e3..64ab991ac479 100644 --- a/llvm/unittests/Target/AArch64/CMakeLists.txt +++ b/llvm/unittests/Target/AArch64/CMakeLists.txt @@ -29,6 +29,7 @@ add_llvm_target_unittest(AArch64Tests MatrixRegisterAliasing.cpp SMEAttributesTest.cpp AArch64SVESchedPseudoTest.cpp + Immediates.cpp ) set_property(TARGET AArch64Tests PROPERTY FOLDER "Tests/UnitTests/TargetTests") diff --git a/llvm/unittests/Target/AArch64/Immediates.cpp b/llvm/unittests/Target/AArch64/Immediates.cpp new file mode 100644 index 000000000000..a4551b083b44 --- /dev/null +++ b/llvm/unittests/Target/AArch64/Immediates.cpp @@ -0,0 +1,106 @@ +#include "AArch64Subtarget.h" +#include "AArch64TargetMachine.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" + +#include "gtest/gtest.h" +#include <initializer_list> +#include <memory> + +using namespace llvm; + +namespace { + +struct TestCase { + int64_t Imm; + bool Result; +}; + +const std::initializer_list<TestCase> Tests = { + // ScalableImm, Result + // No change, easily 'supported' + {0, true}, + + // addvl increments by whole registers, range [-32,31] + // +(16 * vscale), one register's worth + {16, true}, + // -(32 * 16 * vscale) + {-512, true}, + // -(33 * 16 * vscale) + {-528, false}, + // +(31 * 16 * vscale) + {496, true}, + // +(32 * 16 * vscale) + {512, false}, + + // inc[h|w|d] increments by the number of 16/32/64bit elements in a + // register. mult_imm is in the range [1,16] + // +(mult_imm * num_elts * vscale) + // +(1 * 8 * vscale), 16 bit + {8, true}, + // +(15 * 8 * vscale), 16 bit + {120, true}, + // +(1 * 4 * vscale), 32 bit + {4, true}, + // +(7 * 4 * vscale), 32 bit + {28, true}, + // +(1 * 2 * vscale), 64 bit + {2, true}, + // +(13 * 2 * vscale), 64 bit + {26, true}, + // +(17 * 8 * vscale), 16 bit, out of range. + {136, false}, + // +(19 * 2 * vscale), 64 bit, out of range. + {38, false}, + // +(21 * 4 * vscale), 32 bit, out of range. + {84, false}, + + // dec[h|w|d] -- Same as above, but negative. + // -(mult_imm * num_elts * vscale) + // -(1 * 8 * vscale), 16 bit + {-8, true}, + // -(15 * 8 * vscale), 16 bit + {-120, true}, + // -(1 * 4 * vscale), 32 bit + {-4, true}, + // -(7 * 4 * vscale), 32 bit + {-28, true}, + // -(1 * 2 * vscale), 64 bit + {-2, true}, + // -(13 * 2 * vscale), 64 bit + {-26, true}, + // -(17 * 8 * vscale), 16 bit, out of range. + {-136, false}, + // -(19 * 2 * vscale), 64 bit, out of range. + {-38, false}, + // -(21 * 4 * vscale), 32 bit, out of range. + {-84, false}, + + // Invalid; not divisible by the above powers of 2. + {5, false}, +}; +} // namespace + +TEST(Immediates, Immediates) { + LLVMInitializeAArch64TargetInfo(); + LLVMInitializeAArch64Target(); + LLVMInitializeAArch64TargetMC(); + + std::string Error; + auto TT = Triple::normalize("aarch64"); + const Target *T = TargetRegistry::lookupTarget(TT, Error); + + std::unique_ptr<TargetMachine> TM(T->createTargetMachine( + TT, "generic", "+sve2", TargetOptions(), std::nullopt, std::nullopt, + CodeGenOptLevel::Default)); + AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(), + TM->getTargetCPU(), TM->getTargetFeatureString(), *TM, + true); + + auto *TLI = ST.getTargetLowering(); + + for (const auto &Test : Tests) { + ASSERT_EQ(TLI->isLegalAddScalableImmediate(Test.Imm), Test.Result); + } +} -- GitLab From 22f20564a8fc29ce6d3f5de075a2849ff8acb874 Mon Sep 17 00:00:00 2001 From: Mark de Wever <koraq@xs4all.nl> Date: Wed, 20 Mar 2024 11:32:51 +0100 Subject: [PATCH 218/307] [libc++][CI] Reenables the module tests. (#85799) These were disabled due to ODR violations with mixed versions of clang-tidy and the clang libraries. This issue was fixed in e19e8600cf743690e1a23fb8a2b0dfbe2dafe559. This reverts commit 0bbada93a559b604797fe57978f3eca5e41edaeb. --- libcxx/test/libcxx/module_std.gen.py | 5 ----- libcxx/test/libcxx/module_std_compat.gen.py | 5 ----- 2 files changed, 10 deletions(-) diff --git a/libcxx/test/libcxx/module_std.gen.py b/libcxx/test/libcxx/module_std.gen.py index 5acaa837d37e..fc23985caf30 100644 --- a/libcxx/test/libcxx/module_std.gen.py +++ b/libcxx/test/libcxx/module_std.gen.py @@ -16,11 +16,7 @@ # to be one monolitic test. Since the test doesn't take very long it's # not a huge issue. -# WARNING: Disabled at the bottom. Fix this test and remove the UNSUPPORTED line -# TODO: Re-enable this test once we understand why it keeps timing out. - # RUN: %{python} %s %{libcxx-dir}/utils -# END. import sys @@ -39,5 +35,4 @@ generator = module_test_generator( print("//--- module_std.sh.cpp") -print('// UNSUPPORTED: clang') generator.write_test("std") diff --git a/libcxx/test/libcxx/module_std_compat.gen.py b/libcxx/test/libcxx/module_std_compat.gen.py index a502276a1ccf..000aa2998612 100644 --- a/libcxx/test/libcxx/module_std_compat.gen.py +++ b/libcxx/test/libcxx/module_std_compat.gen.py @@ -16,11 +16,7 @@ # to be one monolitic test. Since the test doesn't take very long it's # not a huge issue. -# WARNING: Disabled at the bottom. Fix this test and remove the UNSUPPORTED line -# TODO: Re-enable this test once we understand why it keeps timing out. - # RUN: %{python} %s %{libcxx-dir}/utils -# END. import sys @@ -40,7 +36,6 @@ generator = module_test_generator( print("//--- module_std_compat.sh.cpp") -print("// UNSUPPORTED: clang") generator.write_test( "std.compat", module_c_headers, -- GitLab From 197f3ecf92b91ad1626307a17edf0761f2e4136b Mon Sep 17 00:00:00 2001 From: Tom Eccles <tom.eccles@arm.com> Date: Wed, 20 Mar 2024 10:35:11 +0000 Subject: [PATCH 219/307] [flang][OpenMP] lower simple array reductions (#84958) This has been tested with arrays with compile-time constant bounds. Allocatable arrays and arrays with non-constant bounds are not yet supported. User-defined reduction functions are also not yet supported. The design is intended to work for arrays with non-constant bounds too without a lot of extra work (mostly there are bugs in OpenMPIRBuilder I haven't fixed yet). We need some way to get these runtime bounds into the reduction init and combiner regions. To keep things simple for now I opted to always box the array arguments so the box can be passed as one argument and the lower bounds and extents read from the box. This has the disadvantage of resulting in fir.box_dim operations inside of the critical section. If these prove to be a performance issue, we could follow OpenACC reading box lower bounds and extents before the reduction and passing them as block arguments to the reduction init and combiner regions. I would prefer to keep things simple for now. Note: this implementation only works when the HLFIR lowering is used. I don't think it is worth supporting FIR-only lowering because the plan is for that to be removed soon. OpenMP array reductions 6/6 Previous PR: https://github.com/llvm/llvm-project/pull/84957 --- .../flang/Optimizer/Builder/HLFIRTools.h | 5 + flang/lib/Lower/OpenMP/ReductionProcessor.cpp | 250 +++++++++++++++--- flang/lib/Lower/OpenMP/ReductionProcessor.h | 2 +- flang/lib/Optimizer/Builder/HLFIRTools.cpp | 29 ++ .../Lower/OpenMP/Todo/reduction-arrays.f90 | 15 -- .../Lower/OpenMP/parallel-reduction-array.f90 | 74 ++++++ .../OpenMP/parallel-reduction-array2.f90 | 89 +++++++ .../Lower/OpenMP/wsloop-reduction-array.f90 | 84 ++++++ .../Lower/OpenMP/wsloop-reduction-array2.f90 | 92 +++++++ 9 files changed, 586 insertions(+), 54 deletions(-) delete mode 100644 flang/test/Lower/OpenMP/Todo/reduction-arrays.f90 create mode 100644 flang/test/Lower/OpenMP/parallel-reduction-array.f90 create mode 100644 flang/test/Lower/OpenMP/parallel-reduction-array2.f90 create mode 100644 flang/test/Lower/OpenMP/wsloop-reduction-array.f90 create mode 100644 flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 diff --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h index ce87941d5382..035035601e2f 100644 --- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h +++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h @@ -434,6 +434,11 @@ std::pair<hlfir::Entity, mlir::Value> createTempFromMold(mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity mold); +// TODO: this does not support polymorphic molds +hlfir::Entity createStackTempFromMold(mlir::Location loc, + fir::FirOpBuilder &builder, + hlfir::Entity mold); + hlfir::EntityWithAttributes convertCharacterKind(mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity scalarChar, diff --git a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp index 6dc467c4f69b..54d9fc556973 100644 --- a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp @@ -13,6 +13,7 @@ #include "ReductionProcessor.h" #include "flang/Lower/AbstractConverter.h" +#include "flang/Optimizer/Builder/HLFIRTools.h" #include "flang/Optimizer/Builder/Todo.h" #include "flang/Optimizer/Dialect/FIRType.h" #include "flang/Optimizer/HLFIR/HLFIROps.h" @@ -90,10 +91,42 @@ std::string ReductionProcessor::getReductionName(llvm::StringRef name, if (isByRef) byrefAddition = "_byref"; - return (llvm::Twine(name) + - (ty.isIntOrIndex() ? llvm::Twine("_i_") : llvm::Twine("_f_")) + - llvm::Twine(ty.getIntOrFloatBitWidth()) + byrefAddition) - .str(); + if (fir::isa_trivial(ty)) + return (llvm::Twine(name) + + (ty.isIntOrIndex() ? llvm::Twine("_i_") : llvm::Twine("_f_")) + + llvm::Twine(ty.getIntOrFloatBitWidth()) + byrefAddition) + .str(); + + // creates a name like reduction_i_64_box_ux4x3 + if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(ty)) { + // TODO: support for allocatable boxes: + // !fir.box<!fir.heap<!fir.array<...>>> + fir::SequenceType seqTy = fir::unwrapRefType(boxTy.getEleTy()) + .dyn_cast_or_null<fir::SequenceType>(); + if (!seqTy) + return {}; + + std::string prefix = getReductionName( + name, fir::unwrapSeqOrBoxedSeqType(ty), /*isByRef=*/false); + if (prefix.empty()) + return {}; + std::stringstream tyStr; + tyStr << prefix << "_box_"; + bool first = true; + for (std::int64_t extent : seqTy.getShape()) { + if (first) + first = false; + else + tyStr << "x"; + if (extent == seqTy.getUnknownExtent()) + tyStr << 'u'; // I'm not sure that '?' is safe in symbol names + else + tyStr << extent; + } + return (tyStr.str() + byrefAddition).str(); + } + + return {}; } std::string ReductionProcessor::getReductionName( @@ -281,6 +314,148 @@ mlir::Value ReductionProcessor::createScalarCombiner( return reductionOp; } +/// Create reduction combiner region for reduction variables which are boxed +/// arrays +static void genBoxCombiner(fir::FirOpBuilder &builder, mlir::Location loc, + ReductionProcessor::ReductionIdentifier redId, + fir::BaseBoxType boxTy, mlir::Value lhs, + mlir::Value rhs) { + fir::SequenceType seqTy = + mlir::dyn_cast_or_null<fir::SequenceType>(boxTy.getEleTy()); + // TODO: support allocatable arrays: !fir.box<!fir.heap<!fir.array<...>>> + if (!seqTy || seqTy.hasUnknownShape()) + TODO(loc, "Unsupported boxed type in OpenMP reduction"); + + // load fir.ref<fir.box<...>> + mlir::Value lhsAddr = lhs; + lhs = builder.create<fir::LoadOp>(loc, lhs); + rhs = builder.create<fir::LoadOp>(loc, rhs); + + const unsigned rank = seqTy.getDimension(); + llvm::SmallVector<mlir::Value> extents; + extents.reserve(rank); + llvm::SmallVector<mlir::Value> lbAndExtents; + lbAndExtents.reserve(rank * 2); + + // Get box lowerbounds and extents: + mlir::Type idxTy = builder.getIndexType(); + for (unsigned i = 0; i < rank; ++i) { + // TODO: ideally we want to hoist box reads out of the critical section. + // We could do this by having box dimensions in block arguments like + // OpenACC does + mlir::Value dim = builder.createIntegerConstant(loc, idxTy, i); + auto dimInfo = + builder.create<fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, lhs, dim); + extents.push_back(dimInfo.getExtent()); + lbAndExtents.push_back(dimInfo.getLowerBound()); + lbAndExtents.push_back(dimInfo.getExtent()); + } + + auto shapeShiftTy = fir::ShapeShiftType::get(builder.getContext(), rank); + auto shapeShift = + builder.create<fir::ShapeShiftOp>(loc, shapeShiftTy, lbAndExtents); + + // Iterate over array elements, applying the equivalent scalar reduction: + + // A hlfir::elemental here gets inlined with a temporary so create the + // loop nest directly. + // This function already controls all of the code in this region so we + // know this won't miss any opportuinties for clever elemental inlining + hlfir::LoopNest nest = + hlfir::genLoopNest(loc, builder, extents, /*isUnordered=*/true); + builder.setInsertionPointToStart(nest.innerLoop.getBody()); + mlir::Type refTy = fir::ReferenceType::get(seqTy.getEleTy()); + auto lhsEleAddr = builder.create<fir::ArrayCoorOp>( + loc, refTy, lhs, shapeShift, /*slice=*/mlir::Value{}, + nest.oneBasedIndices, /*typeparms=*/mlir::ValueRange{}); + auto rhsEleAddr = builder.create<fir::ArrayCoorOp>( + loc, refTy, rhs, shapeShift, /*slice=*/mlir::Value{}, + nest.oneBasedIndices, /*typeparms=*/mlir::ValueRange{}); + auto lhsEle = builder.create<fir::LoadOp>(loc, lhsEleAddr); + auto rhsEle = builder.create<fir::LoadOp>(loc, rhsEleAddr); + mlir::Value scalarReduction = ReductionProcessor::createScalarCombiner( + builder, loc, redId, refTy, lhsEle, rhsEle); + builder.create<fir::StoreOp>(loc, scalarReduction, lhsEleAddr); + + builder.setInsertionPointAfter(nest.outerLoop); + builder.create<mlir::omp::YieldOp>(loc, lhsAddr); +} + +// generate combiner region for reduction operations +static void genCombiner(fir::FirOpBuilder &builder, mlir::Location loc, + ReductionProcessor::ReductionIdentifier redId, + mlir::Type ty, mlir::Value lhs, mlir::Value rhs, + bool isByRef) { + ty = fir::unwrapRefType(ty); + + if (fir::isa_trivial(ty)) { + mlir::Value lhsLoaded = builder.loadIfRef(loc, lhs); + mlir::Value rhsLoaded = builder.loadIfRef(loc, rhs); + + mlir::Value result = ReductionProcessor::createScalarCombiner( + builder, loc, redId, ty, lhsLoaded, rhsLoaded); + if (isByRef) { + builder.create<fir::StoreOp>(loc, result, lhs); + builder.create<mlir::omp::YieldOp>(loc, lhs); + } else { + builder.create<mlir::omp::YieldOp>(loc, result); + } + return; + } + // all arrays should have been boxed + if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(ty)) { + genBoxCombiner(builder, loc, redId, boxTy, lhs, rhs); + return; + } + + TODO(loc, "OpenMP genCombiner for unsupported reduction variable type"); +} + +static mlir::Value +createReductionInitRegion(fir::FirOpBuilder &builder, mlir::Location loc, + const ReductionProcessor::ReductionIdentifier redId, + mlir::Type type, bool isByRef) { + mlir::Type ty = fir::unwrapRefType(type); + mlir::Value initValue = ReductionProcessor::getReductionInitValue( + loc, fir::unwrapSeqOrBoxedSeqType(ty), redId, builder); + + if (fir::isa_trivial(ty)) { + if (isByRef) { + mlir::Value alloca = builder.create<fir::AllocaOp>(loc, ty); + builder.createStoreWithConvert(loc, initValue, alloca); + return alloca; + } + // by val + return initValue; + } + + // all arrays are boxed + if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(ty)) { + assert(isByRef && "passing arrays by value is unsupported"); + // TODO: support allocatable arrays: !fir.box<!fir.heap<!fir.array<...>>> + mlir::Type innerTy = fir::extractSequenceType(boxTy); + if (!mlir::isa<fir::SequenceType>(innerTy)) + TODO(loc, "Unsupported boxed type for reduction"); + // Create the private copy from the initial fir.box: + hlfir::Entity source = hlfir::Entity{builder.getBlock()->getArgument(0)}; + + // TODO: if the whole reduction is nested inside of a loop, this alloca + // could lead to a stack overflow (the memory is only freed at the end of + // the stack frame). The reduction declare operation needs a deallocation + // region to undo the init region. + hlfir::Entity temp = createStackTempFromMold(loc, builder, source); + + // Put the temporary inside of a box: + hlfir::Entity box = hlfir::genVariableBox(loc, builder, temp); + builder.create<hlfir::AssignOp>(loc, initValue, box); + mlir::Value boxAlloca = builder.create<fir::AllocaOp>(loc, ty); + builder.create<fir::StoreOp>(loc, box, boxAlloca); + return boxAlloca; + } + + TODO(loc, "createReductionInitRegion for unsupported type"); +} + mlir::omp::ReductionDeclareOp ReductionProcessor::createReductionDecl( fir::FirOpBuilder &builder, llvm::StringRef reductionOpName, const ReductionIdentifier redId, mlir::Type type, mlir::Location loc, @@ -288,6 +463,9 @@ mlir::omp::ReductionDeclareOp ReductionProcessor::createReductionDecl( mlir::OpBuilder::InsertionGuard guard(builder); mlir::ModuleOp module = builder.getModule(); + if (reductionOpName.empty()) + TODO(loc, "Reduction of some types is not supported"); + auto decl = module.lookupSymbol<mlir::omp::ReductionDeclareOp>(reductionOpName); if (decl) @@ -304,14 +482,9 @@ mlir::omp::ReductionDeclareOp ReductionProcessor::createReductionDecl( decl.getInitializerRegion().end(), {type}, {loc}); builder.setInsertionPointToEnd(&decl.getInitializerRegion().back()); - mlir::Value init = getReductionInitValue(loc, type, redId, builder); - if (isByRef) { - mlir::Value alloca = builder.create<fir::AllocaOp>(loc, valTy); - builder.createStoreWithConvert(loc, init, alloca); - builder.create<mlir::omp::YieldOp>(loc, alloca); - } else { - builder.create<mlir::omp::YieldOp>(loc, init); - } + mlir::Value init = + createReductionInitRegion(builder, loc, redId, type, isByRef); + builder.create<mlir::omp::YieldOp>(loc, init); builder.createBlock(&decl.getReductionRegion(), decl.getReductionRegion().end(), {type, type}, @@ -320,19 +493,7 @@ mlir::omp::ReductionDeclareOp ReductionProcessor::createReductionDecl( builder.setInsertionPointToEnd(&decl.getReductionRegion().back()); mlir::Value op1 = decl.getReductionRegion().front().getArgument(0); mlir::Value op2 = decl.getReductionRegion().front().getArgument(1); - mlir::Value outAddr = op1; - - op1 = builder.loadIfRef(loc, op1); - op2 = builder.loadIfRef(loc, op2); - - mlir::Value reductionOp = - createScalarCombiner(builder, loc, redId, type, op1, op2); - if (isByRef) { - builder.create<fir::StoreOp>(loc, reductionOp, outAddr); - builder.create<mlir::omp::YieldOp>(loc, outAddr); - } else { - builder.create<mlir::omp::YieldOp>(loc, reductionOp); - } + genCombiner(builder, loc, redId, type, op1, op2, isByRef); return decl; } @@ -387,13 +548,33 @@ void ReductionProcessor::addReductionDecl( // initial pass to collect all reduction vars so we can figure out if this // should happen byref + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); for (const Object &object : objectList) { const Fortran::semantics::Symbol *symbol = object.id(); if (reductionSymbols) reductionSymbols->push_back(symbol); mlir::Value symVal = converter.getSymbolAddress(*symbol); - if (auto declOp = symVal.getDefiningOp<hlfir::DeclareOp>()) + auto redType = mlir::cast<fir::ReferenceType>(symVal.getType()); + + // all arrays must be boxed so that we have convenient access to all the + // information needed to iterate over the array + if (mlir::isa<fir::SequenceType>(redType.getEleTy())) { + hlfir::Entity entity{symVal}; + entity = genVariableBox(currentLocation, builder, entity); + mlir::Value box = entity.getBase(); + + // Always pass the box by reference so that the OpenMP dialect + // verifiers don't need to know anything about fir.box + auto alloca = + builder.create<fir::AllocaOp>(currentLocation, box.getType()); + builder.create<fir::StoreOp>(currentLocation, box, alloca); + + symVal = alloca; + redType = mlir::cast<fir::ReferenceType>(symVal.getType()); + } else if (auto declOp = symVal.getDefiningOp<hlfir::DeclareOp>()) { symVal = declOp.getBase(); + } + reductionVars.push_back(symVal); } const bool isByRef = doReductionByRef(reductionVars); @@ -418,24 +599,17 @@ void ReductionProcessor::addReductionDecl( break; } - for (const Object &object : objectList) { - const Fortran::semantics::Symbol *symbol = object.id(); - mlir::Value symVal = converter.getSymbolAddress(*symbol); - if (auto declOp = symVal.getDefiningOp<hlfir::DeclareOp>()) - symVal = declOp.getBase(); - auto redType = symVal.getType().cast<fir::ReferenceType>(); + for (mlir::Value symVal : reductionVars) { + auto redType = mlir::cast<fir::ReferenceType>(symVal.getType()); if (redType.getEleTy().isa<fir::LogicalType>()) decl = createReductionDecl( firOpBuilder, getReductionName(intrinsicOp, firOpBuilder.getI1Type(), isByRef), redId, redType, currentLocation, isByRef); - else if (redType.getEleTy().isIntOrIndexOrFloat()) { + else decl = createReductionDecl( firOpBuilder, getReductionName(intrinsicOp, redType, isByRef), redId, redType, currentLocation, isByRef); - } else { - TODO(currentLocation, "Reduction of some types is not supported"); - } reductionDeclSymbols.push_back(mlir::SymbolRefAttr::get( firOpBuilder.getContext(), decl.getSymName())); } @@ -452,8 +626,8 @@ void ReductionProcessor::addReductionDecl( if (auto declOp = symVal.getDefiningOp<hlfir::DeclareOp>()) symVal = declOp.getBase(); auto redType = symVal.getType().cast<fir::ReferenceType>(); - assert(redType.getEleTy().isIntOrIndexOrFloat() && - "Unsupported reduction type"); + if (!redType.getEleTy().isIntOrIndexOrFloat()) + TODO(currentLocation, "User Defined Reduction on non-trivial type"); decl = createReductionDecl( firOpBuilder, getReductionName(getRealName(*reductionIntrinsic).ToString(), diff --git a/flang/lib/Lower/OpenMP/ReductionProcessor.h b/flang/lib/Lower/OpenMP/ReductionProcessor.h index ef6339407c13..f481d4cbd1c5 100644 --- a/flang/lib/Lower/OpenMP/ReductionProcessor.h +++ b/flang/lib/Lower/OpenMP/ReductionProcessor.h @@ -108,7 +108,7 @@ public: /// Creates an OpenMP reduction declaration and inserts it into the provided /// symbol table. The declaration has a constant initializer with the neutral /// value `initValue`, and the reduction combiner carried over from `reduce`. - /// TODO: Generalize this for non-integer types, add atomic region. + /// TODO: add atomic region. static mlir::omp::ReductionDeclareOp createReductionDecl(fir::FirOpBuilder &builder, llvm::StringRef reductionOpName, diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp index c7a550814e1d..db638ceb4070 100644 --- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp +++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp @@ -1111,6 +1111,35 @@ hlfir::createTempFromMold(mlir::Location loc, fir::FirOpBuilder &builder, return {hlfir::Entity{declareOp.getBase()}, isHeapAlloc}; } +hlfir::Entity hlfir::createStackTempFromMold(mlir::Location loc, + fir::FirOpBuilder &builder, + hlfir::Entity mold) { + llvm::SmallVector<mlir::Value> lenParams; + hlfir::genLengthParameters(loc, builder, mold, lenParams); + llvm::StringRef tmpName{".tmp"}; + mlir::Value alloc; + mlir::Value shape{}; + fir::FortranVariableFlagsAttr declAttrs; + + if (mold.isPolymorphic()) { + // genAllocatableApplyMold does heap allocation + TODO(loc, "createStackTempFromMold for polymorphic type"); + } else if (mold.isArray()) { + mlir::Type sequenceType = + hlfir::getFortranElementOrSequenceType(mold.getType()); + shape = hlfir::genShape(loc, builder, mold); + auto extents = hlfir::getIndexExtents(loc, builder, shape); + alloc = + builder.createTemporary(loc, sequenceType, tmpName, extents, lenParams); + } else { + alloc = builder.createTemporary(loc, mold.getFortranElementType(), tmpName, + /*shape=*/std::nullopt, lenParams); + } + auto declareOp = builder.create<hlfir::DeclareOp>(loc, alloc, tmpName, shape, + lenParams, declAttrs); + return hlfir::Entity{declareOp.getBase()}; +} + hlfir::EntityWithAttributes hlfir::convertCharacterKind(mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity scalarChar, int toKind) { diff --git a/flang/test/Lower/OpenMP/Todo/reduction-arrays.f90 b/flang/test/Lower/OpenMP/Todo/reduction-arrays.f90 deleted file mode 100644 index a21611faf248..000000000000 --- a/flang/test/Lower/OpenMP/Todo/reduction-arrays.f90 +++ /dev/null @@ -1,15 +0,0 @@ -! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s -! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s - -! CHECK: not yet implemented: Reduction of some types is not supported -subroutine reduction_array(y) - integer :: x(100), y(100,100) - !$omp parallel - !$omp do reduction(+:x) - do i=1, 100 - x = x + y(:,i) - end do - !$omp end do - !$omp end parallel - print *, x -end subroutine diff --git a/flang/test/Lower/OpenMP/parallel-reduction-array.f90 b/flang/test/Lower/OpenMP/parallel-reduction-array.f90 new file mode 100644 index 000000000000..19c458631085 --- /dev/null +++ b/flang/test/Lower/OpenMP/parallel-reduction-array.f90 @@ -0,0 +1,74 @@ +! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s + +program reduce +integer, dimension(3) :: i = 0 + +!$omp parallel reduction(+:i) +i(1) = 1 +i(2) = 2 +i(3) = 3 +!$omp end parallel + +print *,i +end program + +! CHECK-LABEL: omp.reduction.declare @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>): +! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<3xi32> {bindc_name = ".tmp"} +! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_4:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_5]]) {uniq_name = ".tmp"} : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xi32>>, !fir.ref<!fir.array<3xi32>>) +! CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_6]]#0(%[[VAL_5]]) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>> +! CHECK: hlfir.assign %[[VAL_2]] to %[[VAL_7]] : i32, !fir.box<!fir.array<3xi32>> +! CHECK: %[[VAL_8:.*]] = fir.alloca !fir.box<!fir.array<3xi32>> +! CHECK: fir.store %[[VAL_7]] to %[[VAL_8]] : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: omp.yield(%[[VAL_8]] : !fir.ref<!fir.box<!fir.array<3xi32>>>) +! CHECK: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>): +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<3xi32>>, index) -> (index, index, index) +! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered { +! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32> +! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32> +! CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32 +! CHECK: fir.store %[[VAL_13]] to %[[VAL_9]] : !fir.ref<i32> +! CHECK: } +! CHECK: omp.yield(%[[VAL_0]] : !fir.ref<!fir.box<!fir.array<3xi32>>>) +! CHECK: } + +! CHECK-LABEL: func.func @_QQmain() +! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QFEi) : !fir.ref<!fir.array<3xi32>> +! CHECK: %[[VAL_1:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_2]]) {uniq_name = "_QFEi"} : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xi32>>, !fir.ref<!fir.array<3xi32>>) +! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1(%[[VAL_2]]) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>> +! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.box<!fir.array<3xi32>> +! CHECK: fir.store %[[VAL_4]] to %[[VAL_5]] : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: omp.parallel byref reduction(@add_reduction_i_32_box_3_byref %[[VAL_5]] -> %[[VAL_6:.*]] : !fir.ref<!fir.box<!fir.array<3xi32>>>) { +! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]] {uniq_name = "_QFEi"} : (!fir.ref<!fir.box<!fir.array<3xi32>>>) -> (!fir.ref<!fir.box<!fir.array<3xi32>>>, !fir.ref<!fir.box<!fir.array<3xi32>>>) +! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_10:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_11:.*]] = hlfir.designate %[[VAL_9]] (%[[VAL_10]]) : (!fir.box<!fir.array<3xi32>>, index) -> !fir.ref<i32> +! CHECK: hlfir.assign %[[VAL_8]] to %[[VAL_11]] : i32, !fir.ref<i32> +! CHECK: %[[VAL_12:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_14:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_15:.*]] = hlfir.designate %[[VAL_13]] (%[[VAL_14]]) : (!fir.box<!fir.array<3xi32>>, index) -> !fir.ref<i32> +! CHECK: hlfir.assign %[[VAL_12]] to %[[VAL_15]] : i32, !fir.ref<i32> +! CHECK: %[[VAL_16:.*]] = arith.constant 3 : i32 +! CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_18:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_17]] (%[[VAL_18]]) : (!fir.box<!fir.array<3xi32>>, index) -> !fir.ref<i32> +! CHECK: hlfir.assign %[[VAL_16]] to %[[VAL_19]] : i32, !fir.ref<i32> +! CHECK: omp.terminator +! CHECK: } diff --git a/flang/test/Lower/OpenMP/parallel-reduction-array2.f90 b/flang/test/Lower/OpenMP/parallel-reduction-array2.f90 new file mode 100644 index 000000000000..04c4045a6729 --- /dev/null +++ b/flang/test/Lower/OpenMP/parallel-reduction-array2.f90 @@ -0,0 +1,89 @@ +! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s + +program reduce +integer, dimension(3) :: i = 0 + +!$omp parallel reduction(+:i) +i(1) = i(1) + 1 +i(2) = i(2) + 2 +i(3) = i(3) + 3 +!$omp end parallel + +print *,i +end program + +! CHECK-LABEL: omp.reduction.declare @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>): +! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<3xi32> {bindc_name = ".tmp"} +! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_4:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_5]]) {uniq_name = ".tmp"} : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xi32>>, !fir.ref<!fir.array<3xi32>>) +! CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_6]]#0(%[[VAL_5]]) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>> +! CHECK: hlfir.assign %[[VAL_2]] to %[[VAL_7]] : i32, !fir.box<!fir.array<3xi32>> +! CHECK: %[[VAL_8:.*]] = fir.alloca !fir.box<!fir.array<3xi32>> +! CHECK: fir.store %[[VAL_7]] to %[[VAL_8]] : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: omp.yield(%[[VAL_8]] : !fir.ref<!fir.box<!fir.array<3xi32>>>) +! CHECK: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>): +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<3xi32>>, index) -> (index, index, index) +! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered { +! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32> +! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32> +! CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32 +! CHECK: fir.store %[[VAL_13]] to %[[VAL_9]] : !fir.ref<i32> +! CHECK: } +! CHECK: omp.yield(%[[VAL_0]] : !fir.ref<!fir.box<!fir.array<3xi32>>>) +! CHECK: } + +! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "reduce"} { +! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QFEi) : !fir.ref<!fir.array<3xi32>> +! CHECK: %[[VAL_1:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_2]]) {uniq_name = "_QFEi"} : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xi32>>, !fir.ref<!fir.array<3xi32>>) +! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1(%[[VAL_2]]) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>> +! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.box<!fir.array<3xi32>> +! CHECK: fir.store %[[VAL_4]] to %[[VAL_5]] : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: omp.parallel byref reduction(@add_reduction_i_32_box_3_byref %[[VAL_5]] -> %[[VAL_6:.*]] : !fir.ref<!fir.box<!fir.array<3xi32>>>) { +! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]] {uniq_name = "_QFEi"} : (!fir.ref<!fir.box<!fir.array<3xi32>>>) -> (!fir.ref<!fir.box<!fir.array<3xi32>>>, !fir.ref<!fir.box<!fir.array<3xi32>>>) +! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_9:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_10:.*]] = hlfir.designate %[[VAL_8]] (%[[VAL_9]]) : (!fir.box<!fir.array<3xi32>>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32> +! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32 +! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_15:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_14]] (%[[VAL_15]]) : (!fir.box<!fir.array<3xi32>>, index) -> !fir.ref<i32> +! CHECK: hlfir.assign %[[VAL_13]] to %[[VAL_16]] : i32, !fir.ref<i32> +! CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_18:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_17]] (%[[VAL_18]]) : (!fir.box<!fir.array<3xi32>>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref<i32> +! CHECK: %[[VAL_21:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_20]], %[[VAL_21]] : i32 +! CHECK: %[[VAL_23:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_24:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_25:.*]] = hlfir.designate %[[VAL_23]] (%[[VAL_24]]) : (!fir.box<!fir.array<3xi32>>, index) -> !fir.ref<i32> +! CHECK: hlfir.assign %[[VAL_22]] to %[[VAL_25]] : i32, !fir.ref<i32> +! CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_27:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_28:.*]] = hlfir.designate %[[VAL_26]] (%[[VAL_27]]) : (!fir.box<!fir.array<3xi32>>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_28]] : !fir.ref<i32> +! CHECK: %[[VAL_30:.*]] = arith.constant 3 : i32 +! CHECK: %[[VAL_31:.*]] = arith.addi %[[VAL_29]], %[[VAL_30]] : i32 +! CHECK: %[[VAL_32:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<3xi32>>> +! CHECK: %[[VAL_33:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_34:.*]] = hlfir.designate %[[VAL_32]] (%[[VAL_33]]) : (!fir.box<!fir.array<3xi32>>, index) -> !fir.ref<i32> +! CHECK: hlfir.assign %[[VAL_31]] to %[[VAL_34]] : i32, !fir.ref<i32> +! CHECK: omp.terminator +! CHECK: } diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-array.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-array.f90 new file mode 100644 index 000000000000..4350ace820c2 --- /dev/null +++ b/flang/test/Lower/OpenMP/wsloop-reduction-array.f90 @@ -0,0 +1,84 @@ +! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s +program reduce +integer :: i = 0 +integer, dimension(2) :: r = 0 + +!$omp parallel do reduction(+:r) +do i=0,10 + r(1) = i + r(2) = -i +enddo +!$omp end parallel do + +print *,r +end program + +! CHECK-LABEL omp.reduction.declare @add_reduction_i_32_box_2_byref : !fir.ref<!fir.box<!fir.array<2xi32>>> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>): +! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<2xi32> {bindc_name = ".tmp"} +! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_4:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_5]]) {uniq_name = ".tmp"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>) +! CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_6]]#0(%[[VAL_5]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>> +! CHECK: hlfir.assign %[[VAL_2]] to %[[VAL_7]] : i32, !fir.box<!fir.array<2xi32>> +! CHECK: %[[VAL_8:.*]] = fir.alloca !fir.box<!fir.array<2xi32>> +! CHECK: fir.store %[[VAL_7]] to %[[VAL_8]] : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: omp.yield(%[[VAL_8]] : !fir.ref<!fir.box<!fir.array<2xi32>>>) + +! CHECK-LABEL } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>): +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<2xi32>>, index) -> (index, index, index) +! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered { +! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<2xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<2xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32> +! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32> +! CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32 +! CHECK: fir.store %[[VAL_13]] to %[[VAL_9]] : !fir.ref<i32> +! CHECK: } +! CHECK: omp.yield(%[[VAL_0]] : !fir.ref<!fir.box<!fir.array<2xi32>>>) +! CHECK: } + +! CHECK-LABEL func.func @_QQmain() attributes {fir.bindc_name = "reduce"} { +! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QFEi) : !fir.ref<i32> +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) +! CHECK: %[[VAL_2:.*]] = fir.address_of(@_QFEr) : !fir.ref<!fir.array<2xi32>> +! CHECK: %[[VAL_3:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_4]]) {uniq_name = "_QFEr"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>) +! CHECK: omp.parallel { +! CHECK: %[[VAL_6:.*]] = fir.alloca i32 {adapt.valuebyref, pinned} +! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) +! CHECK: %[[VAL_8:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_9:.*]] = arith.constant 10 : i32 +! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_5]]#1(%[[VAL_4]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>> +! CHECK: %[[VAL_12:.*]] = fir.alloca !fir.box<!fir.array<2xi32>> +! CHECK: fir.store %[[VAL_11]] to %[[VAL_12]] : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_box_2_byref %[[VAL_12]] -> %[[VAL_13:.*]] : !fir.ref<!fir.box<!fir.array<2xi32>>>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { +! CHECK: fir.store %[[VAL_14]] to %[[VAL_7]]#1 : !fir.ref<i32> +! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_13]] {uniq_name = "_QFEr"} : (!fir.ref<!fir.box<!fir.array<2xi32>>>) -> (!fir.ref<!fir.box<!fir.array<2xi32>>>, !fir.ref<!fir.box<!fir.array<2xi32>>>) +! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<i32> +! CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_15]]#0 : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_18:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_17]] (%[[VAL_18]]) : (!fir.box<!fir.array<2xi32>>, index) -> !fir.ref<i32> +! CHECK: hlfir.assign %[[VAL_16]] to %[[VAL_19]] : i32, !fir.ref<i32> +! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<i32> +! CHECK: %[[VAL_21:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_22:.*]] = arith.subi %[[VAL_21]], %[[VAL_20]] : i32 +! CHECK: %[[VAL_23:.*]] = fir.load %[[VAL_15]]#0 : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_24:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_25:.*]] = hlfir.designate %[[VAL_23]] (%[[VAL_24]]) : (!fir.box<!fir.array<2xi32>>, index) -> !fir.ref<i32> +! CHECK: hlfir.assign %[[VAL_22]] to %[[VAL_25]] : i32, !fir.ref<i32> +! CHECK: omp.yield +! CHECK: } +! CHECK: omp.terminator +! CHECK: } diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 new file mode 100644 index 000000000000..8543c58dec4d --- /dev/null +++ b/flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 @@ -0,0 +1,92 @@ +! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s +program reduce +integer :: i = 0 +integer, dimension(2) :: r = 0 + +!$omp parallel do reduction(+:r) +do i=0,10 + r(1) = r(1) + i + r(2) = r(2) - i +enddo +!$omp end parallel do + +print *,r +end program + +! CHECK-LABEL omp.reduction.declare @add_reduction_i_32_box_2_byref : !fir.ref<!fir.box<!fir.array<2xi32>>> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>): +! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<2xi32> {bindc_name = ".tmp"} +! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_4:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_5]]) {uniq_name = ".tmp"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>) +! CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_6]]#0(%[[VAL_5]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>> +! CHECK: hlfir.assign %[[VAL_2]] to %[[VAL_7]] : i32, !fir.box<!fir.array<2xi32>> +! CHECK: %[[VAL_8:.*]] = fir.alloca !fir.box<!fir.array<2xi32>> +! CHECK: fir.store %[[VAL_7]] to %[[VAL_8]] : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: omp.yield(%[[VAL_8]] : !fir.ref<!fir.box<!fir.array<2xi32>>>) + +! CHECK-LABEL } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>): +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<2xi32>>, index) -> (index, index, index) +! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered { +! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<2xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<2xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32> +! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32> +! CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32 +! CHECK: fir.store %[[VAL_13]] to %[[VAL_9]] : !fir.ref<i32> +! CHECK: } +! CHECK: omp.yield(%[[VAL_0]] : !fir.ref<!fir.box<!fir.array<2xi32>>>) +! CHECK: } + +! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "reduce"} { +! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QFEi) : !fir.ref<i32> +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) +! CHECK: %[[VAL_2:.*]] = fir.address_of(@_QFEr) : !fir.ref<!fir.array<2xi32>> +! CHECK: %[[VAL_3:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_4]]) {uniq_name = "_QFEr"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xi32>>, !fir.ref<!fir.array<2xi32>>) +! CHECK: omp.parallel { +! CHECK: %[[VAL_6:.*]] = fir.alloca i32 {adapt.valuebyref, pinned} +! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) +! CHECK: %[[VAL_8:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_9:.*]] = arith.constant 10 : i32 +! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_5]]#1(%[[VAL_4]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>> +! CHECK: %[[VAL_12:.*]] = fir.alloca !fir.box<!fir.array<2xi32>> +! CHECK: fir.store %[[VAL_11]] to %[[VAL_12]] : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_box_2_byref %[[VAL_12]] -> %[[VAL_13:.*]] : !fir.ref<!fir.box<!fir.array<2xi32>>>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { +! CHECK: fir.store %[[VAL_14]] to %[[VAL_7]]#1 : !fir.ref<i32> +! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_13]] {uniq_name = "_QFEr"} : (!fir.ref<!fir.box<!fir.array<2xi32>>>) -> (!fir.ref<!fir.box<!fir.array<2xi32>>>, !fir.ref<!fir.box<!fir.array<2xi32>>>) +! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_15]]#0 : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_17:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_18:.*]] = hlfir.designate %[[VAL_16]] (%[[VAL_17]]) : (!fir.box<!fir.array<2xi32>>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_18]] : !fir.ref<i32> +! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<i32> +! CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_19]], %[[VAL_20]] : i32 +! CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_15]]#0 : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_23:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_24:.*]] = hlfir.designate %[[VAL_22]] (%[[VAL_23]]) : (!fir.box<!fir.array<2xi32>>, index) -> !fir.ref<i32> +! CHECK: hlfir.assign %[[VAL_21]] to %[[VAL_24]] : i32, !fir.ref<i32> +! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_15]]#0 : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_26:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_27:.*]] = hlfir.designate %[[VAL_25]] (%[[VAL_26]]) : (!fir.box<!fir.array<2xi32>>, index) -> !fir.ref<i32> +! CHECK: %[[VAL_28:.*]] = fir.load %[[VAL_27]] : !fir.ref<i32> +! CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<i32> +! CHECK: %[[VAL_30:.*]] = arith.subi %[[VAL_28]], %[[VAL_29]] : i32 +! CHECK: %[[VAL_31:.*]] = fir.load %[[VAL_15]]#0 : !fir.ref<!fir.box<!fir.array<2xi32>>> +! CHECK: %[[VAL_32:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_33:.*]] = hlfir.designate %[[VAL_31]] (%[[VAL_32]]) : (!fir.box<!fir.array<2xi32>>, index) -> !fir.ref<i32> +! CHECK: hlfir.assign %[[VAL_30]] to %[[VAL_33]] : i32, !fir.ref<i32> +! CHECK: omp.yield +! CHECK: } +! CHECK: omp.terminator +! CHECK: } -- GitLab From 6086937976889ac082fbda9d76e94edf4c466410 Mon Sep 17 00:00:00 2001 From: LLVM GN Syncbot <llvmgnsyncbot@gmail.com> Date: Wed, 20 Mar 2024 10:38:06 +0000 Subject: [PATCH 220/307] [gn build] Port 36a3f8f6471b --- llvm/utils/gn/secondary/llvm/unittests/Target/AArch64/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/utils/gn/secondary/llvm/unittests/Target/AArch64/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Target/AArch64/BUILD.gn index 8fde227c4517..cddec7aee574 100644 --- a/llvm/utils/gn/secondary/llvm/unittests/Target/AArch64/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/Target/AArch64/BUILD.gn @@ -20,6 +20,7 @@ unittest("AArch64Tests") { "AArch64SVESchedPseudoTest.cpp", "AddressingModes.cpp", "DecomposeStackOffsetTest.cpp", + "Immediates.cpp", "InstSizes.cpp", "MatrixRegisterAliasing.cpp", "SMEAttributesTest.cpp", -- GitLab From fe2119a7b08b6e468b2a67768904ea85b1bf0a45 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <llvm-dev@redking.me.uk> Date: Wed, 20 Mar 2024 10:23:39 +0000 Subject: [PATCH 221/307] [VectorCombine] foldBitcastShuffle - include the cost of bitcasts in the comparison This makes no real difference currently as we only fold unary shuffles, but I'm hoping to handle binary shuffles in a future patch. --- .../Transforms/Vectorize/VectorCombine.cpp | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp index 85c8d3996bba..0b16a8b76769 100644 --- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp +++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp @@ -684,10 +684,10 @@ bool VectorCombine::foldInsExtFNeg(Instruction &I) { /// destination type followed by shuffle. This can enable further transforms by /// moving bitcasts or shuffles together. bool VectorCombine::foldBitcastShuffle(Instruction &I) { - Value *V; + Value *V0; ArrayRef<int> Mask; - if (!match(&I, m_BitCast( - m_OneUse(m_Shuffle(m_Value(V), m_Undef(), m_Mask(Mask)))))) + if (!match(&I, m_BitCast(m_OneUse( + m_Shuffle(m_Value(V0), m_Undef(), m_Mask(Mask)))))) return false; // 1) Do not fold bitcast shuffle for scalable type. First, shuffle cost for @@ -696,7 +696,7 @@ bool VectorCombine::foldBitcastShuffle(Instruction &I) { // 2) Disallow non-vector casts. // TODO: We could allow any shuffle. auto *DestTy = dyn_cast<FixedVectorType>(I.getType()); - auto *SrcTy = dyn_cast<FixedVectorType>(V->getType()); + auto *SrcTy = dyn_cast<FixedVectorType>(V0->getType()); if (!DestTy || !SrcTy) return false; @@ -724,20 +724,31 @@ bool VectorCombine::foldBitcastShuffle(Instruction &I) { // Bitcast the shuffle src - keep its original width but using the destination // scalar type. unsigned NumSrcElts = SrcTy->getPrimitiveSizeInBits() / DestEltSize; - auto *ShuffleTy = FixedVectorType::get(DestTy->getScalarType(), NumSrcElts); - - // The new shuffle must not cost more than the old shuffle. The bitcast is - // moved ahead of the shuffle, so assume that it has the same cost as before. - InstructionCost DestCost = TTI.getShuffleCost( - TargetTransformInfo::SK_PermuteSingleSrc, ShuffleTy, NewMask); + auto *NewShuffleTy = + FixedVectorType::get(DestTy->getScalarType(), NumSrcElts); + auto *OldShuffleTy = + FixedVectorType::get(SrcTy->getScalarType(), Mask.size()); + + // The new shuffle must not cost more than the old shuffle. + TargetTransformInfo::TargetCostKind CK = + TargetTransformInfo::TCK_RecipThroughput; + TargetTransformInfo::ShuffleKind SK = + TargetTransformInfo::SK_PermuteSingleSrc; + + InstructionCost DestCost = + TTI.getShuffleCost(SK, NewShuffleTy, NewMask, CK) + + TTI.getCastInstrCost(Instruction::BitCast, NewShuffleTy, SrcTy, + TargetTransformInfo::CastContextHint::None, CK); InstructionCost SrcCost = - TTI.getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc, SrcTy, Mask); + TTI.getShuffleCost(SK, SrcTy, Mask, CK) + + TTI.getCastInstrCost(Instruction::BitCast, DestTy, OldShuffleTy, + TargetTransformInfo::CastContextHint::None, CK); if (DestCost > SrcCost || !DestCost.isValid()) return false; - // bitcast (shuf V, MaskC) --> shuf (bitcast V), MaskC' + // bitcast (shuf V0, MaskC) --> shuf (bitcast V0), MaskC' ++NumShufOfBitcast; - Value *CastV = Builder.CreateBitCast(V, ShuffleTy); + Value *CastV = Builder.CreateBitCast(V0, NewShuffleTy); Value *Shuf = Builder.CreateShuffleVector(CastV, NewMask); replaceValue(I, *Shuf); return true; -- GitLab From d84252e064b3f35aa879c10e207f77e931f351d9 Mon Sep 17 00:00:00 2001 From: Sergio Afonso <safonsof@amd.com> Date: Wed, 20 Mar 2024 11:19:38 +0000 Subject: [PATCH 222/307] [MLIR][OpenMP] NFC: Uniformize OpenMP ops names (#85393) This patch proposes the renaming of certain OpenMP dialect operations with the goal of improving readability and following a uniform naming convention for MLIR operations and associated classes. In particular, the following operations are renamed: - `omp.map_info` -> `omp.map.info` - `omp.target_update_data` -> `omp.target_update` - `omp.ordered_region` -> `omp.ordered.region` - `omp.cancellationpoint` -> `omp.cancellation_point` - `omp.bounds` -> `omp.map.bounds` - `omp.reduction.declare` -> `omp.declare_reduction` Also, the following MLIR operation classes have been renamed: - `omp::TaskLoopOp` -> `omp::TaskloopOp` - `omp::TaskGroupOp` -> `omp::TaskgroupOp` - `omp::DataBoundsOp` -> `omp::MapBoundsOp` - `omp::DataOp` -> `omp::TargetDataOp` - `omp::EnterDataOp` -> `omp::TargetEnterDataOp` - `omp::ExitDataOp` -> `omp::TargetExitDataOp` - `omp::UpdateDataOp` -> `omp::TargetUpdateOp` - `omp::ReductionDeclareOp` -> `omp::DeclareReductionOp` - `omp::WsLoopOp` -> `omp::WsloopOp` --- flang/docs/OpenMP-descriptor-management.md | 11 +- .../flang/Optimizer/Transforms/Passes.td | 2 +- flang/include/flang/Tools/CLOptions.inc | 2 +- flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 9 +- flang/lib/Lower/OpenMP/ClauseProcessor.h | 4 +- .../lib/Lower/OpenMP/DataSharingProcessor.cpp | 6 +- flang/lib/Lower/OpenMP/OpenMP.cpp | 82 +++++----- flang/lib/Lower/OpenMP/ReductionProcessor.cpp | 16 +- flang/lib/Lower/OpenMP/ReductionProcessor.h | 28 ++-- flang/lib/Optimizer/Builder/FIRBuilder.cpp | 2 +- flang/lib/Optimizer/CodeGen/CodeGen.cpp | 4 +- flang/test/Driver/bbc-mlir-pass-pipeline.f90 | 4 +- .../test/Driver/mlir-debug-pass-pipeline.f90 | 4 +- flang/test/Driver/mlir-pass-pipeline.f90 | 4 +- flang/test/Fir/basic-program.fir | 4 +- .../Fir/convert-to-llvm-openmp-and-fir.fir | 88 +++++------ .../test/Fir/omp-reduction-embox-codegen.fir | 4 +- flang/test/Lower/OpenMP/FIR/array-bounds.f90 | 24 +-- .../Lower/OpenMP/FIR/map-component-ref.f90 | 4 +- .../test/Lower/OpenMP/FIR/ordered-threads.f90 | 8 +- .../FIR/parallel-reduction-add-byref.f90 | 4 +- .../OpenMP/FIR/parallel-reduction-add.f90 | 4 +- flang/test/Lower/OpenMP/FIR/target.f90 | 130 ++++++++-------- .../OpenMP/FIR/wsloop-reduction-add-byref.f90 | 8 +- .../Lower/OpenMP/FIR/wsloop-reduction-add.f90 | 8 +- .../FIR/wsloop-reduction-iand-byref.f90 | 2 +- .../OpenMP/FIR/wsloop-reduction-iand.f90 | 2 +- .../FIR/wsloop-reduction-ieor-byref.f90 | 2 +- .../OpenMP/FIR/wsloop-reduction-ieor.f90 | 2 +- .../OpenMP/FIR/wsloop-reduction-ior-byref.f90 | 2 +- .../Lower/OpenMP/FIR/wsloop-reduction-ior.f90 | 2 +- .../wsloop-reduction-logical-eqv-byref.f90 | 2 +- .../FIR/wsloop-reduction-logical-eqv.f90 | 2 +- .../wsloop-reduction-logical-neqv-byref.f90 | 2 +- .../FIR/wsloop-reduction-logical-neqv.f90 | 2 +- .../OpenMP/FIR/wsloop-reduction-max-byref.f90 | 4 +- .../Lower/OpenMP/FIR/wsloop-reduction-max.f90 | 4 +- .../OpenMP/FIR/wsloop-reduction-min-byref.f90 | 4 +- .../Lower/OpenMP/FIR/wsloop-reduction-min.f90 | 4 +- .../Lower/OpenMP/allocatable-array-bounds.f90 | 18 +-- flang/test/Lower/OpenMP/allocatable-map.f90 | 4 +- flang/test/Lower/OpenMP/array-bounds.f90 | 20 +-- .../OpenMP/declare-target-link-tarop-cap.f90 | 10 +- .../delayed-privatization-reduction-byref.f90 | 2 +- .../delayed-privatization-reduction.f90 | 2 +- flang/test/Lower/OpenMP/map-component-ref.f90 | 4 +- flang/test/Lower/OpenMP/ordered-threads.f90 | 4 +- .../OpenMP/parallel-reduction-add-byref.f90 | 4 +- .../Lower/OpenMP/parallel-reduction-add.f90 | 4 +- .../Lower/OpenMP/parallel-reduction-array.f90 | 2 +- .../OpenMP/parallel-reduction-array2.f90 | 2 +- .../Lower/OpenMP/parallel-reduction-byref.f90 | 2 +- .../OpenMP/parallel-reduction-rename.f90 | 2 +- .../test/Lower/OpenMP/parallel-reduction.f90 | 2 +- flang/test/Lower/OpenMP/target.f90 | 142 +++++++++--------- .../OpenMP/wsloop-reduction-add-byref.f90 | 8 +- .../wsloop-reduction-add-hlfir-byref.f90 | 2 +- .../OpenMP/wsloop-reduction-add-hlfir.f90 | 2 +- .../Lower/OpenMP/wsloop-reduction-add.f90 | 8 +- .../Lower/OpenMP/wsloop-reduction-array.f90 | 2 +- .../Lower/OpenMP/wsloop-reduction-array2.f90 | 2 +- .../OpenMP/wsloop-reduction-iand-byref.f90 | 2 +- .../Lower/OpenMP/wsloop-reduction-iand.f90 | 2 +- .../OpenMP/wsloop-reduction-ieor-byref.f90 | 2 +- .../Lower/OpenMP/wsloop-reduction-ieor.f90 | 2 +- .../OpenMP/wsloop-reduction-ior-byref.f90 | 2 +- .../Lower/OpenMP/wsloop-reduction-ior.f90 | 2 +- .../wsloop-reduction-logical-and-byref.f90 | 2 +- .../OpenMP/wsloop-reduction-logical-and.f90 | 2 +- .../wsloop-reduction-logical-eqv-byref.f90 | 2 +- .../OpenMP/wsloop-reduction-logical-eqv.f90 | 2 +- .../wsloop-reduction-logical-neqv-byref.f90 | 2 +- .../OpenMP/wsloop-reduction-logical-neqv.f90 | 2 +- .../wsloop-reduction-logical-or-byref.f90 | 2 +- .../OpenMP/wsloop-reduction-logical-or.f90 | 2 +- .../OpenMP/wsloop-reduction-max-byref.f90 | 4 +- .../wsloop-reduction-max-hlfir-byref.f90 | 2 +- .../OpenMP/wsloop-reduction-max-hlfir.f90 | 2 +- .../Lower/OpenMP/wsloop-reduction-max.f90 | 4 +- .../OpenMP/wsloop-reduction-min-byref.f90 | 4 +- .../Lower/OpenMP/wsloop-reduction-min.f90 | 4 +- .../Lower/OpenMP/wsloop-reduction-min2.f90 | 2 +- .../OpenMP/wsloop-reduction-mul-byref.f90 | 8 +- .../Lower/OpenMP/wsloop-reduction-mul.f90 | 8 +- .../omp-descriptor-map-info-gen.fir | 16 +- .../omp-reduction-cfg-conversion.fir | 2 +- mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 65 ++++---- .../Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp | 40 ++--- .../Conversion/SCFToOpenMP/SCFToOpenMP.cpp | 30 ++-- mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 60 ++++---- .../OpenMP/OpenMPToLLVMIRTranslation.cpp | 95 ++++++------ .../OpenMPToLLVM/convert-to-llvmir.mlir | 64 ++++---- .../Conversion/SCFToOpenMP/reductions.mlir | 12 +- mlir/test/Dialect/OpenMP/invalid.mlir | 80 +++++----- mlir/test/Dialect/OpenMP/ops.mlir | 126 ++++++++-------- .../omptarget-array-sectioning-host.mlir | 8 +- ...target-byref-bycopy-generation-device.mlir | 4 +- ...mptarget-byref-bycopy-generation-host.mlir | 4 +- .../omptarget-constant-alloca-raise.mlir | 2 +- ...arget-constant-indexing-device-region.mlir | 4 +- .../omptarget-declare-target-llvm-device.mlir | 2 +- ...target-fortran-allocatable-types-host.mlir | 18 +-- mlir/test/Target/LLVMIR/omptarget-llvm.mlir | 38 ++--- .../Target/LLVMIR/omptarget-nowait-llvm.mlir | 8 +- .../LLVMIR/omptarget-parallel-llvm.mlir | 8 +- .../LLVMIR/omptarget-region-device-llvm.mlir | 6 +- .../Target/LLVMIR/omptarget-region-llvm.mlir | 6 +- .../omptarget-region-parallel-llvm.mlir | 6 +- mlir/test/Target/LLVMIR/openmp-llvm.mlir | 4 +- .../Target/LLVMIR/openmp-reduction-byref.mlir | 2 +- .../Target/LLVMIR/openmp-reduction-call.mlir | 2 +- mlir/test/Target/LLVMIR/openmp-reduction.mlir | 16 +- 112 files changed, 773 insertions(+), 769 deletions(-) diff --git a/flang/docs/OpenMP-descriptor-management.md b/flang/docs/OpenMP-descriptor-management.md index 90a20282e051..368ff3e911fc 100644 --- a/flang/docs/OpenMP-descriptor-management.md +++ b/flang/docs/OpenMP-descriptor-management.md @@ -49,15 +49,16 @@ the lowering to FIR/HLFIR has been performed an OpenMP dialect specific pass for mappings, with one extra per pointer member in the descriptor that is supported on top of the original descriptor map operation. These pointers members are linked to the parent descriptor by adding them to the member field of the original descriptor map operation, they are then inserted into the relevant map -owning operation's (`omp.TargetOp`, `omp.DataOp` etc.) map operand list and in cases where the owning operation -is `IsolatedFromAbove`, it also inserts them as `BlockArgs` to canonicalize the mappings and simplify lowering. +owning operation's (`omp.TargetOp`, `omp.TargetDataOp` etc.) map operand list and in cases where the owning +operation is `IsolatedFromAbove`, it also inserts them as `BlockArgs` to canonicalize the mappings and +simplify lowering. An example transformation by the `OMPDescriptorMapInfoGenPass`: ``` ... -%12 = omp.map_info var_ptr(%1#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.box<!fir.ptr<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%11) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {name = "arg_alloc"} +%12 = omp.map.info var_ptr(%1#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.box<!fir.ptr<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%11) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {name = "arg_alloc"} ... omp.target map_entries(%12 -> %arg1, %13 -> %arg2 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<i32>) { ^bb0(%arg1: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, %arg2: !fir.ref<i32>): @@ -67,8 +68,8 @@ omp.target map_entries(%12 -> %arg1, %13 -> %arg2 : !fir.ref<!fir.box<!fir.ptr<! ... %12 = fir.box_offset %1#1 base_addr : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> -%13 = omp.map_info var_ptr(%1#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%12 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%11) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} -%14 = omp.map_info var_ptr(%1#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.box<!fir.ptr<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) members(%13 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {name = "arg_alloc"} +%13 = omp.map.info var_ptr(%1#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%12 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%11) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} +%14 = omp.map.info var_ptr(%1#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.box<!fir.ptr<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) members(%13 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {name = "arg_alloc"} ... omp.target map_entries(%13 -> %arg1, %14 -> %arg2, %15 -> %arg3 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<i32>) { ^bb0(%arg1: !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, %arg2: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, %arg3: !fir.ref<i32>): diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index e6ea92d81440..978911c21794 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -169,7 +169,7 @@ def CFGConversionOnFunc : CFGConversionBase<"func", "mlir::func::FuncOp"> { let constructor = "::fir::createFirToCfgOnFuncPass()"; } -def CFGConversionOnReduction : CFGConversionBase<"reduce", "mlir::omp::ReductionDeclareOp"> { +def CFGConversionOnReduction : CFGConversionBase<"reduce", "mlir::omp::DeclareReductionOp"> { let constructor = "::fir::createFirToCfgOnReductionPass()"; } diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index 21b36dba9ac7..bc6df2c83069 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -124,7 +124,7 @@ static void addCanonicalizerPassWithoutRegionSimplification( inline void addCfgConversionPass(mlir::PassManager &pm) { addNestedPassConditionally<mlir::func::FuncOp>( pm, disableCfgConversion, fir::createFirToCfgOnFuncPass); - addNestedPassConditionally<mlir::omp::ReductionDeclareOp>( + addNestedPassConditionally<mlir::omp::DeclareReductionOp>( pm, disableCfgConversion, fir::createFirToCfgOnReductionPass); } diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 13347c8cf7b6..ae798b5c0a58 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -870,8 +870,8 @@ bool ClauseProcessor::processMap( Fortran::lower::AddrAndBoundsInfo info = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::OmpObject, mlir::omp::DataBoundsOp, - mlir::omp::DataBoundsType>( + Fortran::parser::OmpObject, mlir::omp::MapBoundsOp, + mlir::omp::MapBoundsType>( converter, firOpBuilder, semaCtx, stmtCtx, ompObject, clauseLocation, asFortran, bounds, treatIndexAsSection); @@ -914,8 +914,9 @@ bool ClauseProcessor::processReduction( [&](const omp::clause::Reduction &clause, const Fortran::parser::CharBlock &) { ReductionProcessor rp; - rp.addReductionDecl(currentLocation, converter, clause, reductionVars, - reductionDeclSymbols, reductionSymbols); + rp.addDeclareReduction(currentLocation, converter, clause, + reductionVars, reductionDeclSymbols, + reductionSymbols); }); } diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index 3f6adcce8ae8..c2db0cfc3cb7 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -217,8 +217,8 @@ bool ClauseProcessor::processMotionClauses( std::stringstream asFortran; Fortran::lower::AddrAndBoundsInfo info = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::OmpObject, mlir::omp::DataBoundsOp, - mlir::omp::DataBoundsType>( + Fortran::parser::OmpObject, mlir::omp::MapBoundsOp, + mlir::omp::MapBoundsType>( converter, firOpBuilder, semaCtx, stmtCtx, ompObject, clauseLocation, asFortran, bounds, treatIndexAsSection); diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp index a5c087e45241..e1aa7524e930 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp @@ -208,7 +208,7 @@ void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { firOpBuilder.restoreInsertionPoint(unstructuredSectionsIP); } } - } else if (mlir::isa<mlir::omp::WsLoopOp>(op)) { + } else if (mlir::isa<mlir::omp::WsloopOp>(op)) { // Update the original variable just before exiting the worksharing // loop. Conversion as follows: // @@ -237,8 +237,8 @@ void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { mlir::Value iv = op->getRegion(0).front().getArguments()[0]; mlir::Value ub = - mlir::dyn_cast<mlir::omp::WsLoopOp>(op).getUpperBound()[0]; - mlir::Value step = mlir::dyn_cast<mlir::omp::WsLoopOp>(op).getStep()[0]; + mlir::dyn_cast<mlir::omp::WsloopOp>(op).getUpperBound()[0]; + mlir::Value step = mlir::dyn_cast<mlir::omp::WsloopOp>(op).getStep()[0]; // v = iv + step // cmp = step < 0 ? v < ub : v > ub diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index eaaa8fcd165a..5c4caa1de573 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -365,7 +365,7 @@ static void createBodyOfOp(Op &op, OpWithBodyGenInfo &info) { // Start with privatization, so that the lowering of the nested // code will use the right symbols. - constexpr bool isLoop = std::is_same_v<Op, mlir::omp::WsLoopOp> || + constexpr bool isLoop = std::is_same_v<Op, mlir::omp::WsloopOp> || std::is_same_v<Op, mlir::omp::SimdLoopOp>; bool privatize = info.clauses && !info.outerCombined; @@ -465,7 +465,7 @@ static void genBodyOfTargetDataOp( Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, bool genNested, - mlir::omp::DataOp &dataOp, llvm::ArrayRef<mlir::Type> useDeviceTypes, + mlir::omp::TargetDataOp &dataOp, llvm::ArrayRef<mlir::Type> useDeviceTypes, llvm::ArrayRef<mlir::Location> useDeviceLocs, llvm::ArrayRef<const Fortran::semantics::Symbol *> useDeviceSymbols, const mlir::Location ¤tLocation) { @@ -775,8 +775,8 @@ genTaskOp(Fortran::lower::AbstractConverter &converter, dependOperands, allocateOperands, allocatorOperands); } -static mlir::omp::TaskGroupOp -genTaskGroupOp(Fortran::lower::AbstractConverter &converter, +static mlir::omp::TaskgroupOp +genTaskgroupOp(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, bool genNested, mlir::Location currentLocation, @@ -786,7 +786,7 @@ genTaskGroupOp(Fortran::lower::AbstractConverter &converter, cp.processAllocate(allocatorOperands, allocateOperands); cp.processTODO<Fortran::parser::OmpClause::TaskReduction>( currentLocation, llvm::omp::Directive::OMPD_taskgroup); - return genOpWithBody<mlir::omp::TaskGroupOp>( + return genOpWithBody<mlir::omp::TaskgroupOp>( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) .setGenNested(genNested) .setClauses(&clauseList), @@ -847,12 +847,12 @@ static void promoteNonCPtrUseDevicePtrArgsToUseDeviceAddr( } } -static mlir::omp::DataOp -genDataOp(Fortran::lower::AbstractConverter &converter, - Fortran::semantics::SemanticsContext &semaCtx, - Fortran::lower::pft::Evaluation &eval, bool genNested, - mlir::Location currentLocation, - const Fortran::parser::OmpClauseList &clauseList) { +static mlir::omp::TargetDataOp +genTargetDataOp(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, + Fortran::lower::pft::Evaluation &eval, bool genNested, + mlir::Location currentLocation, + const Fortran::parser::OmpClauseList &clauseList) { Fortran::lower::StatementContext stmtCtx; mlir::Value ifClauseOperand, deviceOperand; llvm::SmallVector<mlir::Value> mapOperands, devicePtrOperands, @@ -885,7 +885,7 @@ genDataOp(Fortran::lower::AbstractConverter &converter, cp.processMap(currentLocation, llvm::omp::Directive::OMPD_target_data, stmtCtx, mapOperands); - auto dataOp = converter.getFirOpBuilder().create<mlir::omp::DataOp>( + auto dataOp = converter.getFirOpBuilder().create<mlir::omp::TargetDataOp>( currentLocation, ifClauseOperand, deviceOperand, devicePtrOperands, deviceAddrOperands, mapOperands); genBodyOfTargetDataOp(converter, semaCtx, eval, genNested, dataOp, @@ -895,11 +895,11 @@ genDataOp(Fortran::lower::AbstractConverter &converter, } template <typename OpTy> -static OpTy -genEnterExitUpdateDataOp(Fortran::lower::AbstractConverter &converter, - Fortran::semantics::SemanticsContext &semaCtx, - mlir::Location currentLocation, - const Fortran::parser::OmpClauseList &clauseList) { +static OpTy genTargetEnterExitDataUpdateOp( + Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, + mlir::Location currentLocation, + const Fortran::parser::OmpClauseList &clauseList) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); Fortran::lower::StatementContext stmtCtx; mlir::Value ifClauseOperand, deviceOperand; @@ -910,13 +910,13 @@ genEnterExitUpdateDataOp(Fortran::lower::AbstractConverter &converter, clause::If::DirectiveNameModifier directiveName; // GCC 9.3.0 emits a (probably) bogus warning about an unused variable. [[maybe_unused]] llvm::omp::Directive directive; - if constexpr (std::is_same_v<OpTy, mlir::omp::EnterDataOp>) { + if constexpr (std::is_same_v<OpTy, mlir::omp::TargetEnterDataOp>) { directiveName = clause::If::DirectiveNameModifier::TargetEnterData; directive = llvm::omp::Directive::OMPD_target_enter_data; - } else if constexpr (std::is_same_v<OpTy, mlir::omp::ExitDataOp>) { + } else if constexpr (std::is_same_v<OpTy, mlir::omp::TargetExitDataOp>) { directiveName = clause::If::DirectiveNameModifier::TargetExitData; directive = llvm::omp::Directive::OMPD_target_exit_data; - } else if constexpr (std::is_same_v<OpTy, mlir::omp::UpdateDataOp>) { + } else if constexpr (std::is_same_v<OpTy, mlir::omp::TargetUpdateOp>) { directiveName = clause::If::DirectiveNameModifier::TargetUpdate; directive = llvm::omp::Directive::OMPD_target_update; } else { @@ -929,7 +929,7 @@ genEnterExitUpdateDataOp(Fortran::lower::AbstractConverter &converter, cp.processDepend(dependTypeOperands, dependOperands); cp.processNowait(nowaitAttr); - if constexpr (std::is_same_v<OpTy, mlir::omp::UpdateDataOp>) { + if constexpr (std::is_same_v<OpTy, mlir::omp::TargetUpdateOp>) { cp.processMotionClauses<Fortran::parser::OmpClause::To>(stmtCtx, mapOperands); cp.processMotionClauses<Fortran::parser::OmpClause::From>(stmtCtx, @@ -1162,15 +1162,15 @@ genTargetOp(Fortran::lower::AbstractConverter &converter, converter.getCurrentLocation()); if (fir::unwrapRefType(info.addr.getType()).isa<fir::BaseBoxType>()) bounds = - Fortran::lower::genBoundsOpsFromBox<mlir::omp::DataBoundsOp, - mlir::omp::DataBoundsType>( + Fortran::lower::genBoundsOpsFromBox<mlir::omp::MapBoundsOp, + mlir::omp::MapBoundsType>( converter.getFirOpBuilder(), converter.getCurrentLocation(), converter, dataExv, info); if (fir::unwrapRefType(info.addr.getType()).isa<fir::SequenceType>()) { bool dataExvIsAssumedSize = Fortran::semantics::IsAssumedSizeArray(sym.GetUltimate()); - bounds = Fortran::lower::genBaseBoundsOps<mlir::omp::DataBoundsOp, - mlir::omp::DataBoundsType>( + bounds = Fortran::lower::genBaseBoundsOps<mlir::omp::MapBoundsOp, + mlir::omp::MapBoundsType>( converter.getFirOpBuilder(), converter.getCurrentLocation(), converter, dataExv, dataExvIsAssumedSize); } @@ -1401,19 +1401,19 @@ genOmpSimpleStandalone(Fortran::lower::AbstractConverter &converter, firOpBuilder.create<mlir::omp::TaskyieldOp>(currentLocation); break; case llvm::omp::Directive::OMPD_target_data: - genDataOp(converter, semaCtx, eval, genNested, currentLocation, - opClauseList); + genTargetDataOp(converter, semaCtx, eval, genNested, currentLocation, + opClauseList); break; case llvm::omp::Directive::OMPD_target_enter_data: - genEnterExitUpdateDataOp<mlir::omp::EnterDataOp>( + genTargetEnterExitDataUpdateOp<mlir::omp::TargetEnterDataOp>( converter, semaCtx, currentLocation, opClauseList); break; case llvm::omp::Directive::OMPD_target_exit_data: - genEnterExitUpdateDataOp<mlir::omp::ExitDataOp>( + genTargetEnterExitDataUpdateOp<mlir::omp::TargetExitDataOp>( converter, semaCtx, currentLocation, opClauseList); break; case llvm::omp::Directive::OMPD_target_update: - genEnterExitUpdateDataOp<mlir::omp::UpdateDataOp>( + genTargetEnterExitDataUpdateOp<mlir::omp::TargetUpdateOp>( converter, semaCtx, currentLocation, opClauseList); break; case llvm::omp::Directive::OMPD_ordered: @@ -1625,7 +1625,7 @@ createSimdLoop(Fortran::lower::AbstractConverter &converter, .setGenRegionEntryCb(ivCallback)); } -static void createWsLoop(Fortran::lower::AbstractConverter &converter, +static void createWsloop(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, llvm::omp::Directive ompDirective, @@ -1665,7 +1665,7 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, if (ReductionProcessor::doReductionByRef(reductionVars)) byrefOperand = firOpBuilder.getUnitAttr(); - auto wsLoopOp = firOpBuilder.create<mlir::omp::WsLoopOp>( + auto wsLoopOp = firOpBuilder.create<mlir::omp::WsloopOp>( loc, lowerBound, upperBound, step, linearVars, linearStepVars, reductionVars, reductionDeclSymbols.empty() @@ -1712,7 +1712,7 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, reductionTypes); }; - createBodyOfOp<mlir::omp::WsLoopOp>( + createBodyOfOp<mlir::omp::WsloopOp>( wsLoopOp, OpWithBodyGenInfo(converter, semaCtx, loc, *nestedEval) .setClauses(&beginClauseList) .setDataSharingProcessor(&dsp) @@ -1720,7 +1720,7 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, .setGenRegionEntryCb(ivCallback)); } -static void createSimdWsLoop( +static void createSimdWsloop( Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, llvm::omp::Directive ompDirective, @@ -1740,7 +1740,7 @@ static void createSimdWsLoop( // When support for vectorization is enabled, then we need to add handling of // if clause. Currently if clause can be skipped because we always assume // SIMD length = 1. - createWsLoop(converter, semaCtx, eval, ompDirective, beginClauseList, + createWsloop(converter, semaCtx, eval, ompDirective, beginClauseList, endClauseList, loc); } @@ -1812,7 +1812,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, if (llvm::omp::allDoSimdSet.test(ompDirective)) { // 2.9.3.2 Workshare SIMD construct - createSimdWsLoop(converter, semaCtx, eval, ompDirective, loopOpClauseList, + createSimdWsloop(converter, semaCtx, eval, ompDirective, loopOpClauseList, endClauseList, currentLocation); } else if (llvm::omp::allSimdSet.test(ompDirective)) { @@ -1821,7 +1821,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, currentLocation); genOpenMPReduction(converter, semaCtx, loopOpClauseList); } else { - createWsLoop(converter, semaCtx, eval, ompDirective, loopOpClauseList, + createWsloop(converter, semaCtx, eval, ompDirective, loopOpClauseList, endClauseList, currentLocation); } } @@ -1898,15 +1898,15 @@ genOMP(Fortran::lower::AbstractConverter &converter, beginClauseList, directive.v); break; case llvm::omp::Directive::OMPD_target_data: - genDataOp(converter, semaCtx, eval, /*genNested=*/true, currentLocation, - beginClauseList); + genTargetDataOp(converter, semaCtx, eval, /*genNested=*/true, + currentLocation, beginClauseList); break; case llvm::omp::Directive::OMPD_task: genTaskOp(converter, semaCtx, eval, /*genNested=*/true, currentLocation, beginClauseList); break; case llvm::omp::Directive::OMPD_taskgroup: - genTaskGroupOp(converter, semaCtx, eval, /*genNested=*/true, + genTaskgroupOp(converter, semaCtx, eval, /*genNested=*/true, currentLocation, beginClauseList); break; case llvm::omp::Directive::OMPD_teams: @@ -2260,7 +2260,7 @@ genOMP(Fortran::lower::AbstractConverter &converter, mlir::Operation *Fortran::lower::genOpenMPTerminator(fir::FirOpBuilder &builder, mlir::Operation *op, mlir::Location loc) { - if (mlir::isa<mlir::omp::WsLoopOp, mlir::omp::ReductionDeclareOp, + if (mlir::isa<mlir::omp::WsloopOp, mlir::omp::DeclareReductionOp, mlir::omp::AtomicUpdateOp, mlir::omp::SimdLoopOp>(op)) return builder.create<mlir::omp::YieldOp>(loc); else diff --git a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp index 54d9fc556973..d01c585e0ddb 100644 --- a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp @@ -456,7 +456,7 @@ createReductionInitRegion(fir::FirOpBuilder &builder, mlir::Location loc, TODO(loc, "createReductionInitRegion for unsupported type"); } -mlir::omp::ReductionDeclareOp ReductionProcessor::createReductionDecl( +mlir::omp::DeclareReductionOp ReductionProcessor::createDeclareReduction( fir::FirOpBuilder &builder, llvm::StringRef reductionOpName, const ReductionIdentifier redId, mlir::Type type, mlir::Location loc, bool isByRef) { @@ -467,7 +467,7 @@ mlir::omp::ReductionDeclareOp ReductionProcessor::createReductionDecl( TODO(loc, "Reduction of some types is not supported"); auto decl = - module.lookupSymbol<mlir::omp::ReductionDeclareOp>(reductionOpName); + module.lookupSymbol<mlir::omp::DeclareReductionOp>(reductionOpName); if (decl) return decl; @@ -476,7 +476,7 @@ mlir::omp::ReductionDeclareOp ReductionProcessor::createReductionDecl( if (!isByRef) type = valTy; - decl = modBuilder.create<mlir::omp::ReductionDeclareOp>(loc, reductionOpName, + decl = modBuilder.create<mlir::omp::DeclareReductionOp>(loc, reductionOpName, type); builder.createBlock(&decl.getInitializerRegion(), decl.getInitializerRegion().end(), {type}, {loc}); @@ -520,7 +520,7 @@ bool ReductionProcessor::doReductionByRef( return false; } -void ReductionProcessor::addReductionDecl( +void ReductionProcessor::addDeclareReduction( mlir::Location currentLocation, Fortran::lower::AbstractConverter &converter, const omp::clause::Reduction &reduction, @@ -529,7 +529,7 @@ void ReductionProcessor::addReductionDecl( llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *reductionSymbols) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - mlir::omp::ReductionDeclareOp decl; + mlir::omp::DeclareReductionOp decl; const auto &redOperator{ std::get<omp::clause::ReductionOperator>(reduction.t)}; const auto &objectList{std::get<omp::ObjectList>(reduction.t)}; @@ -602,12 +602,12 @@ void ReductionProcessor::addReductionDecl( for (mlir::Value symVal : reductionVars) { auto redType = mlir::cast<fir::ReferenceType>(symVal.getType()); if (redType.getEleTy().isa<fir::LogicalType>()) - decl = createReductionDecl( + decl = createDeclareReduction( firOpBuilder, getReductionName(intrinsicOp, firOpBuilder.getI1Type(), isByRef), redId, redType, currentLocation, isByRef); else - decl = createReductionDecl( + decl = createDeclareReduction( firOpBuilder, getReductionName(intrinsicOp, redType, isByRef), redId, redType, currentLocation, isByRef); reductionDeclSymbols.push_back(mlir::SymbolRefAttr::get( @@ -628,7 +628,7 @@ void ReductionProcessor::addReductionDecl( auto redType = symVal.getType().cast<fir::ReferenceType>(); if (!redType.getEleTy().isIntOrIndexOrFloat()) TODO(currentLocation, "User Defined Reduction on non-trivial type"); - decl = createReductionDecl( + decl = createDeclareReduction( firOpBuilder, getReductionName(getRealName(*reductionIntrinsic).ToString(), redType, isByRef), diff --git a/flang/lib/Lower/OpenMP/ReductionProcessor.h b/flang/lib/Lower/OpenMP/ReductionProcessor.h index f481d4cbd1c5..52b44e555bdb 100644 --- a/flang/lib/Lower/OpenMP/ReductionProcessor.h +++ b/flang/lib/Lower/OpenMP/ReductionProcessor.h @@ -24,7 +24,7 @@ namespace mlir { namespace omp { -class ReductionDeclareOp; +class DeclareReductionOp; } // namespace omp } // namespace mlir @@ -109,22 +109,22 @@ public: /// symbol table. The declaration has a constant initializer with the neutral /// value `initValue`, and the reduction combiner carried over from `reduce`. /// TODO: add atomic region. - static mlir::omp::ReductionDeclareOp - createReductionDecl(fir::FirOpBuilder &builder, - llvm::StringRef reductionOpName, - const ReductionIdentifier redId, mlir::Type type, - mlir::Location loc, bool isByRef); + static mlir::omp::DeclareReductionOp + createDeclareReduction(fir::FirOpBuilder &builder, + llvm::StringRef reductionOpName, + const ReductionIdentifier redId, mlir::Type type, + mlir::Location loc, bool isByRef); /// Creates a reduction declaration and associates it with an OpenMP block /// directive. - static void - addReductionDecl(mlir::Location currentLocation, - Fortran::lower::AbstractConverter &converter, - const omp::clause::Reduction &reduction, - llvm::SmallVectorImpl<mlir::Value> &reductionVars, - llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols, - llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> - *reductionSymbols = nullptr); + static void addDeclareReduction( + mlir::Location currentLocation, + Fortran::lower::AbstractConverter &converter, + const omp::clause::Reduction &reduction, + llvm::SmallVectorImpl<mlir::Value> &reductionVars, + llvm::SmallVectorImpl<mlir::Attribute> &reductionDeclSymbols, + llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> + *reductionSymbols = nullptr); }; template <typename FloatOp, typename IntegerOp> diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp index f7327a299d9a..2bcd5e591402 100644 --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -208,7 +208,7 @@ mlir::Block *fir::FirOpBuilder::getAllocaBlock() { .getParentOfType<mlir::omp::OutlineableOpenMPOpInterface>()) { return ompOutlineableIface.getAllocaBlock(); } - if (mlir::isa<mlir::omp::ReductionDeclareOp>(getRegion().getParentOp())) + if (mlir::isa<mlir::omp::DeclareReductionOp>(getRegion().getParentOp())) return &getRegion().front(); if (auto accRecipeIface = getRegion().getParentOfType<mlir::acc::RecipeInterface>()) { diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index e941a0226ca5..faf90ef6b50a 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -410,8 +410,8 @@ protected: mlir::ConversionPatternRewriter &rewriter) const { auto thisPt = rewriter.saveInsertionPoint(); mlir::Operation *parentOp = rewriter.getInsertionBlock()->getParentOp(); - if (mlir::isa<mlir::omp::ReductionDeclareOp>(parentOp)) { - // ReductionDeclareOp has multiple child regions. We want to get the first + if (mlir::isa<mlir::omp::DeclareReductionOp>(parentOp)) { + // DeclareReductionOp has multiple child regions. We want to get the first // block of whichever of those regions we are currently in mlir::Region *parentRegion = rewriter.getInsertionBlock()->getParent(); rewriter.setInsertionPointToStart(&parentRegion->front()); diff --git a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 b/flang/test/Driver/bbc-mlir-pass-pipeline.f90 index b25edf359917..bd7facad1ce1 100644 --- a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 +++ b/flang/test/Driver/bbc-mlir-pass-pipeline.f90 @@ -38,11 +38,11 @@ end program ! CHECK-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! CHECK-NEXT: (S) 0 num-dce'd - Number of operations DCE'd -! CHECK-NEXT: Pipeline Collection : ['func.func', 'omp.reduction.declare'] +! CHECK-NEXT: Pipeline Collection : ['func.func', 'omp.declare_reduction'] ! CHECK-NEXT: 'func.func' Pipeline ! CHECK-NEXT: PolymorphicOpConversion ! CHECK-NEXT: CFGConversionOnFunc -! CHECK-NEXT: 'omp.reduction.declare' Pipeline +! CHECK-NEXT: 'omp.declare_reduction' Pipeline ! CHECK-NEXT: CFGConversionOnReduction ! CHECK-NEXT: SCFToControlFlow diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90 index a865b170c3d4..e714a66b85f3 100644 --- a/flang/test/Driver/mlir-debug-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90 @@ -58,11 +58,11 @@ end program ! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd -! ALL-NEXT: Pipeline Collection : ['func.func', 'omp.reduction.declare'] +! ALL-NEXT: Pipeline Collection : ['func.func', 'omp.declare_reduction'] ! ALL-NEXT: 'func.func' Pipeline ! ALL-NEXT: PolymorphicOpConversion ! ALL-NEXT: CFGConversionOnFunc -! ALL-NEXT: 'omp.reduction.declare' Pipeline +! ALL-NEXT: 'omp.declare_reduction' Pipeline ! ALL-NEXT: CFGConversionOnReduction ! ALL-NEXT: SCFToControlFlow ! ALL-NEXT: Canonicalizer diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90 index ee3f41a15ca4..cfa0de63cde5 100644 --- a/flang/test/Driver/mlir-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-pass-pipeline.f90 @@ -52,11 +52,11 @@ end program ! O2-NEXT: 'func.func' Pipeline ! O2-NEXT: PolymorphicOpConversion ! O2-NEXT: AddAliasTags -! ALL-NEXT: Pipeline Collection : ['func.func', 'omp.reduction.declare'] +! ALL-NEXT: Pipeline Collection : ['func.func', 'omp.declare_reduction'] ! ALL-NEXT: 'func.func' Pipeline ! NOTO2-NEXT: PolymorphicOpConversion ! ALL-NEXT: CFGConversionOnFunc -! ALL-NEXT: 'omp.reduction.declare' Pipeline +! ALL-NEXT: 'omp.declare_reduction' Pipeline ! ALL-NEXT: CFGConversionOnReduction ! ALL-NEXT: SCFToControlFlow diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir index 516946bd4fb4..80d3520bc7f7 100644 --- a/flang/test/Fir/basic-program.fir +++ b/flang/test/Fir/basic-program.fir @@ -60,10 +60,10 @@ func.func @_QQmain() { // PASSES-NEXT: AddAliasTags -// PASSES-NEXT: Pipeline Collection : ['func.func', 'omp.reduction.declare'] +// PASSES-NEXT: Pipeline Collection : ['func.func', 'omp.declare_reduction'] // PASSES-NEXT: 'func.func' Pipeline // PASSES-NEXT: CFGConversionOnFunc -// PASSES-NEXT: 'omp.reduction.declare' Pipeline +// PASSES-NEXT: 'omp.declare_reduction' Pipeline // PASSES-NEXT: CFGConversionOnReduction // PASSES-NEXT: SCFToControlFlow diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir index 8d9bdca4bf54..92628af37085 100644 --- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir +++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir @@ -231,39 +231,39 @@ func.func @_QPomp_target_data() { %c1 = arith.constant 1 : index %c0 = arith.constant 0 : index %4 = arith.subi %c1024, %c1 : index - %5 = omp.bounds lower_bound(%c0 : index) upper_bound(%4 : index) extent(%c1024 : index) stride(%c1 : index) start_idx(%c1 : index) - %6 = omp.map_info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(to) capture(ByRef) bounds(%5) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + %5 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%4 : index) extent(%c1024 : index) stride(%c1 : index) start_idx(%c1 : index) + %6 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(to) capture(ByRef) bounds(%5) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} %c1_3 = arith.constant 1 : index %c0_4 = arith.constant 0 : index %7 = arith.subi %c1024_0, %c1_3 : index - %8 = omp.bounds lower_bound(%c0_4 : index) upper_bound(%7 : index) extent(%c1024_0 : index) stride(%c1_3 : index) start_idx(%c1_3 : index) - %9 = omp.map_info var_ptr(%1 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(to) capture(ByRef) bounds(%8) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} + %8 = omp.map.bounds lower_bound(%c0_4 : index) upper_bound(%7 : index) extent(%c1024_0 : index) stride(%c1_3 : index) start_idx(%c1_3 : index) + %9 = omp.map.info var_ptr(%1 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(to) capture(ByRef) bounds(%8) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} %c1_5 = arith.constant 1 : index %c0_6 = arith.constant 0 : index %10 = arith.subi %c1024_1, %c1_5 : index - %11 = omp.bounds lower_bound(%c0_6 : index) upper_bound(%10 : index) extent(%c1024_1 : index) stride(%c1_5 : index) start_idx(%c1_5 : index) - %12 = omp.map_info var_ptr(%2 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%11) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} + %11 = omp.map.bounds lower_bound(%c0_6 : index) upper_bound(%10 : index) extent(%c1024_1 : index) stride(%c1_5 : index) start_idx(%c1_5 : index) + %12 = omp.map.info var_ptr(%2 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%11) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} omp.target_enter_data map_entries(%6, %9, %12 : !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) %c1_7 = arith.constant 1 : index %c0_8 = arith.constant 0 : index %13 = arith.subi %c1024, %c1_7 : index - %14 = omp.bounds lower_bound(%c0_8 : index) upper_bound(%13 : index) extent(%c1024 : index) stride(%c1_7 : index) start_idx(%c1_7 : index) - %15 = omp.map_info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(from) capture(ByRef) bounds(%14) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + %14 = omp.map.bounds lower_bound(%c0_8 : index) upper_bound(%13 : index) extent(%c1024 : index) stride(%c1_7 : index) start_idx(%c1_7 : index) + %15 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(from) capture(ByRef) bounds(%14) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} %c1_9 = arith.constant 1 : index %c0_10 = arith.constant 0 : index %16 = arith.subi %c1024_0, %c1_9 : index - %17 = omp.bounds lower_bound(%c0_10 : index) upper_bound(%16 : index) extent(%c1024_0 : index) stride(%c1_9 : index) start_idx(%c1_9 : index) - %18 = omp.map_info var_ptr(%1 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(from) capture(ByRef) bounds(%17) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} + %17 = omp.map.bounds lower_bound(%c0_10 : index) upper_bound(%16 : index) extent(%c1024_0 : index) stride(%c1_9 : index) start_idx(%c1_9 : index) + %18 = omp.map.info var_ptr(%1 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(from) capture(ByRef) bounds(%17) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} %c1_11 = arith.constant 1 : index %c0_12 = arith.constant 0 : index %19 = arith.subi %c1024_1, %c1_11 : index - %20 = omp.bounds lower_bound(%c0_12 : index) upper_bound(%19 : index) extent(%c1024_1 : index) stride(%c1_11 : index) start_idx(%c1_11 : index) - %21 = omp.map_info var_ptr(%2 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%20) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} + %20 = omp.map.bounds lower_bound(%c0_12 : index) upper_bound(%19 : index) extent(%c1024_1 : index) stride(%c1_11 : index) start_idx(%c1_11 : index) + %21 = omp.map.info var_ptr(%2 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%20) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} %c1_13 = arith.constant 1 : index %c0_14 = arith.constant 0 : index %22 = arith.subi %c1024_2, %c1_13 : index - %23 = omp.bounds lower_bound(%c0_14 : index) upper_bound(%22 : index) extent(%c1024_2 : index) stride(%c1_13 : index) start_idx(%c1_13 : index) - %24 = omp.map_info var_ptr(%3 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(always, delete) capture(ByRef) bounds(%23) -> !fir.ref<!fir.array<1024xi32>> {name = "d"} + %23 = omp.map.bounds lower_bound(%c0_14 : index) upper_bound(%22 : index) extent(%c1024_2 : index) stride(%c1_13 : index) start_idx(%c1_13 : index) + %24 = omp.map.info var_ptr(%3 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(always, delete) capture(ByRef) bounds(%23) -> !fir.ref<!fir.array<1024xi32>> {name = "d"} omp.target_exit_data map_entries(%15, %18, %21, %24 : !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) return } @@ -284,39 +284,39 @@ func.func @_QPomp_target_data() { // CHECK: %12 = llvm.mlir.constant(1 : index) : i64 // CHECK: %13 = llvm.mlir.constant(0 : index) : i64 // CHECK: %14 = llvm.mlir.constant(1023 : index) : i64 - // CHECK: %15 = omp.bounds lower_bound(%13 : i64) upper_bound(%14 : i64) extent(%0 : i64) stride(%12 : i64) start_idx(%12 : i64) - // CHECK: %16 = omp.map_info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%15) -> !llvm.ptr {name = "a"} + // CHECK: %15 = omp.map.bounds lower_bound(%13 : i64) upper_bound(%14 : i64) extent(%0 : i64) stride(%12 : i64) start_idx(%12 : i64) + // CHECK: %16 = omp.map.info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%15) -> !llvm.ptr {name = "a"} // CHECK: %17 = llvm.mlir.constant(1 : index) : i64 // CHECK: %18 = llvm.mlir.constant(0 : index) : i64 // CHECK: %19 = llvm.mlir.constant(1023 : index) : i64 - // CHECK: %20 = omp.bounds lower_bound(%18 : i64) upper_bound(%19 : i64) extent(%3 : i64) stride(%17 : i64) start_idx(%17 : i64) - // CHECK: %21 = omp.map_info var_ptr(%[[VAL_3]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%20) -> !llvm.ptr {name = "b"} + // CHECK: %20 = omp.map.bounds lower_bound(%18 : i64) upper_bound(%19 : i64) extent(%3 : i64) stride(%17 : i64) start_idx(%17 : i64) + // CHECK: %21 = omp.map.info var_ptr(%[[VAL_3]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%20) -> !llvm.ptr {name = "b"} // CHECK: %22 = llvm.mlir.constant(1 : index) : i64 // CHECK: %23 = llvm.mlir.constant(0 : index) : i64 // CHECK: %24 = llvm.mlir.constant(1023 : index) : i64 - // CHECK: %25 = omp.bounds lower_bound(%23 : i64) upper_bound(%24 : i64) extent(%6 : i64) stride(%22 : i64) start_idx(%22 : i64) - // CHECK: %26 = omp.map_info var_ptr(%[[VAL_5]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%25) -> !llvm.ptr {name = "c"} + // CHECK: %25 = omp.map.bounds lower_bound(%23 : i64) upper_bound(%24 : i64) extent(%6 : i64) stride(%22 : i64) start_idx(%22 : i64) + // CHECK: %26 = omp.map.info var_ptr(%[[VAL_5]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%25) -> !llvm.ptr {name = "c"} // CHECK: omp.target_enter_data map_entries(%16, %21, %26 : !llvm.ptr, !llvm.ptr, !llvm.ptr) // CHECK: %27 = llvm.mlir.constant(1 : index) : i64 // CHECK: %28 = llvm.mlir.constant(0 : index) : i64 // CHECK: %29 = llvm.mlir.constant(1023 : index) : i64 - // CHECK: %30 = omp.bounds lower_bound(%28 : i64) upper_bound(%29 : i64) extent(%0 : i64) stride(%27 : i64) start_idx(%27 : i64) - // CHECK: %31 = omp.map_info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%30) -> !llvm.ptr {name = "a"} + // CHECK: %30 = omp.map.bounds lower_bound(%28 : i64) upper_bound(%29 : i64) extent(%0 : i64) stride(%27 : i64) start_idx(%27 : i64) + // CHECK: %31 = omp.map.info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%30) -> !llvm.ptr {name = "a"} // CHECK: %32 = llvm.mlir.constant(1 : index) : i64 // CHECK: %33 = llvm.mlir.constant(0 : index) : i64 // CHECK: %34 = llvm.mlir.constant(1023 : index) : i64 - // CHECK: %35 = omp.bounds lower_bound(%33 : i64) upper_bound(%34 : i64) extent(%3 : i64) stride(%32 : i64) start_idx(%32 : i64) - // CHECK: %36 = omp.map_info var_ptr(%[[VAL_3]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%35) -> !llvm.ptr {name = "b"} + // CHECK: %35 = omp.map.bounds lower_bound(%33 : i64) upper_bound(%34 : i64) extent(%3 : i64) stride(%32 : i64) start_idx(%32 : i64) + // CHECK: %36 = omp.map.info var_ptr(%[[VAL_3]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%35) -> !llvm.ptr {name = "b"} // CHECK: %37 = llvm.mlir.constant(1 : index) : i64 // CHECK: %38 = llvm.mlir.constant(0 : index) : i64 // CHECK: %39 = llvm.mlir.constant(1023 : index) : i64 - // CHECK: %40 = omp.bounds lower_bound(%38 : i64) upper_bound(%39 : i64) extent(%6 : i64) stride(%37 : i64) start_idx(%37 : i64) - // CHECK: %41 = omp.map_info var_ptr(%[[VAL_5]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%40) -> !llvm.ptr {name = "c"} + // CHECK: %40 = omp.map.bounds lower_bound(%38 : i64) upper_bound(%39 : i64) extent(%6 : i64) stride(%37 : i64) start_idx(%37 : i64) + // CHECK: %41 = omp.map.info var_ptr(%[[VAL_5]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%40) -> !llvm.ptr {name = "c"} // CHECK: %42 = llvm.mlir.constant(1 : index) : i64 // CHECK: %43 = llvm.mlir.constant(0 : index) : i64 // CHECK: %44 = llvm.mlir.constant(1023 : index) : i64 - // CHECK: %45 = omp.bounds lower_bound(%43 : i64) upper_bound(%44 : i64) extent(%9 : i64) stride(%42 : i64) start_idx(%42 : i64) - // CHECK: %46 = omp.map_info var_ptr(%[[VAL_7]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, delete) capture(ByRef) bounds(%45) -> !llvm.ptr {name = "d"} + // CHECK: %45 = omp.map.bounds lower_bound(%43 : i64) upper_bound(%44 : i64) extent(%9 : i64) stride(%42 : i64) start_idx(%42 : i64) + // CHECK: %46 = omp.map.info var_ptr(%[[VAL_7]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, delete) capture(ByRef) bounds(%45) -> !llvm.ptr {name = "d"} // CHECK: omp.target_exit_data map_entries(%31, %36, %41, %46 : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) // CHECK: llvm.return // CHECK: } @@ -330,8 +330,8 @@ func.func @_QPopenmp_target_data_region() { %c3 = arith.constant 1 : index %c0 = arith.constant 0 : index %c2 = arith.subi %c1024, %c3 : index - %bound = omp.bounds lower_bound(%c0 : index) upper_bound(%c2 : index) extent(%c1024 : index) stride(%c3 : index) start_idx(%c3 : index) - %entry = omp.map_info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%bound) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + %bound = omp.map.bounds lower_bound(%c0 : index) upper_bound(%c2 : index) extent(%c1024 : index) stride(%c3 : index) start_idx(%c3 : index) + %entry = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%bound) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} omp.target_data map_entries(%entry : !fir.ref<!fir.array<1024xi32>>) { %c1_i32 = arith.constant 1 : i32 %2 = fir.convert %c1_i32 : (i32) -> index @@ -369,8 +369,8 @@ func.func @_QPopenmp_target_data_region() { // CHECK: %[[VAL_ONE:.*]] = llvm.mlir.constant(1 : index) : i64 // CHECK: %[[VAL_ZERO:.*]] = llvm.mlir.constant(0 : index) : i64 // CHECK: %[[VAL_UPPER:.*]] = llvm.mlir.constant(1023 : index) : i64 -// CHECK: %[[VAL_BOUNDS:.*]] = omp.bounds lower_bound(%[[VAL_ZERO]] : i64) upper_bound(%[[VAL_UPPER]] : i64) extent(%[[VAL_MAX]] : i64) stride(%[[VAL_ONE]] : i64) start_idx(%[[VAL_ONE]] : i64) -// CHECK: %[[VAL_MAP:.*]] = omp.map_info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_BOUNDS]]) -> !llvm.ptr {name = "a"} +// CHECK: %[[VAL_BOUNDS:.*]] = omp.map.bounds lower_bound(%[[VAL_ZERO]] : i64) upper_bound(%[[VAL_UPPER]] : i64) extent(%[[VAL_MAX]] : i64) stride(%[[VAL_ONE]] : i64) start_idx(%[[VAL_ONE]] : i64) +// CHECK: %[[VAL_MAP:.*]] = omp.map.info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_BOUNDS]]) -> !llvm.ptr {name = "a"} // CHECK: omp.target_data map_entries(%[[VAL_MAP]] : !llvm.ptr) { // CHECK: %[[VAL_4:.*]] = llvm.mlir.constant(1 : i32) : i32 // CHECK: %[[VAL_5:.*]] = llvm.sext %[[VAL_4]] : i32 to i64 @@ -431,8 +431,8 @@ func.func @_QPomp_target() { %c1 = arith.constant 1 : index %c0 = arith.constant 0 : index %1 = arith.subi %c512, %c1 : index - %2 = omp.bounds lower_bound(%c0 : index) upper_bound(%1 : index) extent(%c512 : index) stride(%c1 : index) start_idx(%c1 : index) - %3 = omp.map_info var_ptr(%0 : !fir.ref<!fir.array<512xi32>>, !fir.array<512xi32>) map_clauses(tofrom) capture(ByRef) bounds(%2) -> !fir.ref<!fir.array<512xi32>> {name = "a"} + %2 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%1 : index) extent(%c512 : index) stride(%c1 : index) start_idx(%c1 : index) + %3 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<512xi32>>, !fir.array<512xi32>) map_clauses(tofrom) capture(ByRef) bounds(%2) -> !fir.ref<!fir.array<512xi32>> {name = "a"} omp.target thread_limit(%c64_i32 : i32) map_entries(%3 -> %arg0 : !fir.ref<!fir.array<512xi32>>) { ^bb0(%arg0: !fir.ref<!fir.array<512xi32>>): %c10_i32 = arith.constant 10 : i32 @@ -454,8 +454,8 @@ func.func @_QPomp_target() { // CHECK: %[[STRIDE:.*]] = llvm.mlir.constant(1 : index) : i64 // CHECK: %[[LOWER:.*]] = llvm.mlir.constant(0 : index) : i64 // CHECK: %[[UPPER:.*]] = llvm.mlir.constant(511 : index) : i64 -// CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[LOWER]] : i64) upper_bound(%[[UPPER]] : i64) extent(%[[EXTENT]] : i64) stride(%[[STRIDE]] : i64) start_idx(%[[STRIDE]] : i64) -// CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%2 : !llvm.ptr, !llvm.array<512 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr {name = "a"} +// CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%[[LOWER]] : i64) upper_bound(%[[UPPER]] : i64) extent(%[[EXTENT]] : i64) stride(%[[STRIDE]] : i64) start_idx(%[[STRIDE]] : i64) +// CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%2 : !llvm.ptr, !llvm.array<512 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr {name = "a"} // CHECK: omp.target thread_limit(%[[VAL_2]] : i32) map_entries(%[[MAP]] -> %[[ARG_0:.*]] : !llvm.ptr) { // CHECK: ^bb0(%[[ARG_0]]: !llvm.ptr): // CHECK: %[[VAL_3:.*]] = llvm.mlir.constant(10 : i32) : i32 @@ -683,7 +683,7 @@ func.func @_QPsb() { // ----- -// CHECK: omp.reduction.declare @[[EQV_REDUCTION:.*]] : i32 init { +// CHECK: omp.declare_reduction @[[EQV_REDUCTION:.*]] : i32 init { // CHECK: ^bb0(%{{.*}}: i32): // CHECK: %[[TRUE:.*]] = llvm.mlir.constant(1 : i64) : i32 // CHECK: omp.yield(%[[TRUE]] : i32) @@ -716,7 +716,7 @@ func.func @_QPsb() { // CHECK: omp.terminator // CHECK: llvm.return -omp.reduction.declare @eqv_reduction : !fir.logical<4> init { +omp.declare_reduction @eqv_reduction : !fir.logical<4> init { ^bb0(%arg0: !fir.logical<4>): %true = arith.constant true %0 = fir.convert %true : (i1) -> !fir.logical<4> @@ -820,8 +820,8 @@ func.func @sub_() { %c0 = arith.constant 0 : index %c1 = arith.constant 1 : index %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsubEi"} -// CHECK: omp.ordered_region - omp.ordered_region { +// CHECK: omp.ordered.region + omp.ordered.region { %1 = fir.convert %c1 : (index) -> i32 cf.br ^bb1(%1, %c1 : i32, index) ^bb1(%2: i32, %3: index): // 2 preds: ^bb0, ^bb2 @@ -914,10 +914,10 @@ func.func @omp_critical_() { func.func @omp_map_info_descriptor_type_conversion(%arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>) { // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> %0 = fir.box_offset %arg0 base_addr : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> !fir.llvm_ptr<!fir.ref<i32>> - // CHECK: %[[MEMBER_MAP:.*]] = omp.map_info var_ptr(%[[GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} - %1 = omp.map_info var_ptr(%0 : !fir.llvm_ptr<!fir.ref<i32>>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""} - // CHECK: %[[DESC_MAP:.*]] = omp.map_info var_ptr(%[[ARG_0]] : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(always, delete) capture(ByRef) members(%[[MEMBER_MAP]] : !llvm.ptr) -> !llvm.ptr {name = ""} - %2 = omp.map_info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>) map_clauses(always, delete) capture(ByRef) members(%1 : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.heap<i32>>> {name = ""} + // CHECK: %[[MEMBER_MAP:.*]] = omp.map.info var_ptr(%[[GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %1 = omp.map.info var_ptr(%0 : !fir.llvm_ptr<!fir.ref<i32>>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""} + // CHECK: %[[DESC_MAP:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(always, delete) capture(ByRef) members(%[[MEMBER_MAP]] : !llvm.ptr) -> !llvm.ptr {name = ""} + %2 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>) map_clauses(always, delete) capture(ByRef) members(%1 : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.heap<i32>>> {name = ""} // CHECK: omp.target_exit_data map_entries(%[[DESC_MAP]] : !llvm.ptr) omp.target_exit_data map_entries(%2 : !fir.ref<!fir.box<!fir.heap<i32>>>) return diff --git a/flang/test/Fir/omp-reduction-embox-codegen.fir b/flang/test/Fir/omp-reduction-embox-codegen.fir index 24bde536667b..7602012ebc5c 100644 --- a/flang/test/Fir/omp-reduction-embox-codegen.fir +++ b/flang/test/Fir/omp-reduction-embox-codegen.fir @@ -2,12 +2,12 @@ // the fir.embox in the init region is turned into an alloca for the box. Test // that CodeGen.cpp knows where to place an alloca when it is inside of an -// omp.reduction.declare +// omp.declare_reduction // regretably this has to be nonsense IR because we need the subsequent patches // to process anything useful -omp.reduction.declare @test_reduction : !fir.ref<!fir.box<i32>> init { +omp.declare_reduction @test_reduction : !fir.ref<!fir.box<i32>> init { ^bb0(%arg0: !fir.ref<!fir.box<i32>>): %0 = fir.alloca !fir.box<i32> %1 = fir.alloca i32 diff --git a/flang/test/Lower/OpenMP/FIR/array-bounds.f90 b/flang/test/Lower/OpenMP/FIR/array-bounds.f90 index 3cd284c46e72..c2bb7a94712b 100644 --- a/flang/test/Lower/OpenMP/FIR/array-bounds.f90 +++ b/flang/test/Lower/OpenMP/FIR/array-bounds.f90 @@ -10,14 +10,14 @@ !ALL: %[[C1:.*]] = arith.constant 1 : index !ALL: %[[C2:.*]] = arith.constant 1 : index !ALL: %[[C3:.*]] = arith.constant 4 : index -!ALL: %[[BOUNDS0:.*]] = omp.bounds lower_bound(%[[C2]] : index) upper_bound(%[[C3]] : index) extent(%[[C10]] : index) stride(%[[C1]] : index) start_idx(%[[C1]] : index) -!ALL: %[[MAP0:.*]] = omp.map_info var_ptr(%[[READ]] : !fir.ref<!fir.array<10xi32>>, !fir.array<10xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS0]]) -> !fir.ref<!fir.array<10xi32>> {name = "sp_read(2:5)"} +!ALL: %[[BOUNDS0:.*]] = omp.map.bounds lower_bound(%[[C2]] : index) upper_bound(%[[C3]] : index) extent(%[[C10]] : index) stride(%[[C1]] : index) start_idx(%[[C1]] : index) +!ALL: %[[MAP0:.*]] = omp.map.info var_ptr(%[[READ]] : !fir.ref<!fir.array<10xi32>>, !fir.array<10xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS0]]) -> !fir.ref<!fir.array<10xi32>> {name = "sp_read(2:5)"} !ALL: %[[C4:.*]] = arith.constant 1 : index !ALL: %[[C5:.*]] = arith.constant 1 : index !ALL: %[[C6:.*]] = arith.constant 4 : index -!ALL: %[[BOUNDS1:.*]] = omp.bounds lower_bound(%[[C5]] : index) upper_bound(%[[C6]] : index) extent(%[[C10_0]] : index) stride(%[[C4]] : index) start_idx(%[[C4]] : index) -!ALL: %[[MAP1:.*]] = omp.map_info var_ptr(%[[WRITE]] : !fir.ref<!fir.array<10xi32>>, !fir.array<10xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS1]]) -> !fir.ref<!fir.array<10xi32>> {name = "sp_write(2:5)"} -!ALL: %[[MAP2:.*]] = omp.map_info var_ptr(%[[ITER]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "i"} +!ALL: %[[BOUNDS1:.*]] = omp.map.bounds lower_bound(%[[C5]] : index) upper_bound(%[[C6]] : index) extent(%[[C10_0]] : index) stride(%[[C4]] : index) start_idx(%[[C4]] : index) +!ALL: %[[MAP1:.*]] = omp.map.info var_ptr(%[[WRITE]] : !fir.ref<!fir.array<10xi32>>, !fir.array<10xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS1]]) -> !fir.ref<!fir.array<10xi32>> {name = "sp_write(2:5)"} +!ALL: %[[MAP2:.*]] = omp.map.info var_ptr(%[[ITER]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "i"} !ALL: omp.target map_entries(%[[MAP0]] -> %{{.*}}, %[[MAP1]] -> %{{.*}}, %[[MAP2]] -> %{{.*}} : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>, !fir.ref<i32>) { subroutine read_write_section() @@ -44,11 +44,11 @@ contains !ALL: %[[C4:.*]] = arith.constant 4 : index !ALL: %[[C0_1:.*]] = arith.constant 0 : index !ALL: %[[DIMS1:.*]]:3 = fir.box_dims %arg0, %[[C0_1]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index) -!ALL: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[C3]] : index) upper_bound(%[[C4]] : index) extent(%[[DIMS1]]#1 : index) stride(%[[DIMS0]]#2 : index) start_idx(%[[C0]] : index) {stride_in_bytes = true} +!ALL: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%[[C3]] : index) upper_bound(%[[C4]] : index) extent(%[[DIMS1]]#1 : index) stride(%[[DIMS0]]#2 : index) start_idx(%[[C0]] : index) {stride_in_bytes = true} !ALL: %[[BOXADDRADDR:.*]] = fir.box_offset %0 base_addr : (!fir.ref<!fir.box<!fir.array<?xi32>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> -!ALL: %[[MAP_MEMBER:.*]] = omp.map_info var_ptr(%0 : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.array<?xi32>) var_ptr_ptr(%[[BOXADDRADDR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} -!ALL: %[[MAP:.*]] = omp.map_info var_ptr(%0 : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.box<!fir.array<?xi32>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.array<?xi32>> {name = "arr_read_write(2:5)"} -!ALL: %[[MAP2:.*]] = omp.map_info var_ptr(%[[ALLOCA]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "i"} +!ALL: %[[MAP_MEMBER:.*]] = omp.map.info var_ptr(%0 : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.array<?xi32>) var_ptr_ptr(%[[BOXADDRADDR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} +!ALL: %[[MAP:.*]] = omp.map.info var_ptr(%0 : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.box<!fir.array<?xi32>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.array<?xi32>> {name = "arr_read_write(2:5)"} +!ALL: %[[MAP2:.*]] = omp.map.info var_ptr(%[[ALLOCA]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "i"} !ALL: omp.target map_entries(%[[MAP_MEMBER]] -> %{{.*}}, %[[MAP]] -> %{{.*}}, %[[MAP2]] -> %{{.*}} : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<!fir.array<?xi32>>, !fir.ref<i32>) { subroutine assumed_shape_array(arr_read_write) integer, intent(inout) :: arr_read_write(:) @@ -68,9 +68,9 @@ contains !ALL: %[[C2:.*]] = arith.constant 4 : index !ALL: %[[DIFF:.*]] = arith.subi %[[C2]], %[[C1]] : index !ALL: %[[EXT:.*]] = arith.addi %[[DIFF]], %[[C0]] : index -!ALL: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[C1]] : index) upper_bound(%[[C2]] : index) extent(%[[EXT]] : index) stride(%[[C0]] : index) start_idx(%[[C0]] : index) -!ALL: %[[MAP:.*]] = omp.map_info var_ptr(%[[ARG0]] : !fir.ref<!fir.array<?xi32>>, !fir.array<?xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<?xi32>> {name = "arr_read_write(2:5)"} -!ALL: %[[MAP2:.*]] = omp.map_info var_ptr(%[[ALLOCA]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "i"} +!ALL: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%[[C1]] : index) upper_bound(%[[C2]] : index) extent(%[[EXT]] : index) stride(%[[C0]] : index) start_idx(%[[C0]] : index) +!ALL: %[[MAP:.*]] = omp.map.info var_ptr(%[[ARG0]] : !fir.ref<!fir.array<?xi32>>, !fir.array<?xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<?xi32>> {name = "arr_read_write(2:5)"} +!ALL: %[[MAP2:.*]] = omp.map.info var_ptr(%[[ALLOCA]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "i"} !ALL: omp.target map_entries(%[[MAP]] -> %{{.*}}, %[[MAP2]] -> %{{.*}} : !fir.ref<!fir.array<?xi32>>, !fir.ref<i32>) { subroutine assumed_size_array(arr_read_write) integer, intent(inout) :: arr_read_write(*) diff --git a/flang/test/Lower/OpenMP/FIR/map-component-ref.f90 b/flang/test/Lower/OpenMP/FIR/map-component-ref.f90 index af8c6fa3c5e8..6799941701f4 100644 --- a/flang/test/Lower/OpenMP/FIR/map-component-ref.f90 +++ b/flang/test/Lower/OpenMP/FIR/map-component-ref.f90 @@ -5,8 +5,8 @@ ! CHECK: %[[V1:[0-9]+]] = fir.declare %[[V0]] {uniq_name = "_QFfooEa"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>> ! CHECK: %[[V2:[0-9]+]] = fir.field_index a1, !fir.type<_QFfooTt0{a0:i32,a1:i32}> ! CHECK: %[[V3:[0-9]+]] = fir.coordinate_of %[[V1]], %[[V2]] : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.field) -> !fir.ref<i32> -! CHECK: %[[V4:[0-9]+]] = omp.map_info var_ptr(%[[V3]] : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "a%a1"} -! CHECK: %[[V5:[0-9]+]] = omp.map_info var_ptr(%[[V1]] : !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.type<_QFfooTt0{a0:i32,a1:i32}>) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>> {name = "a"} +! CHECK: %[[V4:[0-9]+]] = omp.map.info var_ptr(%[[V3]] : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "a%a1"} +! CHECK: %[[V5:[0-9]+]] = omp.map.info var_ptr(%[[V1]] : !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.type<_QFfooTt0{a0:i32,a1:i32}>) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>> {name = "a"} ! CHECK: omp.target map_entries(%[[V4]] -> %arg0, %[[V5]] -> %arg1 : !fir.ref<i32>, !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) { ! CHECK: ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>): ! CHECK: %c0_i32 = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/FIR/ordered-threads.f90 b/flang/test/Lower/OpenMP/FIR/ordered-threads.f90 index 2e6afe2125b1..2dea4c857e87 100644 --- a/flang/test/Lower/OpenMP/FIR/ordered-threads.f90 +++ b/flang/test/Lower/OpenMP/FIR/ordered-threads.f90 @@ -10,8 +10,8 @@ subroutine ordered integer :: i integer :: a(20) -!FIRDialect: omp.ordered_region { -!LLVMIRDialect: omp.ordered_region { +!FIRDialect: omp.ordered.region { +!LLVMIRDialect: omp.ordered.region { !LLVMIR: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB0:[0-9]+]]) !LLVMIR-NEXT: call void @__kmpc_ordered(ptr @[[GLOB0]], i32 [[TMP0]]) !$OMP ORDERED @@ -23,8 +23,8 @@ subroutine ordered !LLVMIR: call void @__kmpc_end_ordered(ptr @[[GLOB0]], i32 [[TMP0]]) !$OMP END ORDERED -!FIRDialect: omp.ordered_region { -!LLVMIRDialect: omp.ordered_region { +!FIRDialect: omp.ordered.region { +!LLVMIRDialect: omp.ordered.region { !LLVMIR: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]) !LLVMIR-NEXT: call void @__kmpc_ordered(ptr @[[GLOB1]], i32 [[TMP1]]) !$OMP ORDERED THREADS diff --git a/flang/test/Lower/OpenMP/FIR/parallel-reduction-add-byref.f90 b/flang/test/Lower/OpenMP/FIR/parallel-reduction-add-byref.f90 index ca432662b77c..ea45e716ceae 100644 --- a/flang/test/Lower/OpenMP/FIR/parallel-reduction-add-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/parallel-reduction-add-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp --force-byref-reduction -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -mmlir --force-byref-reduction -o - %s 2>&1 | FileCheck %s -!CHECK-LABEL: omp.reduction.declare +!CHECK-LABEL: omp.declare_reduction !CHECK-SAME: @[[RED_F32_NAME:.*]] : !fir.ref<f32> !CHECK-SAME: init { !CHECK: ^bb0(%{{.*}}: !fir.ref<f32>): @@ -18,7 +18,7 @@ !CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) !CHECK: } -!CHECK-LABEL: omp.reduction.declare +!CHECK-LABEL: omp.declare_reduction !CHECK-SAME: @[[RED_I32_NAME:.*]] : !fir.ref<i32> !CHECK-SAME: init { !CHECK: ^bb0(%{{.*}}: !fir.ref<i32>): diff --git a/flang/test/Lower/OpenMP/FIR/parallel-reduction-add.f90 b/flang/test/Lower/OpenMP/FIR/parallel-reduction-add.f90 index 4b223e822760..3f6d9e647c9b 100644 --- a/flang/test/Lower/OpenMP/FIR/parallel-reduction-add.f90 +++ b/flang/test/Lower/OpenMP/FIR/parallel-reduction-add.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s -!CHECK-LABEL: omp.reduction.declare +!CHECK-LABEL: omp.declare_reduction !CHECK-SAME: @[[RED_F32_NAME:.*]] : f32 init { !CHECK: ^bb0(%{{.*}}: f32): !CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f32 @@ -12,7 +12,7 @@ !CHECK: omp.yield(%[[RES]] : f32) !CHECK: } -!CHECK-LABEL: omp.reduction.declare +!CHECK-LABEL: omp.declare_reduction !CHECK-SAME: @[[RED_I32_NAME:.*]] : i32 init { !CHECK: ^bb0(%{{.*}}: i32): !CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/FIR/target.f90 b/flang/test/Lower/OpenMP/FIR/target.f90 index 06772771647d..821196b83c3b 100644 --- a/flang/test/Lower/OpenMP/FIR/target.f90 +++ b/flang/test/Lower/OpenMP/FIR/target.f90 @@ -7,8 +7,8 @@ !CHECK-LABEL: func.func @_QPomp_target_enter_simple() { subroutine omp_target_enter_simple integer :: a(1024) - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_enter_data map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target enter data map(to: a) end subroutine omp_target_enter_simple @@ -23,14 +23,14 @@ subroutine omp_target_enter_mt integer :: b(1024) integer :: c(1024) integer :: d(1024) - !CHECK: %[[BOUNDS_0:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_0:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_0]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} - !CHECK: %[[BOUNDS_1:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_1:.*]] = omp.map_info var_ptr(%{{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_1]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} - !CHECK: %[[BOUNDS_2:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_2:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%[[BOUNDS_2]]) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} - !CHECK: %[[BOUNDS_3:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_3:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_3]]) -> !fir.ref<!fir.array<1024xi32>> {name = "d"} + !CHECK: %[[BOUNDS_0:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_0:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_0]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS_1:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_1:.*]] = omp.map.info var_ptr(%{{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_1]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} + !CHECK: %[[BOUNDS_2:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_2:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%[[BOUNDS_2]]) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} + !CHECK: %[[BOUNDS_3:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_3:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_3]]) -> !fir.ref<!fir.array<1024xi32>> {name = "d"} !CHECK: omp.target_enter_data map_entries(%[[MAP_0]], %[[MAP_1]], %[[MAP_2]], %[[MAP_3]] : !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) !$omp target enter data map(to: a, b) map(always, alloc: c) map(to: d) end subroutine omp_target_enter_mt @@ -42,8 +42,8 @@ end subroutine omp_target_enter_mt !CHECK-LABEL: func.func @_QPomp_target_enter_nowait() { subroutine omp_target_enter_nowait integer :: a(1024) - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_enter_data nowait map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target enter data map(to: a) nowait end subroutine omp_target_enter_nowait @@ -60,8 +60,8 @@ subroutine omp_target_enter_if !CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1:.*]] : !fir.ref<i32> !CHECK: %[[VAL_4:.*]] = arith.constant 10 : i32 !CHECK: %[[VAL_5:.*]] = arith.cmpi slt, %[[VAL_3]], %[[VAL_4]] : i32 - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_enter_data if(%[[VAL_5]] : i1) map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target enter data if(i<10) map(to: a) end subroutine omp_target_enter_if @@ -74,8 +74,8 @@ end subroutine omp_target_enter_if subroutine omp_target_enter_device integer :: a(1024) !CHECK: %[[VAL_1:.*]] = arith.constant 2 : i32 - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_enter_data device(%[[VAL_1]] : i32) map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target enter data map(to: a) device(2) end subroutine omp_target_enter_device @@ -87,8 +87,8 @@ end subroutine omp_target_enter_device !CHECK-LABEL: func.func @_QPomp_target_exit_simple() { subroutine omp_target_exit_simple integer :: a(1024) - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_exit_data map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target exit data map(from: a) end subroutine omp_target_exit_simple @@ -104,16 +104,16 @@ subroutine omp_target_exit_mt integer :: c(1024) integer :: d(1024) integer :: e(1024) - !CHECK: %[[BOUNDS_0:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_0:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_0]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} - !CHECK: %[[BOUNDS_1:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_1:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_1]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} - !CHECK: %[[BOUNDS_2:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_2:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%[[BOUNDS_2]]) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} - !CHECK: %[[BOUNDS_3:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_3:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(always, delete) capture(ByRef) bounds(%[[BOUNDS_3]]) -> !fir.ref<!fir.array<1024xi32>> {name = "d"} - !CHECK: %[[BOUNDS_4:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_4:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_4]]) -> !fir.ref<!fir.array<1024xi32>> {name = "e"} + !CHECK: %[[BOUNDS_0:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_0:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_0]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS_1:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_1:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_1]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} + !CHECK: %[[BOUNDS_2:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_2:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%[[BOUNDS_2]]) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} + !CHECK: %[[BOUNDS_3:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_3:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(always, delete) capture(ByRef) bounds(%[[BOUNDS_3]]) -> !fir.ref<!fir.array<1024xi32>> {name = "d"} + !CHECK: %[[BOUNDS_4:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_4:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_4]]) -> !fir.ref<!fir.array<1024xi32>> {name = "e"} !CHECK: omp.target_exit_data map_entries(%[[MAP_0]], %[[MAP_1]], %[[MAP_2]], %[[MAP_3]], %[[MAP_4]] : !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) !$omp target exit data map(from: a,b) map(release: c) map(always, delete: d) map(from: e) end subroutine omp_target_exit_mt @@ -127,8 +127,8 @@ subroutine omp_target_exit_device integer :: a(1024) integer :: d !CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1:.*]] : !fir.ref<i32> - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_exit_data device(%[[VAL_2]] : i32) map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target exit data map(from: a) device(d) end subroutine omp_target_exit_device @@ -141,13 +141,13 @@ subroutine omp_target_update_to integer :: a(1024) !CHECK-DAG: %[[A_ALLOC:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_update_toEa"} - !CHECK-DAG: %[[BOUNDS:.*]] = omp.bounds + !CHECK-DAG: %[[BOUNDS:.*]] = omp.map.bounds - !CHECK: %[[TO_MAP:.*]] = omp.map_info var_ptr(%[[A_ALLOC]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) + !CHECK: %[[TO_MAP:.*]] = omp.map.info var_ptr(%[[A_ALLOC]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) !CHECK-SAME: map_clauses(to) capture(ByRef) !CHECK-SAME: bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} - !CHECK: omp.target_update_data + !CHECK: omp.target_update !CHECK-SAME: motion_entries(%[[TO_MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target update to(a) end subroutine omp_target_update_to @@ -160,13 +160,13 @@ subroutine omp_target_update_from integer :: a(1024) !CHECK-DAG: %[[A_ALLOC:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_update_fromEa"} - !CHECK-DAG: %[[BOUNDS:.*]] = omp.bounds + !CHECK-DAG: %[[BOUNDS:.*]] = omp.map.bounds - !CHECK: %[[FROM_MAP:.*]] = omp.map_info var_ptr(%[[A_ALLOC]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) + !CHECK: %[[FROM_MAP:.*]] = omp.map.info var_ptr(%[[A_ALLOC]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) !CHECK-SAME: map_clauses(from) capture(ByRef) !CHECK-SAME: bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} - !CHECK: omp.target_update_data + !CHECK: omp.target_update !CHECK-SAME: motion_entries(%[[FROM_MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target update from(a) end subroutine omp_target_update_from @@ -180,12 +180,12 @@ subroutine omp_target_update_if logical :: i !CHECK-DAG: %[[A_ALLOC:.*]] = fir.alloca - !CHECK-DAG: %[[BOUNDS:.*]] = omp.bounds + !CHECK-DAG: %[[BOUNDS:.*]] = omp.map.bounds !CHECK-DAG: %[[COND:.*]] = fir.convert %{{.*}} : (!fir.logical<4>) -> i1 - !CHECK: %[[TO_MAP:.*]] = omp.map_info + !CHECK: %[[TO_MAP:.*]] = omp.map.info - !CHECK: omp.target_update_data if(%[[COND]] : i1) + !CHECK: omp.target_update if(%[[COND]] : i1) !CHECK-SAME: motion_entries(%[[TO_MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target update to(a) if(i) end subroutine omp_target_update_if @@ -198,12 +198,12 @@ subroutine omp_target_update_device integer :: a(1024) !CHECK-DAG: %[[A_ALLOC:.*]] = fir.alloca - !CHECK-DAG: %[[BOUNDS:.*]] = omp.bounds + !CHECK-DAG: %[[BOUNDS:.*]] = omp.map.bounds !CHECK-DAG: %[[DEVICE:.*]] = arith.constant 1 : i32 - !CHECK: %[[TO_MAP:.*]] = omp.map_info + !CHECK: %[[TO_MAP:.*]] = omp.map.info - !CHECK: omp.target_update_data + !CHECK: omp.target_update !CHECK-SAME: device(%[[DEVICE]] : i32) !CHECK-SAME: motion_entries(%[[TO_MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target update to(a) device(1) @@ -217,11 +217,11 @@ subroutine omp_target_update_nowait integer :: a(1024) !CHECK-DAG: %[[A_ALLOC:.*]] = fir.alloca - !CHECK-DAG: %[[BOUNDS:.*]] = omp.bounds + !CHECK-DAG: %[[BOUNDS:.*]] = omp.map.bounds - !CHECK: %[[TO_MAP:.*]] = omp.map_info + !CHECK: %[[TO_MAP:.*]] = omp.map.info - !CHECK: omp.target_update_data + !CHECK: omp.target_update !CHECK-SAME: nowait !CHECK-SAME: motion_entries(%[[TO_MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target update to(a) nowait @@ -235,8 +235,8 @@ end subroutine omp_target_update_nowait subroutine omp_target_data !CHECK: %[[VAL_0:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_dataEa"} integer :: a(1024) - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%[[VAL_0]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%[[VAL_0]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_data map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) { !$omp target data map(tofrom: a) !CHECK: %[[VAL_1:.*]] = arith.constant 10 : i32 @@ -257,15 +257,15 @@ subroutine omp_target_data_mt integer :: b(1024) !CHECK: %[[VAR_A:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_data_mtEa"} !CHECK: %[[VAR_B:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "b", uniq_name = "_QFomp_target_data_mtEb"} - !CHECK: %[[BOUNDS_A:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_A:.*]] = omp.map_info var_ptr(%[[VAR_A]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS_A]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS_A:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAR_A]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS_A]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_data map_entries(%[[MAP_A]] : !fir.ref<!fir.array<1024xi32>>) { !$omp target data map(a) !CHECK: omp.terminator !$omp end target data !CHECK: } - !CHECK: %[[BOUNDS_B:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_B:.*]] = omp.map_info var_ptr(%[[VAR_B]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(always, from) capture(ByRef) bounds(%[[BOUNDS_B]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} + !CHECK: %[[BOUNDS_B:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_B:.*]] = omp.map.info var_ptr(%[[VAR_B]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(always, from) capture(ByRef) bounds(%[[BOUNDS_B]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} !CHECK: omp.target_data map_entries(%[[MAP_B]] : !fir.ref<!fir.array<1024xi32>>) { !$omp target data map(always, from : b) !CHECK: omp.terminator @@ -281,8 +281,8 @@ end subroutine omp_target_data_mt subroutine omp_target !CHECK: %[[VAL_0:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_targetEa"} integer :: a(1024) - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%[[VAL_0]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%[[VAL_0]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]] : !fir.ref<!fir.array<1024xi32>>) { !CHECK: ^bb0(%[[ARG_0]]: !fir.ref<!fir.array<1024xi32>>): !$omp target map(tofrom: a) @@ -306,7 +306,7 @@ end subroutine omp_target subroutine omp_target_implicit !CHECK: %[[VAL_0:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_implicitEa"} integer :: a(1024) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%[[VAL_0]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%{{.*}}) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%[[VAL_0]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%{{.*}}) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]] : !fir.ref<!fir.array<1024xi32>>) { !CHECK: ^bb0(%[[ARG_0]]: !fir.ref<!fir.array<1024xi32>>): !$omp target @@ -366,12 +366,12 @@ subroutine omp_target_implicit_bounds(n) !CHECK: %[[VAL_13:.*]] = arith.constant 1 : index !CHECK: %[[VAL_14:.*]] = arith.constant 0 : index !CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_6]], %[[VAL_13]] : index - !CHECK: %[[VAL_16:.*]] = omp.bounds lower_bound(%[[VAL_14]] : index) upper_bound(%[[VAL_15]] : index) extent(%[[VAL_6]] : index) stride(%[[VAL_13]] : index) start_idx(%[[VAL_13]] : index) + !CHECK: %[[VAL_16:.*]] = omp.map.bounds lower_bound(%[[VAL_14]] : index) upper_bound(%[[VAL_15]] : index) extent(%[[VAL_6]] : index) stride(%[[VAL_13]] : index) start_idx(%[[VAL_13]] : index) !CHECK: %[[VAL_17:.*]] = arith.constant 0 : index !CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_11]], %[[VAL_13]] : index - !CHECK: %[[VAL_19:.*]] = omp.bounds lower_bound(%[[VAL_17]] : index) upper_bound(%[[VAL_18]] : index) extent(%[[VAL_11]] : index) stride(%[[VAL_13]] : index) start_idx(%[[VAL_13]] : index) - !CHECK: %[[VAL_20:.*]] = omp.map_info var_ptr(%[[VAL_12]] : !fir.ref<!fir.array<?x1024xi32>>, !fir.array<?x1024xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%[[VAL_16]], %[[VAL_19]]) -> !fir.ref<!fir.array<?x1024xi32>> {name = "a"} - !CHECK: %[[VAL_21:.*]] = omp.map_info var_ptr(%[[VAL_COPY]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = ""} + !CHECK: %[[VAL_19:.*]] = omp.map.bounds lower_bound(%[[VAL_17]] : index) upper_bound(%[[VAL_18]] : index) extent(%[[VAL_11]] : index) stride(%[[VAL_13]] : index) start_idx(%[[VAL_13]] : index) + !CHECK: %[[VAL_20:.*]] = omp.map.info var_ptr(%[[VAL_12]] : !fir.ref<!fir.array<?x1024xi32>>, !fir.array<?x1024xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%[[VAL_16]], %[[VAL_19]]) -> !fir.ref<!fir.array<?x1024xi32>> {name = "a"} + !CHECK: %[[VAL_21:.*]] = omp.map.info var_ptr(%[[VAL_COPY]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = ""} !CHECK: omp.target map_entries(%[[VAL_20]] -> %[[VAL_22:.*]], %[[VAL_21]] -> %[[VAL_23:.*]] : !fir.ref<!fir.array<?x1024xi32>>, !fir.ref<i32>) { !CHECK: ^bb0(%[[VAL_22]]: !fir.ref<!fir.array<?x1024xi32>>, %[[VAL_23]]: !fir.ref<i32>): !$omp target @@ -412,7 +412,7 @@ end subroutine omp_target_implicit_bounds subroutine omp_target_thread_limit integer :: a !CHECK: %[[VAL_1:.*]] = arith.constant 64 : i32 - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "a"} + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "a"} !CHECK: omp.target thread_limit(%[[VAL_1]] : i32) map_entries(%[[MAP]] -> %[[ARG_0:.*]] : !fir.ref<i32>) { !CHECK: ^bb0(%[[ARG_0]]: !fir.ref<i32>): !$omp target map(tofrom: a) thread_limit(64) @@ -431,7 +431,7 @@ subroutine omp_target_device_ptr use iso_c_binding, only : c_ptr, c_loc type(c_ptr) :: a integer, target :: b - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(tofrom) capture(ByRef) -> {{.*}} {name = "a"} + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(tofrom) capture(ByRef) -> {{.*}} {name = "a"} !CHECK: omp.target_data map_entries(%[[MAP]]{{.*}} !$omp target data map(tofrom: a) use_device_ptr(a) !CHECK: ^bb0(%[[VAL_1:.*]]: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>): @@ -450,8 +450,8 @@ end subroutine omp_target_device_ptr subroutine omp_target_device_addr integer, pointer :: a !CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box<!fir.ptr<i32>> {bindc_name = "a", uniq_name = "_QFomp_target_device_addrEa"} - !CHECK: %[[MAP_MEMBERS:.*]] = omp.map_info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, i32) var_ptr_ptr({{.*}} : !fir.llvm_ptr<!fir.ref<i32>>) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""} - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBERS]] : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "a"} + !CHECK: %[[MAP_MEMBERS:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, i32) var_ptr_ptr({{.*}} : !fir.llvm_ptr<!fir.ref<i32>>) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""} + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBERS]] : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "a"} !CHECK: omp.target_data map_entries(%[[MAP_MEMBERS]], %[[MAP]] : {{.*}}) use_device_addr(%[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>) { !$omp target data map(tofrom: a) use_device_addr(a) !CHECK: ^bb0(%[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>): @@ -476,9 +476,9 @@ subroutine omp_target_parallel_do !CHECK: %[[C1:.*]] = arith.constant 1 : index !CHECK: %[[C0:.*]] = arith.constant 0 : index !CHECK: %[[SUB:.*]] = arith.subi %[[C1024]], %[[C1]] : index - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[C0]] : index) upper_bound(%[[SUB]] : index) extent(%[[C1024]] : index) stride(%[[C1]] : index) start_idx(%[[C1]] : index) - !CHECK: %[[MAP1:.*]] = omp.map_info var_ptr(%[[VAL_0]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} - !CHECK: %[[MAP2:.*]] = omp.map_info var_ptr(%[[VAL_1]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "i"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%[[C0]] : index) upper_bound(%[[SUB]] : index) extent(%[[C1024]] : index) stride(%[[C1]] : index) start_idx(%[[C1]] : index) + !CHECK: %[[MAP1:.*]] = omp.map.info var_ptr(%[[VAL_0]] : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[MAP2:.*]] = omp.map.info var_ptr(%[[VAL_1]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "i"} !CHECK: omp.target map_entries(%[[MAP1]] -> %[[VAL_2:.*]], %[[MAP2]] -> %[[VAL_3:.*]] : !fir.ref<!fir.array<1024xi32>>, !fir.ref<i32>) { !CHECK: ^bb0(%[[VAL_2]]: !fir.ref<!fir.array<1024xi32>>, %[[VAL_3]]: !fir.ref<i32>): !CHECK-NEXT: omp.parallel diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add-byref.f90 index d4d3452d3e86..e9eadb4bc31a 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add-byref.f90 @@ -2,7 +2,7 @@ ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @add_reduction_f_64_byref : !fir.ref<f64> +! CHECK-LABEL: omp.declare_reduction @add_reduction_f_64_byref : !fir.ref<f64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f64>): ! CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f64 @@ -19,7 +19,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f64>) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_64_byref : !fir.ref<i64> +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_64_byref : !fir.ref<i64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i64>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i64 @@ -36,7 +36,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<i64>) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_f_32_byref : !fir.ref<f32> +! CHECK-LABEL: omp.declare_reduction @add_reduction_f_32_byref : !fir.ref<f32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f32 @@ -53,7 +53,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32_byref : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add.f90 index 5664529416fe..b53dc715e65b 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add.f90 @@ -7,7 +7,7 @@ ! about what constitutes a good test! The CHECK should be ! minimized and named to reflect the test intent. -! CHECK-LABEL: omp.reduction.declare @add_reduction_f_64 : f64 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_f_64 : f64 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f64): ! CHECK: %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f64 ! CHECK: omp.yield(%[[VAL_1]] : f64) @@ -18,7 +18,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f64) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_64 : i64 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_64 : i64 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i64): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i64 ! CHECK: omp.yield(%[[VAL_1]] : i64) @@ -29,7 +29,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : i64) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_f_32 : f32 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_f_32 : f32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f32 ! CHECK: omp.yield(%[[VAL_1]] : f32) @@ -40,7 +40,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand-byref.f90 index 00dfad69248b..92e5e8a0abb5 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s -!CHECK-LABEL: omp.reduction.declare @iand_i_32_byref : !fir.ref<i32> +!CHECK-LABEL: omp.declare_reduction @iand_i_32_byref : !fir.ref<i32> !CHECK-SAME: init { !CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): !CHECK: %[[C0_1:.*]] = arith.constant -1 : i32 diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand.f90 index 9ce1725dbab0..9bc45f9f3a0d 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s -!CHECK: omp.reduction.declare @[[IAND_DECLARE_I:.*]] : i32 init { +!CHECK: omp.declare_reduction @[[IAND_DECLARE_I:.*]] : i32 init { !CHECK: %[[ZERO_VAL_I:.*]] = arith.constant -1 : i32 !CHECK: omp.yield(%[[ZERO_VAL_I]] : i32) !CHECK: combiner diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor-byref.f90 index fb35c405ca1d..c55778903924 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -mmlir --force-byref-reduction -fopenmp %s -o - | FileCheck %s -! CHECK-LABEL: omp.reduction.declare @ieor_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @ieor_i_32_byref : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor.f90 index f6027416246a..9c07d5ee2087 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s -!CHECK: omp.reduction.declare @[[IEOR_DECLARE_I:.*]] : i32 init { +!CHECK: omp.declare_reduction @[[IEOR_DECLARE_I:.*]] : i32 init { !CHECK: %[[ZERO_VAL_I:.*]] = arith.constant 0 : i32 !CHECK: omp.yield(%[[ZERO_VAL_I]] : i32) !CHECK: combiner diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior-byref.f90 index 0365eff3fd81..57f393b9688e 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s -! CHECK-LABEL: omp.reduction.declare @ior_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @ior_i_32_byref : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior.f90 index bc143611abe8..79cc8b2d8922 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s -!CHECK: omp.reduction.declare @[[IOR_DECLARE_I:.*]] : i32 init { +!CHECK: omp.declare_reduction @[[IOR_DECLARE_I:.*]] : i32 init { !CHECK: %[[ZERO_VAL_I:.*]] = arith.constant 0 : i32 !CHECK: omp.yield(%[[ZERO_VAL_I]] : i32) !CHECK: combiner diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-eqv-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-eqv-byref.f90 index 84219b34f964..696ff68b2059 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-eqv-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-eqv-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @eqv_reduction : !fir.ref<!fir.logical<4>> +! CHECK-LABEL: omp.declare_reduction @eqv_reduction : !fir.ref<!fir.logical<4>> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>): ! CHECK: %[[VAL_1:.*]] = arith.constant true diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-eqv.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-eqv.f90 index d5aacd74d8b1..6dcb3952655e 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-eqv.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-eqv.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @eqv_reduction : !fir.logical<4> init { +! CHECK-LABEL: omp.declare_reduction @eqv_reduction : !fir.logical<4> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.logical<4>): ! CHECK: %[[VAL_1:.*]] = arith.constant true ! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i1) -> !fir.logical<4> diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-neqv-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-neqv-byref.f90 index ec4d8500850b..a31abd0def56 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-neqv-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-neqv-byref.f90 @@ -4,7 +4,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @neqv_reduction : !fir.ref<!fir.logical<4>> +! CHECK-LABEL: omp.declare_reduction @neqv_reduction : !fir.ref<!fir.logical<4>> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>): ! CHECK: %[[VAL_1:.*]] = arith.constant false diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-neqv.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-neqv.f90 index 9f44e0e26d40..702c185e25ee 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-neqv.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-neqv.f90 @@ -4,7 +4,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @neqv_reduction : !fir.logical<4> init { +! CHECK-LABEL: omp.declare_reduction @neqv_reduction : !fir.logical<4> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.logical<4>): ! CHECK: %[[VAL_1:.*]] = arith.constant false ! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i1) -> !fir.logical<4> diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 index ddda24a17a83..bc655b5e4295 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp --force-byref-reduction -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -mmlir --force-byref-reduction -o - %s 2>&1 | FileCheck %s -!CHECK: omp.reduction.declare @max_f_32_byref : !fir.ref<f32> +!CHECK: omp.declare_reduction @max_f_32_byref : !fir.ref<f32> !CHECK-SAME: init { !CHECK: %[[MINIMUM_VAL:.*]] = arith.constant -3.40282347E+38 : f32 !CHECK: %[[REF:.*]] = fir.alloca f32 @@ -15,7 +15,7 @@ !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32> !CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) -!CHECK-LABEL: omp.reduction.declare @max_i_32_byref : !fir.ref<i32> +!CHECK-LABEL: omp.declare_reduction @max_i_32_byref : !fir.ref<i32> !CHECK-SAME: init { !CHECK: %[[MINIMUM_VAL:.*]] = arith.constant -2147483648 : i32 !CHECK: fir.store %[[MINIMUM_VAL]] to %[[REF]] : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max.f90 index af79658491b5..996296c2adc2 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s -!CHECK: omp.reduction.declare @[[MAX_DECLARE_F:.*]] : f32 init { +!CHECK: omp.declare_reduction @[[MAX_DECLARE_F:.*]] : f32 init { !CHECK: %[[MINIMUM_VAL_F:.*]] = arith.constant -3.40282347E+38 : f32 !CHECK: omp.yield(%[[MINIMUM_VAL_F]] : f32) !CHECK: combiner @@ -9,7 +9,7 @@ !CHECK: %[[COMB_VAL_F:.*]] = arith.maximumf %[[ARG0_F]], %[[ARG1_F]] {{.*}}: f32 !CHECK: omp.yield(%[[COMB_VAL_F]] : f32) -!CHECK: omp.reduction.declare @[[MAX_DECLARE_I:.*]] : i32 init { +!CHECK: omp.declare_reduction @[[MAX_DECLARE_I:.*]] : i32 init { !CHECK: %[[MINIMUM_VAL_I:.*]] = arith.constant -2147483648 : i32 !CHECK: omp.yield(%[[MINIMUM_VAL_I]] : i32) !CHECK: combiner diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 index d767c54cdbc5..ce928aa131b7 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp --force-byref-reduction -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -mmlir --force-byref-reduction -fopenmp -o - %s 2>&1 | FileCheck %s -!CHECK: omp.reduction.declare @min_f_32_byref : !fir.ref<f32> +!CHECK: omp.declare_reduction @min_f_32_byref : !fir.ref<f32> !CHECK-SAME: init { !CHECK: %[[MAXIMUM_VAL:.*]] = arith.constant 3.40282347E+38 : f32 !CHECK: %[[REF:.*]] = fir.alloca f32 @@ -15,7 +15,7 @@ !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32> !CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) -!CHECK-LABEL: omp.reduction.declare @min_i_32_byref : !fir.ref<i32> +!CHECK-LABEL: omp.declare_reduction @min_i_32_byref : !fir.ref<i32> !CHECK-SAME: init { !CHECK: %[[MAXIMUM_VAL:.*]] = arith.constant 2147483647 : i32 !CHECK: fir.store %[[MAXIMUM_VAL]] to %[[REF]] : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min.f90 index 1095718b4b13..268f51c9dc93 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s -!CHECK: omp.reduction.declare @[[MIN_DECLARE_F:.*]] : f32 init { +!CHECK: omp.declare_reduction @[[MIN_DECLARE_F:.*]] : f32 init { !CHECK: %[[MAXIMUM_VAL_F:.*]] = arith.constant 3.40282347E+38 : f32 !CHECK: omp.yield(%[[MAXIMUM_VAL_F]] : f32) !CHECK: combiner @@ -9,7 +9,7 @@ !CHECK: %[[COMB_VAL_F:.*]] = arith.minimumf %[[ARG0_F]], %[[ARG1_F]] {{.*}}: f32 !CHECK: omp.yield(%[[COMB_VAL_F]] : f32) -!CHECK: omp.reduction.declare @[[MIN_DECLARE_I:.*]] : i32 init { +!CHECK: omp.declare_reduction @[[MIN_DECLARE_I:.*]] : i32 init { !CHECK: %[[MAXIMUM_VAL_I:.*]] = arith.constant 2147483647 : i32 !CHECK: omp.yield(%[[MAXIMUM_VAL_I]] : i32) !CHECK: combiner diff --git a/flang/test/Lower/OpenMP/allocatable-array-bounds.f90 b/flang/test/Lower/OpenMP/allocatable-array-bounds.f90 index adf74efa9b59..aeb56a0427e3 100644 --- a/flang/test/Lower/OpenMP/allocatable-array-bounds.f90 +++ b/flang/test/Lower/OpenMP/allocatable-array-bounds.f90 @@ -21,10 +21,10 @@ !HOST: %[[LOAD_3:.*]] = fir.load %[[DECLARE_1]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> !HOST: %[[CONSTANT_3:.*]] = arith.constant 0 : index !HOST: %[[BOX_3:.*]]:3 = fir.box_dims %[[LOAD_3]], %[[CONSTANT_3]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index) -!HOST: %[[BOUNDS_1:.*]] = omp.bounds lower_bound(%[[LB_1]] : index) upper_bound(%[[UB_1]] : index) extent(%[[BOX_3]]#1 : index) stride(%[[BOX_2]]#2 : index) start_idx(%[[BOX_1]]#0 : index) {stride_in_bytes = true} +!HOST: %[[BOUNDS_1:.*]] = omp.map.bounds lower_bound(%[[LB_1]] : index) upper_bound(%[[UB_1]] : index) extent(%[[BOX_3]]#1 : index) stride(%[[BOX_2]]#2 : index) start_idx(%[[BOX_1]]#0 : index) {stride_in_bytes = true} !HOST: %[[VAR_PTR_PTR:.*]] = fir.box_offset %[[DECLARE_1]]#1 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> -!HOST: %[[MAP_INFO_MEMBER:.*]] = omp.map_info var_ptr(%[[DECLARE_1]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAR_PTR_PTR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS_1]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} -!HOST: %[[MAP_INFO_1:.*]] = omp.map_info var_ptr(%[[DECLARE_1]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_INFO_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {name = "sp_read(2:5)"} +!HOST: %[[MAP_INFO_MEMBER:.*]] = omp.map.info var_ptr(%[[DECLARE_1]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAR_PTR_PTR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS_1]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} +!HOST: %[[MAP_INFO_1:.*]] = omp.map.info var_ptr(%[[DECLARE_1]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_INFO_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {name = "sp_read(2:5)"} !HOST: %[[LOAD_3:.*]] = fir.load %[[DECLARE_2]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> !HOST: %[[LOAD_4:.*]] = fir.load %[[DECLARE_2]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> @@ -39,10 +39,10 @@ !HOST: %[[LOAD_5:.*]] = fir.load %[[DECLARE_2]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> !HOST: %[[CONSTANT_5:.*]] = arith.constant 0 : index !HOST: %[[BOX_5:.*]]:3 = fir.box_dims %[[LOAD_5]], %[[CONSTANT_5]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index) -!HOST: %[[BOUNDS_2:.*]] = omp.bounds lower_bound(%[[LB_2]] : index) upper_bound(%[[UB_2]] : index) extent(%[[BOX_5]]#1 : index) stride(%[[BOX_4]]#2 : index) start_idx(%[[BOX_3]]#0 : index) {stride_in_bytes = true} +!HOST: %[[BOUNDS_2:.*]] = omp.map.bounds lower_bound(%[[LB_2]] : index) upper_bound(%[[UB_2]] : index) extent(%[[BOX_5]]#1 : index) stride(%[[BOX_4]]#2 : index) start_idx(%[[BOX_3]]#0 : index) {stride_in_bytes = true} !HOST: %[[VAR_PTR_PTR:.*]] = fir.box_offset %[[DECLARE_2]]#1 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> -!HOST: %[[MAP_INFO_MEMBER:.*]] = omp.map_info var_ptr(%[[DECLARE_2]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAR_PTR_PTR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS_2]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} -!HOST: %[[MAP_INFO_2:.*]] = omp.map_info var_ptr(%[[DECLARE_2]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_INFO_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {name = "sp_write(2:5)"} +!HOST: %[[MAP_INFO_MEMBER:.*]] = omp.map.info var_ptr(%[[DECLARE_2]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAR_PTR_PTR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS_2]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} +!HOST: %[[MAP_INFO_2:.*]] = omp.map.info var_ptr(%[[DECLARE_2]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_INFO_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {name = "sp_write(2:5)"} subroutine read_write_section() integer, allocatable :: sp_read(:) @@ -78,10 +78,10 @@ module assumed_allocatable_array_routines !HOST: %[[LOAD_3:.*]] = fir.load %[[DECLARE]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> !HOST: %[[CONSTANT_3:.*]] = arith.constant 0 : index !HOST: %[[BOX_3:.*]]:3 = fir.box_dims %[[LOAD_3]], %[[CONSTANT_3]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index) -!HOST: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[LB]] : index) upper_bound(%[[UB]] : index) extent(%[[BOX_3]]#1 : index) stride(%[[BOX_2]]#2 : index) start_idx(%[[BOX_1]]#0 : index) {stride_in_bytes = true} +!HOST: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%[[LB]] : index) upper_bound(%[[UB]] : index) extent(%[[BOX_3]]#1 : index) stride(%[[BOX_2]]#2 : index) start_idx(%[[BOX_1]]#0 : index) {stride_in_bytes = true} !HOST: %[[VAR_PTR_PTR:.*]] = fir.box_offset %[[DECLARE]]#1 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> -!HOST: %[[MAP_INFO_MEMBER:.*]] = omp.map_info var_ptr(%[[DECLARE]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAR_PTR_PTR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} -!HOST: %[[MAP_INFO:.*]] = omp.map_info var_ptr(%[[DECLARE]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_INFO_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {name = "arr_read_write(2:5)"} +!HOST: %[[MAP_INFO_MEMBER:.*]] = omp.map.info var_ptr(%[[DECLARE]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAR_PTR_PTR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} +!HOST: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%[[DECLARE]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_INFO_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {name = "arr_read_write(2:5)"} subroutine assumed_shape_array(arr_read_write) integer, allocatable, intent(inout) :: arr_read_write(:) diff --git a/flang/test/Lower/OpenMP/allocatable-map.f90 b/flang/test/Lower/OpenMP/allocatable-map.f90 index ddc20b582b26..396d45373b84 100644 --- a/flang/test/Lower/OpenMP/allocatable-map.f90 +++ b/flang/test/Lower/OpenMP/allocatable-map.f90 @@ -2,8 +2,8 @@ !HLFIRDIALECT: %[[POINTER:.*]]:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFpointer_routineEpoint"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>) !HLFIRDIALECT: %[[BOX_OFF:.*]] = fir.box_offset %[[POINTER]]#1 base_addr : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> !fir.llvm_ptr<!fir.ref<i32>> -!HLFIRDIALECT: %[[POINTER_MAP_MEMBER:.*]] = omp.map_info var_ptr(%[[POINTER]]#1 : !fir.ref<!fir.box<!fir.ptr<i32>>>, i32) var_ptr_ptr(%[[BOX_OFF]] : !fir.llvm_ptr<!fir.ref<i32>>) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""} -!HLFIRDIALECT: %[[POINTER_MAP:.*]] = omp.map_info var_ptr(%[[POINTER]]#1 : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(implicit, tofrom) capture(ByRef) members(%[[POINTER_MAP_MEMBER]] : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "point"} +!HLFIRDIALECT: %[[POINTER_MAP_MEMBER:.*]] = omp.map.info var_ptr(%[[POINTER]]#1 : !fir.ref<!fir.box<!fir.ptr<i32>>>, i32) var_ptr_ptr(%[[BOX_OFF]] : !fir.llvm_ptr<!fir.ref<i32>>) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""} +!HLFIRDIALECT: %[[POINTER_MAP:.*]] = omp.map.info var_ptr(%[[POINTER]]#1 : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(implicit, tofrom) capture(ByRef) members(%[[POINTER_MAP_MEMBER]] : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "point"} !HLFIRDIALECT: omp.target map_entries({{.*}}, %[[POINTER_MAP_MEMBER]] -> {{.*}}, %[[POINTER_MAP]] -> {{.*}} : {{.*}}, !fir.llvm_ptr<!fir.ref<i32>>, !fir.ref<!fir.box<!fir.ptr<i32>>>) { subroutine pointer_routine() integer, pointer :: point diff --git a/flang/test/Lower/OpenMP/array-bounds.f90 b/flang/test/Lower/OpenMP/array-bounds.f90 index 7d76ff4b106a..2c8a8999a2cc 100644 --- a/flang/test/Lower/OpenMP/array-bounds.f90 +++ b/flang/test/Lower/OpenMP/array-bounds.f90 @@ -14,13 +14,13 @@ !HOST: %[[C1:.*]] = arith.constant 1 : index !HOST: %[[C2:.*]] = arith.constant 1 : index !HOST: %[[C3:.*]] = arith.constant 4 : index -!HOST: %[[BOUNDS0:.*]] = omp.bounds lower_bound(%[[C2]] : index) upper_bound(%[[C3]] : index) extent(%[[C10]] : index) stride(%[[C1]] : index) start_idx(%[[C1]] : index) -!HOST: %[[MAP0:.*]] = omp.map_info var_ptr(%[[READ_DECL]]#0 : !fir.ref<!fir.array<10xi32>>, !fir.array<10xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS0]]) -> !fir.ref<!fir.array<10xi32>> {name = "sp_read(2:5)"} +!HOST: %[[BOUNDS0:.*]] = omp.map.bounds lower_bound(%[[C2]] : index) upper_bound(%[[C3]] : index) extent(%[[C10]] : index) stride(%[[C1]] : index) start_idx(%[[C1]] : index) +!HOST: %[[MAP0:.*]] = omp.map.info var_ptr(%[[READ_DECL]]#0 : !fir.ref<!fir.array<10xi32>>, !fir.array<10xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS0]]) -> !fir.ref<!fir.array<10xi32>> {name = "sp_read(2:5)"} !HOST: %[[C4:.*]] = arith.constant 1 : index !HOST: %[[C5:.*]] = arith.constant 1 : index !HOST: %[[C6:.*]] = arith.constant 4 : index -!HOST: %[[BOUNDS1:.*]] = omp.bounds lower_bound(%[[C5]] : index) upper_bound(%[[C6]] : index) extent(%[[C10_0]] : index) stride(%[[C4]] : index) start_idx(%[[C4]] : index) -!HOST: %[[MAP1:.*]] = omp.map_info var_ptr(%[[WRITE_DECL]]#0 : !fir.ref<!fir.array<10xi32>>, !fir.array<10xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS1]]) -> !fir.ref<!fir.array<10xi32>> {name = "sp_write(2:5)"} +!HOST: %[[BOUNDS1:.*]] = omp.map.bounds lower_bound(%[[C5]] : index) upper_bound(%[[C6]] : index) extent(%[[C10_0]] : index) stride(%[[C4]] : index) start_idx(%[[C4]] : index) +!HOST: %[[MAP1:.*]] = omp.map.info var_ptr(%[[WRITE_DECL]]#0 : !fir.ref<!fir.array<10xi32>>, !fir.array<10xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS1]]) -> !fir.ref<!fir.array<10xi32>> {name = "sp_write(2:5)"} !HOST: omp.target map_entries(%[[MAP0]] -> %{{.*}}, %[[MAP1]] -> %{{.*}}, {{.*}} -> {{.*}} : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>, !fir.ref<i32>) { subroutine read_write_section() @@ -49,10 +49,10 @@ module assumed_array_routines !HOST: %[[C4:.*]] = arith.constant 4 : index !HOST: %[[C0_1:.*]] = arith.constant 0 : index !HOST: %[[DIMS1:.*]]:3 = fir.box_dims %[[ARG0_DECL]]#1, %[[C0_1]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index) -!HOST: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[C3]] : index) upper_bound(%[[C4]] : index) extent(%[[DIMS1]]#1 : index) stride(%[[DIMS0]]#2 : index) start_idx(%[[C0]] : index) {stride_in_bytes = true} +!HOST: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%[[C3]] : index) upper_bound(%[[C4]] : index) extent(%[[DIMS1]]#1 : index) stride(%[[DIMS0]]#2 : index) start_idx(%[[C0]] : index) {stride_in_bytes = true} !HOST: %[[VAR_PTR_PTR:.*]] = fir.box_offset %0 base_addr : (!fir.ref<!fir.box<!fir.array<?xi32>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> -!HOST: %[[MAP_INFO_MEMBER:.*]] = omp.map_info var_ptr(%[[INTERMEDIATE_ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAR_PTR_PTR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} -!HOST: %[[MAP:.*]] = omp.map_info var_ptr(%[[INTERMEDIATE_ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.box<!fir.array<?xi32>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_INFO_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.array<?xi32>> {name = "arr_read_write(2:5)"} +!HOST: %[[MAP_INFO_MEMBER:.*]] = omp.map.info var_ptr(%[[INTERMEDIATE_ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAR_PTR_PTR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} +!HOST: %[[MAP:.*]] = omp.map.info var_ptr(%[[INTERMEDIATE_ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.box<!fir.array<?xi32>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_INFO_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.array<?xi32>> {name = "arr_read_write(2:5)"} !HOST: omp.target map_entries(%[[MAP_INFO_MEMBER]] -> %{{.*}}, %[[MAP]] -> %{{.*}}, {{.*}} -> {{.*}} : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<!fir.array<?xi32>>, !fir.ref<i32>) { subroutine assumed_shape_array(arr_read_write) integer, intent(inout) :: arr_read_write(:) @@ -74,10 +74,10 @@ module assumed_array_routines !HOST: %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0_DECL]]#0, %c0{{.*}} : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index) !HOST: %[[C4_1:.*]] = arith.subi %c4, %c1{{.*}} : index !HOST: %[[EXT:.*]] = arith.addi %[[C4_1]], %c1{{.*}} : index -!HOST: %[[BOUNDS:.*]] = omp.bounds lower_bound(%c1{{.*}} : index) upper_bound(%c4{{.*}} : index) extent(%[[EXT]] : index) stride(%[[DIMS0]]#2 : index) start_idx(%c1{{.*}} : index) {stride_in_bytes = true} +!HOST: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%c1{{.*}} : index) upper_bound(%c4{{.*}} : index) extent(%[[EXT]] : index) stride(%[[DIMS0]]#2 : index) start_idx(%c1{{.*}} : index) {stride_in_bytes = true} !HOST: %[[VAR_PTR_PTR:.*]] = fir.box_offset %[[INTERMEDIATE_ALLOCA]] base_addr : (!fir.ref<!fir.box<!fir.array<?xi32>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> -!HOST: %[[MAP_INFO_MEMBER:.*]] = omp.map_info var_ptr(%[[INTERMEDIATE_ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAR_PTR_PTR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} -!HOST: %[[MAP:.*]] = omp.map_info var_ptr(%[[INTERMEDIATE_ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.box<!fir.array<?xi32>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_INFO_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.array<?xi32>> {name = "arr_read_write(2:5)"} +!HOST: %[[MAP_INFO_MEMBER:.*]] = omp.map.info var_ptr(%[[INTERMEDIATE_ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.array<?xi32>) var_ptr_ptr(%[[VAR_PTR_PTR]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} +!HOST: %[[MAP:.*]] = omp.map.info var_ptr(%[[INTERMEDIATE_ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.box<!fir.array<?xi32>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_INFO_MEMBER]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.array<?xi32>> {name = "arr_read_write(2:5)"} !HOST: omp.target map_entries(%[[MAP_INFO_MEMBER]] -> %{{.*}}, %[[MAP]] -> %{{.*}}, {{.*}} -> {{.*}} : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<!fir.array<?xi32>>, !fir.ref<i32>) { subroutine assumed_size_array(arr_read_write) integer, intent(inout) :: arr_read_write(*) diff --git a/flang/test/Lower/OpenMP/declare-target-link-tarop-cap.f90 b/flang/test/Lower/OpenMP/declare-target-link-tarop-cap.f90 index 7cd059716157..3459be87fea2 100644 --- a/flang/test/Lower/OpenMP/declare-target-link-tarop-cap.f90 +++ b/flang/test/Lower/OpenMP/declare-target-link-tarop-cap.f90 @@ -20,13 +20,13 @@ program test_link integer, pointer :: test_ptr2 !$omp declare target link(test_ptr2) - !CHECK-DAG: {{%.*}} = omp.map_info var_ptr({{%.*}} : !fir.ref<i32>, i32) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<i32> {name = "test_int"} + !CHECK-DAG: {{%.*}} = omp.map.info var_ptr({{%.*}} : !fir.ref<i32>, i32) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<i32> {name = "test_int"} !$omp target test_int = test_int + 1 !$omp end target - !CHECK-DAG: {{%.*}} = omp.map_info var_ptr({{%.*}} : !fir.ref<!fir.array<3xi32>>, !fir.array<3xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds({{%.*}}) -> !fir.ref<!fir.array<3xi32>> {name = "test_array_1d"} + !CHECK-DAG: {{%.*}} = omp.map.info var_ptr({{%.*}} : !fir.ref<!fir.array<3xi32>>, !fir.array<3xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds({{%.*}}) -> !fir.ref<!fir.array<3xi32>> {name = "test_array_1d"} !$omp target do i = 1,3 test_array_1d(i) = i * 2 @@ -35,18 +35,18 @@ program test_link allocate(test_ptr1) test_ptr1 = 1 - !CHECK-DAG: {{%.*}} = omp.map_info var_ptr({{%.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(implicit, tofrom) capture(ByRef) members({{%.*}} : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "test_ptr1"} + !CHECK-DAG: {{%.*}} = omp.map.info var_ptr({{%.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(implicit, tofrom) capture(ByRef) members({{%.*}} : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "test_ptr1"} !$omp target test_ptr1 = test_ptr1 + 1 !$omp end target - !CHECK-DAG: {{%.*}} = omp.map_info var_ptr({{%.*}} : !fir.ref<i32>, i32) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<i32> {name = "test_target"} + !CHECK-DAG: {{%.*}} = omp.map.info var_ptr({{%.*}} : !fir.ref<i32>, i32) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<i32> {name = "test_target"} !$omp target test_target = test_target + 1 !$omp end target - !CHECK-DAG: {{%.*}} = omp.map_info var_ptr({{%.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(implicit, tofrom) capture(ByRef) members({{%.*}} : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "test_ptr2"} + !CHECK-DAG: {{%.*}} = omp.map.info var_ptr({{%.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(implicit, tofrom) capture(ByRef) members({{%.*}} : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "test_ptr2"} test_ptr2 => test_target !$omp target test_ptr2 = test_ptr2 + 1 diff --git a/flang/test/Lower/OpenMP/delayed-privatization-reduction-byref.f90 b/flang/test/Lower/OpenMP/delayed-privatization-reduction-byref.f90 index 067a71340b8d..49d1142ea4b6 100644 --- a/flang/test/Lower/OpenMP/delayed-privatization-reduction-byref.f90 +++ b/flang/test/Lower/OpenMP/delayed-privatization-reduction-byref.f90 @@ -21,7 +21,7 @@ end subroutine ! CHECK-LABEL: omp.private {type = private} ! CHECK-SAME: @[[PRIVATIZER_SYM:.*]] : !fir.ref<i32> alloc { -! CHECK-LABEL: omp.reduction.declare +! CHECK-LABEL: omp.declare_reduction ! CHECK-SAME: @[[REDUCTION_SYM:.*]] : !fir.ref<i32> init ! CHECK-LABEL: _QPred_and_delayed_private diff --git a/flang/test/Lower/OpenMP/delayed-privatization-reduction.f90 b/flang/test/Lower/OpenMP/delayed-privatization-reduction.f90 index a7eeb1facead..d814b2b0ff0f 100644 --- a/flang/test/Lower/OpenMP/delayed-privatization-reduction.f90 +++ b/flang/test/Lower/OpenMP/delayed-privatization-reduction.f90 @@ -24,7 +24,7 @@ end subroutine ! CHECK-LABEL: omp.private {type = private} ! CHECK-SAME: @[[PRIVATIZER_SYM:.*]] : !fir.ref<i32> alloc { -! CHECK-LABEL: omp.reduction.declare +! CHECK-LABEL: omp.declare_reduction ! CHECK-SAME: @[[REDUCTION_SYM:.*]] : i32 init ! CHECK-LABEL: _QPred_and_delayed_private diff --git a/flang/test/Lower/OpenMP/map-component-ref.f90 b/flang/test/Lower/OpenMP/map-component-ref.f90 index 1ed37e731580..435bc8e6bd36 100644 --- a/flang/test/Lower/OpenMP/map-component-ref.f90 +++ b/flang/test/Lower/OpenMP/map-component-ref.f90 @@ -4,8 +4,8 @@ ! CHECK: %[[V0:[0-9]+]] = fir.alloca !fir.type<_QFfooTt0{a0:i32,a1:i32}> {bindc_name = "a", uniq_name = "_QFfooEa"} ! CHECK: %[[V1:[0-9]+]]:2 = hlfir.declare %[[V0]] {uniq_name = "_QFfooEa"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) ! CHECK: %[[V2:[0-9]+]] = hlfir.designate %[[V1]]#0{"a1"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> !fir.ref<i32> -! CHECK: %[[V3:[0-9]+]] = omp.map_info var_ptr(%[[V2]] : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "a%a1"} -! CHECK: %[[V4:[0-9]+]] = omp.map_info var_ptr(%[[V1]]#1 : !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.type<_QFfooTt0{a0:i32,a1:i32}>) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>> {name = "a"} +! CHECK: %[[V3:[0-9]+]] = omp.map.info var_ptr(%[[V2]] : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "a%a1"} +! CHECK: %[[V4:[0-9]+]] = omp.map.info var_ptr(%[[V1]]#1 : !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.type<_QFfooTt0{a0:i32,a1:i32}>) map_clauses(implicit, tofrom) capture(ByRef) -> !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>> {name = "a"} ! CHECK: omp.target map_entries(%[[V3]] -> %arg0, %[[V4]] -> %arg1 : !fir.ref<i32>, !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) { ! CHECK: ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>): ! CHECK: %[[V5:[0-9]+]]:2 = hlfir.declare %arg1 {uniq_name = "_QFfooEa"} : (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) -> (!fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>, !fir.ref<!fir.type<_QFfooTt0{a0:i32,a1:i32}>>) diff --git a/flang/test/Lower/OpenMP/ordered-threads.f90 b/flang/test/Lower/OpenMP/ordered-threads.f90 index a3f99129eba7..81f5c419b236 100644 --- a/flang/test/Lower/OpenMP/ordered-threads.f90 +++ b/flang/test/Lower/OpenMP/ordered-threads.f90 @@ -8,14 +8,14 @@ subroutine ordered integer :: i integer :: a(20) -!CHECK: omp.ordered_region { +!CHECK: omp.ordered.region { !$OMP ORDERED a(i) = a(i-1) + 1 !CHECK: omp.terminator !CHECK-NEXT: } !$OMP END ORDERED -!CHECK: omp.ordered_region { +!CHECK: omp.ordered.region { !$OMP ORDERED THREADS a(i) = a(i-1) + 1 !CHECK: omp.terminator diff --git a/flang/test/Lower/OpenMP/parallel-reduction-add-byref.f90 b/flang/test/Lower/OpenMP/parallel-reduction-add-byref.f90 index c4a4695b8d9f..2a1d26407b27 100644 --- a/flang/test/Lower/OpenMP/parallel-reduction-add-byref.f90 +++ b/flang/test/Lower/OpenMP/parallel-reduction-add-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-hlfir --force-byref-reduction -fopenmp -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --force-byref-reduction -o - %s 2>&1 | FileCheck %s -!CHECK-LABEL: omp.reduction.declare +!CHECK-LABEL: omp.declare_reduction !CHECK-SAME: @[[RED_F32_NAME:.*]] : !fir.ref<f32> !CHECK-SAME: init { !CHECK: ^bb0(%{{.*}}: !fir.ref<f32>): @@ -18,7 +18,7 @@ !CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) !CHECK: } -!CHECK-LABEL: omp.reduction.declare +!CHECK-LABEL: omp.declare_reduction !CHECK-SAME: @[[RED_I32_NAME:.*]] : !fir.ref<i32> !CHECK-SAME: init { !CHECK: ^bb0(%{{.*}}: !fir.ref<i32>): diff --git a/flang/test/Lower/OpenMP/parallel-reduction-add.f90 b/flang/test/Lower/OpenMP/parallel-reduction-add.f90 index 8f3ac3dc357a..213fc71cc349 100644 --- a/flang/test/Lower/OpenMP/parallel-reduction-add.f90 +++ b/flang/test/Lower/OpenMP/parallel-reduction-add.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s -!CHECK-LABEL: omp.reduction.declare +!CHECK-LABEL: omp.declare_reduction !CHECK-SAME: @[[RED_F32_NAME:.*]] : f32 init { !CHECK: ^bb0(%{{.*}}: f32): !CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f32 @@ -12,7 +12,7 @@ !CHECK: omp.yield(%[[RES]] : f32) !CHECK: } -!CHECK-LABEL: omp.reduction.declare +!CHECK-LABEL: omp.declare_reduction !CHECK-SAME: @[[RED_I32_NAME:.*]] : i32 init { !CHECK: ^bb0(%{{.*}}: i32): !CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/parallel-reduction-array.f90 b/flang/test/Lower/OpenMP/parallel-reduction-array.f90 index 19c458631085..359dab35e8a6 100644 --- a/flang/test/Lower/OpenMP/parallel-reduction-array.f90 +++ b/flang/test/Lower/OpenMP/parallel-reduction-array.f90 @@ -13,7 +13,7 @@ i(3) = 3 print *,i end program -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>): ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<3xi32> {bindc_name = ".tmp"} ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/parallel-reduction-array2.f90 b/flang/test/Lower/OpenMP/parallel-reduction-array2.f90 index 04c4045a6729..5a31be8d206b 100644 --- a/flang/test/Lower/OpenMP/parallel-reduction-array2.f90 +++ b/flang/test/Lower/OpenMP/parallel-reduction-array2.f90 @@ -13,7 +13,7 @@ i(3) = i(3) + 3 print *,i end program -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>): ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<3xi32> {bindc_name = ".tmp"} ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/parallel-reduction-byref.f90 b/flang/test/Lower/OpenMP/parallel-reduction-byref.f90 index a7c77c52674e..fdcdf0c0b8d9 100644 --- a/flang/test/Lower/OpenMP/parallel-reduction-byref.f90 +++ b/flang/test/Lower/OpenMP/parallel-reduction-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp --force-byref-reduction -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --force-byref-reduction -o - %s 2>&1 | FileCheck %s -!CHECK: omp.reduction.declare @[[REDUCTION_DECLARE:[_a-z0-9]+]] : !fir.ref<i32> +!CHECK: omp.declare_reduction @[[REDUCTION_DECLARE:[_a-z0-9]+]] : !fir.ref<i32> !CHECK-SAME: init { !CHECK: ^bb0(%{{.*}}: !fir.ref<i32>): !CHECK: %[[I0:[_a-z0-9]+]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/parallel-reduction-rename.f90 b/flang/test/Lower/OpenMP/parallel-reduction-rename.f90 index 86db2ffbcfeb..7845f808e6c5 100644 --- a/flang/test/Lower/OpenMP/parallel-reduction-rename.f90 +++ b/flang/test/Lower/OpenMP/parallel-reduction-rename.f90 @@ -14,7 +14,7 @@ end program main ! test that we understood that this should be a max reduction -! CHECK-LABEL: omp.reduction.declare @max_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @max_i_32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant -2147483648 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) diff --git a/flang/test/Lower/OpenMP/parallel-reduction.f90 b/flang/test/Lower/OpenMP/parallel-reduction.f90 index a07d118b0ba1..612549fb32de 100644 --- a/flang/test/Lower/OpenMP/parallel-reduction.f90 +++ b/flang/test/Lower/OpenMP/parallel-reduction.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s -!CHECK: omp.reduction.declare @[[REDUCTION_DECLARE:[_a-z0-9]+]] : i32 init { +!CHECK: omp.declare_reduction @[[REDUCTION_DECLARE:[_a-z0-9]+]] : i32 init { !CHECK: ^bb0(%{{.*}}: i32): !CHECK: %[[I0:[_a-z0-9]+]] = arith.constant 0 : i32 !CHECK: omp.yield(%[[I0]] : i32) diff --git a/flang/test/Lower/OpenMP/target.f90 b/flang/test/Lower/OpenMP/target.f90 index 030533e1a045..6f72b5a34d06 100644 --- a/flang/test/Lower/OpenMP/target.f90 +++ b/flang/test/Lower/OpenMP/target.f90 @@ -7,8 +7,8 @@ !CHECK-LABEL: func.func @_QPomp_target_enter_simple() { subroutine omp_target_enter_simple integer :: a(1024) - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_enter_data map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target enter data map(to: a) return @@ -27,8 +27,8 @@ subroutine omp_target_enter_depend !$omp task depend(out: a) call foo(a) !$omp end task - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_enter_data map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) depend(taskdependin -> %[[A]]#1 : !fir.ref<!fir.array<1024xi32>>) !$omp target enter data map(to: a) depend(in: a) return @@ -44,14 +44,14 @@ subroutine omp_target_enter_mt integer :: b(1024) integer :: c(1024) integer :: d(1024) - !CHECK: %[[BOUNDS_0:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_0:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_0]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} - !CHECK: %[[BOUNDS_1:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_1:.*]] = omp.map_info var_ptr(%{{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_1]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} - !CHECK: %[[BOUNDS_2:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_2:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%[[BOUNDS_2]]) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} - !CHECK: %[[BOUNDS_3:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_3:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_3]]) -> !fir.ref<!fir.array<1024xi32>> {name = "d"} + !CHECK: %[[BOUNDS_0:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_0:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_0]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS_1:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_1:.*]] = omp.map.info var_ptr(%{{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_1]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} + !CHECK: %[[BOUNDS_2:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_2:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%[[BOUNDS_2]]) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} + !CHECK: %[[BOUNDS_3:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_3:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS_3]]) -> !fir.ref<!fir.array<1024xi32>> {name = "d"} !CHECK: omp.target_enter_data map_entries(%[[MAP_0]], %[[MAP_1]], %[[MAP_2]], %[[MAP_3]] : !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) !$omp target enter data map(to: a, b) map(always, alloc: c) map(to: d) end subroutine omp_target_enter_mt @@ -63,8 +63,8 @@ end subroutine omp_target_enter_mt !CHECK-LABEL: func.func @_QPomp_target_enter_nowait() { subroutine omp_target_enter_nowait integer :: a(1024) - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_enter_data nowait map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target enter data map(to: a) nowait end subroutine omp_target_enter_nowait @@ -81,8 +81,8 @@ subroutine omp_target_enter_if !CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1:.*]] : !fir.ref<i32> !CHECK: %[[VAL_4:.*]] = arith.constant 10 : i32 !CHECK: %[[VAL_5:.*]] = arith.cmpi slt, %[[VAL_3]], %[[VAL_4]] : i32 - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_enter_data if(%[[VAL_5]] : i1) map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target enter data if(i<10) map(to: a) end subroutine omp_target_enter_if @@ -95,8 +95,8 @@ end subroutine omp_target_enter_if subroutine omp_target_enter_device integer :: a(1024) !CHECK: %[[VAL_1:.*]] = arith.constant 2 : i32 - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_enter_data device(%[[VAL_1]] : i32) map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target enter data map(to: a) device(2) end subroutine omp_target_enter_device @@ -108,8 +108,8 @@ end subroutine omp_target_enter_device !CHECK-LABEL: func.func @_QPomp_target_exit_simple() { subroutine omp_target_exit_simple integer :: a(1024) - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_exit_data map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target exit data map(from: a) end subroutine omp_target_exit_simple @@ -125,16 +125,16 @@ subroutine omp_target_exit_mt integer :: c(1024) integer :: d(1024) integer :: e(1024) - !CHECK: %[[BOUNDS_0:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_0:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_0]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} - !CHECK: %[[BOUNDS_1:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_1:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_1]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} - !CHECK: %[[BOUNDS_2:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_2:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%[[BOUNDS_2]]) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} - !CHECK: %[[BOUNDS_3:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_3:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(always, delete) capture(ByRef) bounds(%[[BOUNDS_3]]) -> !fir.ref<!fir.array<1024xi32>> {name = "d"} - !CHECK: %[[BOUNDS_4:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_4:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_4]]) -> !fir.ref<!fir.array<1024xi32>> {name = "e"} + !CHECK: %[[BOUNDS_0:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_0:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_0]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS_1:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_1:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_1]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} + !CHECK: %[[BOUNDS_2:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_2:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%[[BOUNDS_2]]) -> !fir.ref<!fir.array<1024xi32>> {name = "c"} + !CHECK: %[[BOUNDS_3:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_3:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(always, delete) capture(ByRef) bounds(%[[BOUNDS_3]]) -> !fir.ref<!fir.array<1024xi32>> {name = "d"} + !CHECK: %[[BOUNDS_4:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_4:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS_4]]) -> !fir.ref<!fir.array<1024xi32>> {name = "e"} !CHECK: omp.target_exit_data map_entries(%[[MAP_0]], %[[MAP_1]], %[[MAP_2]], %[[MAP_3]], %[[MAP_4]] : !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) !$omp target exit data map(from: a,b) map(release: c) map(always, delete: d) map(from: e) end subroutine omp_target_exit_mt @@ -148,8 +148,8 @@ subroutine omp_target_exit_device integer :: a(1024) integer :: d !CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1:.*]] : !fir.ref<i32> - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_exit_data device(%[[VAL_2]] : i32) map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target exit data map(from: a) device(d) end subroutine omp_target_exit_device @@ -166,8 +166,8 @@ subroutine omp_target_exit_depend !$omp task depend(out: a) call foo(a) !$omp end task - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_exit_data map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) depend(taskdependout -> %[[A]]#1 : !fir.ref<!fir.array<1024xi32>>) !$omp target exit data map(from: a) depend(out: a) end subroutine omp_target_exit_depend @@ -187,9 +187,9 @@ subroutine omp_target_update_depend call foo(a) !$omp end task - !CHECK: %[[BOUNDS:.*]] = omp.bounds - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%[[A]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} - !CHECK: omp.target_update_data motion_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) depend(taskdependin -> %[[A]]#1 : !fir.ref<!fir.array<1024xi32>>) + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%[[A]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(to) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: omp.target_update motion_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) depend(taskdependin -> %[[A]]#1 : !fir.ref<!fir.array<1024xi32>>) !$omp target update to(a) depend(in:a) end subroutine omp_target_update_depend @@ -202,13 +202,13 @@ subroutine omp_target_update_to integer :: a(1024) !CHECK-DAG: %[[A_DECL:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) - !CHECK-DAG: %[[BOUNDS:.*]] = omp.bounds + !CHECK-DAG: %[[BOUNDS:.*]] = omp.map.bounds - !CHECK: %[[TO_MAP:.*]] = omp.map_info var_ptr(%[[A_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) + !CHECK: %[[TO_MAP:.*]] = omp.map.info var_ptr(%[[A_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) !CHECK-SAME: map_clauses(to) capture(ByRef) !CHECK-SAME: bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} - !CHECK: omp.target_update_data motion_entries(%[[TO_MAP]] : !fir.ref<!fir.array<1024xi32>>) + !CHECK: omp.target_update motion_entries(%[[TO_MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target update to(a) end subroutine omp_target_update_to @@ -221,13 +221,13 @@ subroutine omp_target_update_from integer :: a(1024) !CHECK-DAG: %[[A_DECL:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) - !CHECK-DAG: %[[BOUNDS:.*]] = omp.bounds + !CHECK-DAG: %[[BOUNDS:.*]] = omp.map.bounds - !CHECK: %[[FROM_MAP:.*]] = omp.map_info var_ptr(%[[A_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) + !CHECK: %[[FROM_MAP:.*]] = omp.map.info var_ptr(%[[A_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) !CHECK-SAME: map_clauses(from) capture(ByRef) !CHECK-SAME: bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} - !CHECK: omp.target_update_data motion_entries(%[[FROM_MAP]] : !fir.ref<!fir.array<1024xi32>>) + !CHECK: omp.target_update motion_entries(%[[FROM_MAP]] : !fir.ref<!fir.array<1024xi32>>) !$omp target update from(a) end subroutine omp_target_update_from @@ -241,10 +241,10 @@ subroutine omp_target_update_if logical :: i !CHECK-DAG: %[[A_DECL:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) - !CHECK-DAG: %[[BOUNDS:.*]] = omp.bounds + !CHECK-DAG: %[[BOUNDS:.*]] = omp.map.bounds !CHECK-DAG: %[[COND:.*]] = fir.convert %{{.*}} : (!fir.logical<4>) -> i1 - !CHECK: omp.target_update_data if(%[[COND]] : i1) motion_entries + !CHECK: omp.target_update if(%[[COND]] : i1) motion_entries !$omp target update from(a) if(i) end subroutine omp_target_update_if @@ -258,10 +258,10 @@ subroutine omp_target_update_device logical :: i !CHECK-DAG: %[[A_DECL:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) - !CHECK-DAG: %[[BOUNDS:.*]] = omp.bounds + !CHECK-DAG: %[[BOUNDS:.*]] = omp.map.bounds !CHECK-DAG: %[[DEVICE:.*]] = arith.constant 1 : i32 - !CHECK: omp.target_update_data device(%[[DEVICE]] : i32) motion_entries + !CHECK: omp.target_update device(%[[DEVICE]] : i32) motion_entries !$omp target update from(a) device(1) end subroutine omp_target_update_device @@ -275,9 +275,9 @@ subroutine omp_target_update_nowait logical :: i !CHECK-DAG: %[[A_DECL:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) - !CHECK-DAG: %[[BOUNDS:.*]] = omp.bounds + !CHECK-DAG: %[[BOUNDS:.*]] = omp.map.bounds - !CHECK: omp.target_update_data nowait motion_entries + !CHECK: omp.target_update nowait motion_entries !$omp target update from(a) nowait end subroutine omp_target_update_nowait @@ -290,8 +290,8 @@ subroutine omp_target_data !CHECK: %[[VAL_0:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_dataEa"} !CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[VAL_0]](%{{.*}}) {uniq_name = "_QFomp_target_dataEa"} : (!fir.ref<!fir.array<1024xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) integer :: a(1024) - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%[[A_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%[[A_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_data map_entries(%[[MAP]] : !fir.ref<!fir.array<1024xi32>>) { !$omp target data map(tofrom: a) !CHECK: %[[C10:.*]] = arith.constant 10 : i32 @@ -312,15 +312,15 @@ subroutine omp_target_data_mt !CHECK: %[[VAR_A_DECL:.*]]:2 = hlfir.declare %[[VAR_A]](%{{.*}}) {uniq_name = "_QFomp_target_data_mtEa"} : (!fir.ref<!fir.array<1024xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) !CHECK: %[[VAR_B:.*]] = fir.alloca !fir.array<1024xi32> {bindc_name = "b", uniq_name = "_QFomp_target_data_mtEb"} !CHECK: %[[VAR_B_DECL:.*]]:2 = hlfir.declare %[[VAR_B]](%{{.*}}) {uniq_name = "_QFomp_target_data_mtEb"} : (!fir.ref<!fir.array<1024xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) - !CHECK: %[[BOUNDS_A:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_A:.*]] = omp.map_info var_ptr(%[[VAR_A_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS_A]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS_A:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAR_A_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS_A]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target_data map_entries(%[[MAP_A]] : !fir.ref<!fir.array<1024xi32>>) { !$omp target data map(a) !CHECK: omp.terminator !$omp end target data !CHECK: } - !CHECK: %[[BOUNDS_B:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP_B:.*]] = omp.map_info var_ptr(%[[VAR_B_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(always, from) capture(ByRef) bounds(%[[BOUNDS_B]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} + !CHECK: %[[BOUNDS_B:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP_B:.*]] = omp.map.info var_ptr(%[[VAR_B_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(always, from) capture(ByRef) bounds(%[[BOUNDS_B]]) -> !fir.ref<!fir.array<1024xi32>> {name = "b"} !CHECK: omp.target_data map_entries(%[[MAP_B]] : !fir.ref<!fir.array<1024xi32>>) { !$omp target data map(always, from : b) !CHECK: omp.terminator @@ -336,8 +336,8 @@ end subroutine omp_target_data_mt subroutine omp_target !CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {uniq_name = "_QFomp_targetEa"} : (!fir.ref<!fir.array<1024xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) integer :: a(1024) - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%[[VAL_1]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%[[VAL_1]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]] : !fir.ref<!fir.array<1024xi32>>) { !CHECK: ^bb0(%[[ARG_0]]: !fir.ref<!fir.array<1024xi32>>): !$omp target map(tofrom: a) @@ -370,8 +370,8 @@ subroutine omp_target_depend !CHECK: %[[STRIDE_A:.*]] = arith.constant 1 : index !CHECK: %[[LBOUND_A:.*]] = arith.constant 0 : index !CHECK: %[[UBOUND_A:.*]] = arith.subi %c1024, %c1 : index - !CHECK: %[[BOUNDS_A:.*]] = omp.bounds lower_bound(%[[LBOUND_A]] : index) upper_bound(%[[UBOUND_A]] : index) extent(%[[EXTENT_A]] : index) stride(%[[STRIDE_A]] : index) start_idx(%[[STRIDE_A]] : index) - !CHECK: %[[MAP_A:.*]] = omp.map_info var_ptr(%[[A]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS_A]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS_A:.*]] = omp.map.bounds lower_bound(%[[LBOUND_A]] : index) upper_bound(%[[UBOUND_A]] : index) extent(%[[EXTENT_A]] : index) stride(%[[STRIDE_A]] : index) start_idx(%[[STRIDE_A]] : index) + !CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[A]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS_A]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target map_entries(%[[MAP_A]] -> %[[BB0_ARG:.*]] : !fir.ref<!fir.array<1024xi32>>) depend(taskdependin -> %[[A]]#1 : !fir.ref<!fir.array<1024xi32>>) { !$omp target map(tofrom: a) depend(in: a) a(1) = 10 @@ -391,7 +391,7 @@ subroutine omp_target_implicit !CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_0]] : (index) -> !fir.shape<1> !CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_2]]) {uniq_name = "_QFomp_target_implicitEa"} : (!fir.ref<!fir.array<1024xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) integer :: a(1024) - !CHECK: %[[VAL_4:.*]] = omp.map_info var_ptr(%[[VAL_3]]#1 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%{{.*}}) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[VAL_4:.*]] = omp.map.info var_ptr(%[[VAL_3]]#1 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%{{.*}}) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target map_entries(%[[VAL_4]] -> %[[VAL_6:.*]] : !fir.ref<!fir.array<1024xi32>>) { !CHECK: ^bb0(%[[VAL_6]]: !fir.ref<!fir.array<1024xi32>>): !$omp target @@ -459,9 +459,9 @@ subroutine omp_target_implicit_bounds(n) integer :: n integer :: a(n) - !CHECK: %[[VAL_14:.*]] = omp.bounds lower_bound(%c0{{.*}} : index) upper_bound(%[[UB]] : index) extent(%[[DIMS0]]#1 : index) stride(%[[DIMS0]]#2 : index) start_idx(%c1{{.*}} : index) {stride_in_bytes = true} - !CHECK: %[[VAL_15:.*]] = omp.map_info var_ptr(%[[VAL_10]]#1 : !fir.ref<!fir.array<?xi32>>, !fir.array<?xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%[[VAL_14]]) -> !fir.ref<!fir.array<?xi32>> {name = "a"} - !CHECK: %[[VAL_16:.*]] = omp.map_info var_ptr(%[[VAL_COPY]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = ""} + !CHECK: %[[VAL_14:.*]] = omp.map.bounds lower_bound(%c0{{.*}} : index) upper_bound(%[[UB]] : index) extent(%[[DIMS0]]#1 : index) stride(%[[DIMS0]]#2 : index) start_idx(%c1{{.*}} : index) {stride_in_bytes = true} + !CHECK: %[[VAL_15:.*]] = omp.map.info var_ptr(%[[VAL_10]]#1 : !fir.ref<!fir.array<?xi32>>, !fir.array<?xi32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%[[VAL_14]]) -> !fir.ref<!fir.array<?xi32>> {name = "a"} + !CHECK: %[[VAL_16:.*]] = omp.map.info var_ptr(%[[VAL_COPY]] : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = ""} !CHECK: omp.target map_entries(%[[VAL_15]] -> %[[VAL_17:.*]], %[[VAL_16]] -> %[[VAL_18:.*]] : !fir.ref<!fir.array<?xi32>>, !fir.ref<i32>) { !CHECK: ^bb0(%[[VAL_17]]: !fir.ref<!fir.array<?xi32>>, %[[VAL_18]]: !fir.ref<i32>): !$omp target @@ -491,7 +491,7 @@ end subroutine omp_target_implicit_bounds subroutine omp_target_thread_limit integer :: a !CHECK: %[[VAL_1:.*]] = arith.constant 64 : i32 - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "a"} + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "a"} !CHECK: omp.target thread_limit(%[[VAL_1]] : i32) map_entries(%[[MAP]] -> %{{.*}} : !fir.ref<i32>) { !CHECK: ^bb0(%{{.*}}: !fir.ref<i32>): !$omp target map(tofrom: a) thread_limit(64) @@ -510,7 +510,7 @@ subroutine omp_target_device_ptr use iso_c_binding, only : c_ptr, c_loc type(c_ptr) :: a integer, target :: b - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}}) map_clauses(tofrom) capture(ByRef) -> {{.*}} {name = "a"} + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}}) map_clauses(tofrom) capture(ByRef) -> {{.*}} {name = "a"} !CHECK: omp.target_data map_entries(%[[MAP]]{{.*}} !$omp target data map(tofrom: a) use_device_ptr(a) !CHECK: ^bb0(%[[VAL_1:.*]]: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>): @@ -530,8 +530,8 @@ end subroutine omp_target_device_ptr integer, pointer :: a !CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box<!fir.ptr<i32>> {bindc_name = "a", uniq_name = "_QFomp_target_device_addrEa"} !CHECK: %[[VAL_0_DECL:.*]]:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFomp_target_device_addrEa"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>) - !CHECK: %[[MAP_MEMBERS:.*]] = omp.map_info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, i32) var_ptr_ptr({{.*}} : !fir.llvm_ptr<!fir.ref<i32>>) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""} - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBERS]] : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "a"} + !CHECK: %[[MAP_MEMBERS:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, i32) var_ptr_ptr({{.*}} : !fir.llvm_ptr<!fir.ref<i32>>) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""} + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.box<!fir.ptr<i32>>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBERS]] : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>> {name = "a"} !CHECK: omp.target_data map_entries(%[[MAP_MEMBERS]], %[[MAP]] : {{.*}}) use_device_addr(%[[VAL_0_DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<i32>>>) { !$omp target data map(tofrom: a) use_device_addr(a) !CHECK: ^bb0(%[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>): @@ -585,8 +585,8 @@ subroutine omp_target_parallel_do !CHECK: %[[C1:.*]] = arith.constant 1 : index !CHECK: %[[C0:.*]] = arith.constant 0 : index !CHECK: %[[SUB:.*]] = arith.subi %[[C1024]], %[[C1]] : index - !CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[C0]] : index) upper_bound(%[[SUB]] : index) extent(%[[C1024]] : index) stride(%[[C1]] : index) start_idx(%[[C1]] : index) - !CHECK: %[[MAP:.*]] = omp.map_info var_ptr(%[[VAL_0_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} + !CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%[[C0]] : index) upper_bound(%[[SUB]] : index) extent(%[[C1024]] : index) stride(%[[C1]] : index) start_idx(%[[C1]] : index) + !CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%[[VAL_0_DECL]]#0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<1024xi32>> {name = "a"} !CHECK: omp.target map_entries(%[[MAP]] -> %[[ARG_0:.*]], %{{.*}} -> %{{.*}} : !fir.ref<!fir.array<1024xi32>>, !fir.ref<i32>) { !CHECK: ^bb0(%[[ARG_0]]: !fir.ref<!fir.array<1024xi32>>, %{{.*}}: !fir.ref<i32>): !CHECK: %[[VAL_0_DECL:.*]]:2 = hlfir.declare %[[ARG_0]](%{{.*}}) {uniq_name = "_QFomp_target_parallel_doEa"} : (!fir.ref<!fir.array<1024xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>) @@ -623,8 +623,8 @@ subroutine target_unstructured integer :: i = 1 !CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFtarget_unstructuredEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) integer :: j = 11 - !CHECK: %[[VAL_4:.*]] = omp.map_info var_ptr(%[[VAL_1]]#1 : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "i"} - !CHECK: %[[VAL_5:.*]] = omp.map_info var_ptr(%[[VAL_3]]#1 : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "j"} + !CHECK: %[[VAL_4:.*]] = omp.map.info var_ptr(%[[VAL_1]]#1 : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "i"} + !CHECK: %[[VAL_5:.*]] = omp.map.info var_ptr(%[[VAL_3]]#1 : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "j"} !CHECK: omp.target map_entries(%[[VAL_4]] -> %[[VAL_6:.*]], %[[VAL_5]] -> %[[VAL_7:.*]] : !fir.ref<i32>, !fir.ref<i32>) { !CHECK: ^bb0(%[[VAL_6]]: !fir.ref<i32>, %[[VAL_7]]: !fir.ref<i32>): !$omp target diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-add-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-add-byref.f90 index e8a04c23f4ea..caec65b6051c 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-add-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-add-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s -! CHECK-LABEL: omp.reduction.declare @add_reduction_f_64_byref : !fir.ref<f64> +! CHECK-LABEL: omp.declare_reduction @add_reduction_f_64_byref : !fir.ref<f64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f64>): ! CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f64 @@ -18,7 +18,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f64>) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_64_byref : !fir.ref<i64> +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_64_byref : !fir.ref<i64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i64>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i64 @@ -35,7 +35,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<i64>) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_f_32_byref : !fir.ref<f32> +! CHECK-LABEL: omp.declare_reduction @add_reduction_f_32_byref : !fir.ref<f32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f32 @@ -52,7 +52,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32_byref : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir-byref.f90 index 3739b3ae36ea..5e5df8c1365a 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32_byref : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir.f90 index 4d30282fc8c2..d6006f21b3bd 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 index 7df4f37b98df..d6222a248b7f 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 @@ -11,7 +11,7 @@ -! CHECK-LABEL: omp.reduction.declare @add_reduction_f_64 : f64 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_f_64 : f64 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f64): ! CHECK: %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f64 ! CHECK: omp.yield(%[[VAL_1]] : f64) @@ -22,7 +22,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f64) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_64 : i64 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_64 : i64 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i64): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i64 ! CHECK: omp.yield(%[[VAL_1]] : i64) @@ -33,7 +33,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : i64) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_f_32 : f32 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_f_32 : f32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f32 ! CHECK: omp.yield(%[[VAL_1]] : f32) @@ -44,7 +44,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @add_reduction_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-array.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-array.f90 index 4350ace820c2..be4d27f6ac47 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-array.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-array.f90 @@ -14,7 +14,7 @@ enddo print *,r end program -! CHECK-LABEL omp.reduction.declare @add_reduction_i_32_box_2_byref : !fir.ref<!fir.box<!fir.array<2xi32>>> init { +! CHECK-LABEL omp.declare_reduction @add_reduction_i_32_box_2_byref : !fir.ref<!fir.box<!fir.array<2xi32>>> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>): ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<2xi32> {bindc_name = ".tmp"} ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 index 8543c58dec4d..c77bd72f916d 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 @@ -14,7 +14,7 @@ enddo print *,r end program -! CHECK-LABEL omp.reduction.declare @add_reduction_i_32_box_2_byref : !fir.ref<!fir.box<!fir.array<2xi32>>> init { +! CHECK-LABEL omp.declare_reduction @add_reduction_i_32_box_2_byref : !fir.ref<!fir.box<!fir.array<2xi32>>> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>): ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<2xi32> {bindc_name = ".tmp"} ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-iand-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-iand-byref.f90 index 15a6dde046fe..2df3ad393ba5 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-iand-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-iand-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @iand_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @iand_i_32_byref : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant -1 : i32 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-iand.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-iand.f90 index 9588531f6c90..707be66def8d 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-iand.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-iand.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @iand_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @iand_i_32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant -1 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-ieor-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-ieor-byref.f90 index 4e0957219fa5..72a6901878ad 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-ieor-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-ieor-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s -! CHECK-LABEL: omp.reduction.declare @ieor_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @ieor_i_32_byref : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-ieor.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-ieor.f90 index a14a37101874..11245c4ac95e 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-ieor.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-ieor.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s -!CHECK: omp.reduction.declare @[[IEOR_DECLARE_I:.*]] : i32 init { +!CHECK: omp.declare_reduction @[[IEOR_DECLARE_I:.*]] : i32 init { !CHECK: %[[ZERO_VAL_I:.*]] = arith.constant 0 : i32 !CHECK: omp.yield(%[[ZERO_VAL_I]] : i32) !CHECK: combiner diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-ior-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-ior-byref.f90 index 712edaf95575..662e64b8fae6 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-ior-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-ior-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @ior_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @ior_i_32_byref : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-ior.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-ior.f90 index 3b5e32743935..8f6ca7c41c42 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-ior.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-ior.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @ior_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @ior_i_32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-logical-and-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-logical-and-byref.f90 index 4162626f926a..59411534e4a5 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-logical-and-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-logical-and-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @and_reduction : !fir.ref<!fir.logical<4>> +! CHECK-LABEL: omp.declare_reduction @and_reduction : !fir.ref<!fir.logical<4>> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>): ! CHECK: %[[VAL_1:.*]] = arith.constant true diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-logical-and.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-logical-and.f90 index 17d321620cca..9ca733281c2f 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-logical-and.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-logical-and.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @and_reduction : !fir.logical<4> init { +! CHECK-LABEL: omp.declare_reduction @and_reduction : !fir.logical<4> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.logical<4>): ! CHECK: %[[VAL_1:.*]] = arith.constant true ! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i1) -> !fir.logical<4> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-logical-eqv-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-logical-eqv-byref.f90 index 4c159f3a69f9..1d6e1b0545c3 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-logical-eqv-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-logical-eqv-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @eqv_reduction : !fir.ref<!fir.logical<4>> +! CHECK-LABEL: omp.declare_reduction @eqv_reduction : !fir.ref<!fir.logical<4>> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>): ! CHECK: %[[VAL_1:.*]] = arith.constant true diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-logical-eqv.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-logical-eqv.f90 index 8204e4c878cb..a1bfa462cd59 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-logical-eqv.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-logical-eqv.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @eqv_reduction : !fir.logical<4> init { +! CHECK-LABEL: omp.declare_reduction @eqv_reduction : !fir.logical<4> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.logical<4>): ! CHECK: %[[VAL_1:.*]] = arith.constant true ! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i1) -> !fir.logical<4> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-logical-neqv-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-logical-neqv-byref.f90 index cfa8e47d3ca7..a94b67a97832 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-logical-neqv-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-logical-neqv-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @neqv_reduction : !fir.ref<!fir.logical<4>> +! CHECK-LABEL: omp.declare_reduction @neqv_reduction : !fir.ref<!fir.logical<4>> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>): ! CHECK: %[[VAL_1:.*]] = arith.constant false diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-logical-neqv.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-logical-neqv.f90 index 623368a50e86..08d6a2efd399 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-logical-neqv.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-logical-neqv.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @neqv_reduction : !fir.logical<4> init { +! CHECK-LABEL: omp.declare_reduction @neqv_reduction : !fir.logical<4> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.logical<4>): ! CHECK: %[[VAL_1:.*]] = arith.constant false ! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i1) -> !fir.logical<4> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-logical-or-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-logical-or-byref.f90 index c71ea02f9373..ca69ccee4a38 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-logical-or-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-logical-or-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @or_reduction : !fir.ref<!fir.logical<4>> +! CHECK-LABEL: omp.declare_reduction @or_reduction : !fir.ref<!fir.logical<4>> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>): ! CHECK: %[[VAL_1:.*]] = arith.constant false diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-logical-or.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-logical-or.f90 index f1ae1bc687cd..c4bf8e9d65ae 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-logical-or.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-logical-or.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @or_reduction : !fir.logical<4> init { +! CHECK-LABEL: omp.declare_reduction @or_reduction : !fir.logical<4> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.logical<4>): ! CHECK: %[[VAL_1:.*]] = arith.constant false ! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i1) -> !fir.logical<4> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 index f9bffc269bb8..058eeea5fb92 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -!CHECK: omp.reduction.declare @max_f_32_byref : !fir.ref<f32> +!CHECK: omp.declare_reduction @max_f_32_byref : !fir.ref<f32> !CHECK-SAME: init { !CHECK: %[[MINIMUM_VAL:.*]] = arith.constant -3.40282347E+38 : f32 !CHECK: %[[REF:.*]] = fir.alloca f32 @@ -17,7 +17,7 @@ !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32> !CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) -!CHECK-LABEL: omp.reduction.declare @max_i_32_byref : !fir.ref<i32> +!CHECK-LABEL: omp.declare_reduction @max_i_32_byref : !fir.ref<i32> !CHECK-SAME: init { !CHECK: %[[MINIMUM_VAL:.*]] = arith.constant -2147483648 : i32 !CHECK: %[[REF:.*]] = fir.alloca i32 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir-byref.f90 index a296ce47f20f..3a07450765cf 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @max_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @max_i_32_byref : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[MINIMUM_VAL:.*]] = arith.constant -2147483648 : i32 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir.f90 index ed25cedae90c..3dfed100a02e 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @max_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @max_i_32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant -2147483648 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 index ea3b1bebce03..895eca85fd1e 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @max_f_32 : f32 init { +! CHECK-LABEL: omp.declare_reduction @max_f_32 : f32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32): ! CHECK: %[[VAL_1:.*]] = arith.constant -3.40282347E+38 : f32 ! CHECK: omp.yield(%[[VAL_1]] : f32) @@ -14,7 +14,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @max_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @max_i_32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant -2147483648 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 index da9e686362b6..c44301f68b83 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -!CHECK: omp.reduction.declare @min_f_32_byref : !fir.ref<f32> +!CHECK: omp.declare_reduction @min_f_32_byref : !fir.ref<f32> !CHECK-SAME: init { !CHECK: %[[MAXIMUM_VAL:.*]] = arith.constant 3.40282347E+38 : f32 !CHECK: %[[REF:.*]] = fir.alloca f32 @@ -17,7 +17,7 @@ !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32> !CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) -!CHECK-LABEL: omp.reduction.declare @min_i_32_byref : !fir.ref<i32> +!CHECK-LABEL: omp.declare_reduction @min_i_32_byref : !fir.ref<i32> !CHECK-SAME: init { !CHECK: %[[MAXIMUM_VAL:.*]] = arith.constant 2147483647 : i32 !CHECK: %[[REF:.*]] = fir.alloca i32 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 index 3aa9001869dc..700ff78339c1 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @min_f_32 : f32 init { +! CHECK-LABEL: omp.declare_reduction @min_f_32 : f32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32): ! CHECK: %[[VAL_1:.*]] = arith.constant 3.40282347E+38 : f32 ! CHECK: omp.yield(%[[VAL_1]] : f32) @@ -14,7 +14,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @min_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @min_i_32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 2147483647 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-min2.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-min2.f90 index 86fb067fc48e..cef1102a2fcc 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-min2.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-min2.f90 @@ -17,7 +17,7 @@ print *,r end program -! CHECK-LABEL: omp.reduction.declare @min_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @min_i_32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 2147483647 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-mul-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-mul-byref.f90 index 00854281b87e..c6aa21c4231c 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-mul-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-mul-byref.f90 @@ -4,7 +4,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @multiply_reduction_f_64_byref : !fir.ref<f64> +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_f_64_byref : !fir.ref<f64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f64>): ! CHECK: %[[VAL_1:.*]] = arith.constant 1.000000e+00 : f64 @@ -21,7 +21,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f64>) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @multiply_reduction_i_64_byref : !fir.ref<i64> +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_i_64_byref : !fir.ref<i64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i64>): ! CHECK: %[[VAL_1:.*]] = arith.constant 1 : i64 @@ -38,7 +38,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<i64>) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @multiply_reduction_f_32_byref : !fir.ref<f32> +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_f_32_byref : !fir.ref<f32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>): ! CHECK: %[[VAL_1:.*]] = arith.constant 1.000000e+00 : f32 @@ -55,7 +55,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @multiply_reduction_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_i_32_byref : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[VAL_1:.*]] = arith.constant 1 : i32 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 index 4774fba3f33e..ce34aafe7dc5 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 @@ -4,7 +4,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.reduction.declare @multiply_reduction_f_64 : f64 init { +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_f_64 : f64 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f64): ! CHECK: %[[VAL_1:.*]] = arith.constant 1.000000e+00 : f64 ! CHECK: omp.yield(%[[VAL_1]] : f64) @@ -15,7 +15,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f64) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @multiply_reduction_i_64 : i64 init { +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_i_64 : i64 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i64): ! CHECK: %[[VAL_1:.*]] = arith.constant 1 : i64 ! CHECK: omp.yield(%[[VAL_1]] : i64) @@ -26,7 +26,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : i64) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @multiply_reduction_f_32 : f32 init { +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_f_32 : f32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32): ! CHECK: %[[VAL_1:.*]] = arith.constant 1.000000e+00 : f32 ! CHECK: omp.yield(%[[VAL_1]] : f32) @@ -37,7 +37,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } -! CHECK-LABEL: omp.reduction.declare @multiply_reduction_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_i_32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 1 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) diff --git a/flang/test/Transforms/omp-descriptor-map-info-gen.fir b/flang/test/Transforms/omp-descriptor-map-info-gen.fir index 22594ec88c9c..05d05b0ecb59 100644 --- a/flang/test/Transforms/omp-descriptor-map-info-gen.fir +++ b/flang/test/Transforms/omp-descriptor-map-info-gen.fir @@ -15,10 +15,10 @@ module attributes {omp.is_target_device = false} { %c1 = arith.constant 0 : index %c2 = arith.constant 10 : index %dims:3 = fir.box_dims %2#1, %c1 : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index) - %bounds = omp.bounds lower_bound(%c1 : index) upper_bound(%c2 : index) extent(%dims#1 : index) stride(%dims#2 : index) start_idx(%c0 : index) {stride_in_bytes = true} + %bounds = omp.map.bounds lower_bound(%c1 : index) upper_bound(%c2 : index) extent(%dims#1 : index) stride(%dims#2 : index) start_idx(%c0 : index) {stride_in_bytes = true} %7 = fir.box_addr %2#1 : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>> - %8 = omp.map_info var_ptr(%4#1 : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<i32>>> - %9 = omp.map_info var_ptr(%7 : !fir.ref<!fir.array<?xi32>>, !fir.array<?xi32>) map_clauses(from) capture(ByRef) bounds(%bounds) -> !fir.ref<!fir.array<?xi32>> + %8 = omp.map.info var_ptr(%4#1 : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<i32>>> + %9 = omp.map.info var_ptr(%7 : !fir.ref<!fir.array<?xi32>>, !fir.array<?xi32>) map_clauses(from) capture(ByRef) bounds(%bounds) -> !fir.ref<!fir.array<?xi32>> omp.target map_entries(%8 -> %arg1, %9 -> %arg2 : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.array<?xi32>>) { ^bb0(%arg1: !fir.ref<!fir.box<!fir.heap<i32>>>, %arg2: !fir.ref<!fir.array<?xi32>>): omp.terminator @@ -32,13 +32,13 @@ module attributes {omp.is_target_device = false} { // CHECK: %[[ALLOCA2:.*]] = fir.alloca !fir.box<!fir.heap<i32>> // CHECK: %[[DECLARE1:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<intent_out>, uniq_name = "test"} : (!fir.box<!fir.array<?xi32>>) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>) // CHECK: %[[DECLARE2:.*]]:2 = hlfir.declare %[[ALLOCA2]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "test2"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>) -// CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound(%{{.*}} : index) upper_bound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) start_idx(%{{.*}} : index) {stride_in_bytes = true} +// CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%{{.*}} : index) upper_bound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) start_idx(%{{.*}} : index) {stride_in_bytes = true} // CHECK: %[[BASE_ADDR_OFF:.*]] = fir.box_offset %[[DECLARE2]]#1 base_addr : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> !fir.llvm_ptr<!fir.ref<i32>> -// CHECK: %[[DESC_MEMBER_MAP:.*]] = omp.map_info var_ptr(%[[DECLARE2]]#1 : !fir.ref<!fir.box<!fir.heap<i32>>>, i32) var_ptr_ptr(%[[BASE_ADDR_OFF]] : !fir.llvm_ptr<!fir.ref<i32>>) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""} -// CHECK: %[[DESC_PARENT_MAP:.*]] = omp.map_info var_ptr(%[[DECLARE2]]#1 : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>) map_clauses(tofrom) capture(ByRef) members(%[[DESC_MEMBER_MAP]] : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.heap<i32>>> +// CHECK: %[[DESC_MEMBER_MAP:.*]] = omp.map.info var_ptr(%[[DECLARE2]]#1 : !fir.ref<!fir.box<!fir.heap<i32>>>, i32) var_ptr_ptr(%[[BASE_ADDR_OFF]] : !fir.llvm_ptr<!fir.ref<i32>>) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""} +// CHECK: %[[DESC_PARENT_MAP:.*]] = omp.map.info var_ptr(%[[DECLARE2]]#1 : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>) map_clauses(tofrom) capture(ByRef) members(%[[DESC_MEMBER_MAP]] : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.heap<i32>>> // CHECK: fir.store %[[DECLARE1]]#1 to %[[ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>> // CHECK: %[[BASE_ADDR_OFF_2:.*]] = fir.box_offset %[[ALLOCA]] base_addr : (!fir.ref<!fir.box<!fir.array<?xi32>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> -// CHECK: %[[DESC_MEMBER_MAP_2:.*]] = omp.map_info var_ptr(%[[ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.array<?xi32>) var_ptr_ptr(%[[BASE_ADDR_OFF_2]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} -// CHECK: %[[DESC_PARENT_MAP_2:.*]] = omp.map_info var_ptr(%[[ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.box<!fir.array<?xi32>>) map_clauses(from) capture(ByRef) members(%15 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.array<?xi32>> +// CHECK: %[[DESC_MEMBER_MAP_2:.*]] = omp.map.info var_ptr(%[[ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.array<?xi32>) var_ptr_ptr(%[[BASE_ADDR_OFF_2]] : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(from) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>> {name = ""} +// CHECK: %[[DESC_PARENT_MAP_2:.*]] = omp.map.info var_ptr(%[[ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.box<!fir.array<?xi32>>) map_clauses(from) capture(ByRef) members(%15 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.array<?xi32>> // CHECK: omp.target map_entries(%[[DESC_MEMBER_MAP]] -> %[[ARG1:.*]], %[[DESC_PARENT_MAP]] -> %[[ARG2:.*]], %[[DESC_MEMBER_MAP_2]] -> %[[ARG3:.*]], %[[DESC_PARENT_MAP_2]] -> %[[ARG4:.*]] : {{.*}}) { // CHECK: ^bb0(%[[ARG1]]: !fir.llvm_ptr<!fir.ref<i32>>, %[[ARG2]]: !fir.ref<!fir.box<!fir.heap<i32>>>, %[[ARG3]]: !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, %[[ARG4]]: !fir.ref<!fir.array<?xi32>>): diff --git a/flang/test/Transforms/omp-reduction-cfg-conversion.fir b/flang/test/Transforms/omp-reduction-cfg-conversion.fir index c27bba2f7b07..3103c4456d72 100644 --- a/flang/test/Transforms/omp-reduction-cfg-conversion.fir +++ b/flang/test/Transforms/omp-reduction-cfg-conversion.fir @@ -1,6 +1,6 @@ // RUN: fir-opt --cfg-conversion-on-reduce-opt %s | FileCheck %s -omp.reduction.declare @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init { +omp.declare_reduction @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init { ^bb0(%arg0: !fir.ref<!fir.box<!fir.array<3xi32>>>): %c4_i32 = arith.constant 4 : i32 %c0_i32 = arith.constant 0 : i32 diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td index dcf04ab24225..f33942b3c7c0 100644 --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -515,7 +515,7 @@ def SingleOp : OpenMP_Op<"single", [AttrSizedOperandSegments]> { // 2.9.2 Workshare Loop Construct //===----------------------------------------------------------------------===// -def WsLoopOp : OpenMP_Op<"wsloop", [AttrSizedOperandSegments, +def WsloopOp : OpenMP_Op<"wsloop", [AttrSizedOperandSegments, AllTypesMatch<["lowerBound", "upperBound", "step"]>, RecursiveMemoryEffects, ReductionClauseInterface]> { let summary = "worksharing-loop construct"; @@ -625,9 +625,9 @@ def WsLoopOp : OpenMP_Op<"wsloop", [AttrSizedOperandSegments, |`byref` $byref |`ordered` `(` $ordered_val `)` |`order` `(` custom<ClauseAttr>($order_val) `)` - ) custom<WsLoop>($region, $lowerBound, $upperBound, $step, - type($step), $reduction_vars, type($reduction_vars), $reductions, - $inclusive) attr-dict + ) custom<Wsloop>($region, $lowerBound, $upperBound, $step, type($step), + $reduction_vars, type($reduction_vars), $reductions, + $inclusive) attr-dict }]; let hasVerifier = 1; } @@ -724,7 +724,7 @@ def SimdLoopOp : OpenMP_Op<"simdloop", [AttrSizedOperandSegments, def YieldOp : OpenMP_Op<"yield", [Pure, ReturnLike, Terminator, - ParentOneOf<["WsLoopOp", "ReductionDeclareOp", + ParentOneOf<["WsloopOp", "DeclareReductionOp", "AtomicUpdateOp", "SimdLoopOp", "PrivateClauseOp"]>]> { let summary = "loop yield and termination operation"; let description = [{ @@ -914,7 +914,7 @@ def TaskOp : OpenMP_Op<"task", [AttrSizedOperandSegments, let hasVerifier = 1; } -def TaskLoopOp : OpenMP_Op<"taskloop", [AttrSizedOperandSegments, +def TaskloopOp : OpenMP_Op<"taskloop", [AttrSizedOperandSegments, AutomaticAllocationScope, RecursiveMemoryEffects, AllTypesMatch<["lowerBound", "upperBound", "step"]>, ReductionClauseInterface]> { @@ -1072,7 +1072,7 @@ def TaskLoopOp : OpenMP_Op<"taskloop", [AttrSizedOperandSegments, let hasVerifier = 1; } -def TaskGroupOp : OpenMP_Op<"taskgroup", [AttrSizedOperandSegments, +def TaskgroupOp : OpenMP_Op<"taskgroup", [AttrSizedOperandSegments, ReductionClauseInterface, AutomaticAllocationScope]> { let summary = "taskgroup construct"; @@ -1191,24 +1191,24 @@ def VariableCaptureKindAttr : EnumAttr<OpenMP_Dialect, VariableCaptureKind, let assemblyFormat = "`(` $value `)`"; } -def DataBoundsType : OpenMP_Type<"DataBounds", "data_bounds_ty"> { - let summary = "Type for representing omp data clause bounds information"; +def MapBoundsType : OpenMP_Type<"MapBounds", "map_bounds_ty"> { + let summary = "Type for representing omp map clause bounds information"; } -def DataBoundsOp : OpenMP_Op<"bounds", +def MapBoundsOp : OpenMP_Op<"map.bounds", [AttrSizedOperandSegments, NoMemoryEffect]> { let summary = "Represents normalized bounds information for map clauses."; let description = [{ This operation is a variation on the OpenACC dialects DataBoundsOp. Within the OpenMP dialect it stores the bounds/range of data to be mapped to a - device specified by map clauses on target directives. Within, - the OpenMP dialect the DataBoundsOp is associated with MapInfoOp, + device specified by map clauses on target directives. Within + the OpenMP dialect, the MapBoundsOp is associated with MapInfoOp, helping to store bounds information for the mapped variable. It is used to support OpenMP array sectioning, Fortran pointer and allocatable mapping and pointer/allocatable member of derived types. - In all cases the DataBoundsOp holds information on the section of + In all cases the MapBoundsOp holds information on the section of data to be mapped. Such as the upper bound and lower bound of the section of data to be mapped. This information is currently utilised by the LLVM-IR lowering to help generate instructions to @@ -1227,7 +1227,7 @@ def DataBoundsOp : OpenMP_Op<"bounds", ``` => ```mlir - omp.bounds lower_bound(1) upper_bound(9) extent(9) start_idx(0) + omp.map.bounds lower_bound(1) upper_bound(9) extent(9) start_idx(0) ``` Fortran: @@ -1237,7 +1237,7 @@ def DataBoundsOp : OpenMP_Op<"bounds", ``` => ```mlir - omp.bounds lower_bound(1) upper_bound(9) extent(9) start_idx(1) + omp.map.bounds lower_bound(1) upper_bound(9) extent(9) start_idx(1) ``` For Fortran pointers and allocatables (as well as those that are @@ -1257,7 +1257,7 @@ def DataBoundsOp : OpenMP_Op<"bounds", ``` => ```mlir - omp.bounds lower_bound(0) upper_bound(9) extent(10) start_idx(1) + omp.map.bounds lower_bound(0) upper_bound(9) extent(10) start_idx(1) ``` This operation records the bounds information in a normalized fashion @@ -1276,7 +1276,7 @@ def DataBoundsOp : OpenMP_Op<"bounds", Optional<IntLikeType>:$stride, DefaultValuedAttr<BoolAttr, "false">:$stride_in_bytes, Optional<IntLikeType>:$start_idx); - let results = (outs DataBoundsType:$result); + let results = (outs MapBoundsType:$result); let assemblyFormat = [{ oilist( @@ -1303,12 +1303,12 @@ def DataBoundsOp : OpenMP_Op<"bounds", let hasVerifier = 1; } -def MapInfoOp : OpenMP_Op<"map_info", [AttrSizedOperandSegments]> { +def MapInfoOp : OpenMP_Op<"map.info", [AttrSizedOperandSegments]> { let arguments = (ins OpenMP_PointerLikeType:$var_ptr, TypeAttr:$var_type, Optional<OpenMP_PointerLikeType>:$var_ptr_ptr, Variadic<OpenMP_PointerLikeType>:$members, - Variadic<DataBoundsType>:$bounds, /* rank-0 to rank-{n-1} */ + Variadic<MapBoundsType>:$bounds, /* rank-0 to rank-{n-1} */ OptionalAttr<UI64Attr>:$map_type, OptionalAttr<VariableCaptureKindAttr>:$map_capture_type, OptionalAttr<StrAttr>:$name); @@ -1338,7 +1338,7 @@ def MapInfoOp : OpenMP_Op<"map_info", [AttrSizedOperandSegments]> { ``` => ```mlir - omp.map_info var_ptr(%index_ssa) map_type(to) map_capture_type(ByRef) + omp.map.info var_ptr(%index_ssa) map_type(to) map_capture_type(ByRef) name(index) ``` @@ -1391,8 +1391,8 @@ def MapInfoOp : OpenMP_Op<"map_info", [AttrSizedOperandSegments]> { // 2.14.2 target data Construct //===---------------------------------------------------------------------===// -def Target_DataOp: OpenMP_Op<"target_data", [AttrSizedOperandSegments, - MapClauseOwningOpInterface]>{ +def TargetDataOp: OpenMP_Op<"target_data", [AttrSizedOperandSegments, + MapClauseOwningOpInterface]>{ let summary = "target data construct"; let description = [{ Map variables to a device data environment for the extent of the region. @@ -1448,7 +1448,7 @@ def Target_DataOp: OpenMP_Op<"target_data", [AttrSizedOperandSegments, // 2.14.3 target enter data Construct //===---------------------------------------------------------------------===// -def Target_EnterDataOp: OpenMP_Op<"target_enter_data", +def TargetEnterDataOp: OpenMP_Op<"target_enter_data", [AttrSizedOperandSegments, MapClauseOwningOpInterface]>{ let summary = "target enter data construct"; @@ -1502,7 +1502,7 @@ def Target_EnterDataOp: OpenMP_Op<"target_enter_data", // 2.14.4 target exit data Construct //===---------------------------------------------------------------------===// -def Target_ExitDataOp: OpenMP_Op<"target_exit_data", +def TargetExitDataOp: OpenMP_Op<"target_exit_data", [AttrSizedOperandSegments, MapClauseOwningOpInterface]>{ let summary = "target exit data construct"; @@ -1553,13 +1553,12 @@ def Target_ExitDataOp: OpenMP_Op<"target_exit_data", } //===---------------------------------------------------------------------===// -// 2.14.6 target update data Construct +// 2.14.6 target update Construct //===---------------------------------------------------------------------===// -def Target_UpdateDataOp: OpenMP_Op<"target_update_data", - [AttrSizedOperandSegments, - MapClauseOwningOpInterface]>{ - let summary = "target update data construct"; +def TargetUpdateOp: OpenMP_Op<"target_update", [AttrSizedOperandSegments, + MapClauseOwningOpInterface]>{ + let summary = "target update construct"; let description = [{ The target update directive makes the corresponding list items in the device data environment consistent with their original list items, according to the @@ -1613,7 +1612,7 @@ def Target_UpdateDataOp: OpenMP_Op<"target_update_data", // 2.14.5 target construct //===----------------------------------------------------------------------===// -def TargetOp : OpenMP_Op<"target",[IsolatedFromAbove, MapClauseOwningOpInterface, +def TargetOp : OpenMP_Op<"target", [IsolatedFromAbove, MapClauseOwningOpInterface, OutlineableOpenMPOpInterface, AttrSizedOperandSegments]> { let summary = "target construct"; let description = [{ @@ -1782,7 +1781,7 @@ def OrderedOp : OpenMP_Op<"ordered"> { let hasVerifier = 1; } -def OrderedRegionOp : OpenMP_Op<"ordered_region"> { +def OrderedRegionOp : OpenMP_Op<"ordered.region"> { let summary = "ordered construct with region"; let description = [{ The ordered construct with region specifies a structured block in a @@ -2113,7 +2112,7 @@ def CancelOp : OpenMP_Op<"cancel"> { //===----------------------------------------------------------------------===// // 2.18.2 Cancellation Point Construct //===----------------------------------------------------------------------===// -def CancellationPointOp : OpenMP_Op<"cancellationpoint"> { +def CancellationPointOp : OpenMP_Op<"cancellation_point"> { let summary = "cancellation point directive"; let description = [{ The cancellation point construct introduces a user-defined cancellation @@ -2131,7 +2130,7 @@ def CancellationPointOp : OpenMP_Op<"cancellationpoint"> { // 2.19.5.7 declare reduction Directive //===----------------------------------------------------------------------===// -def ReductionDeclareOp : OpenMP_Op<"reduction.declare", [Symbol, +def DeclareReductionOp : OpenMP_Op<"declare_reduction", [Symbol, IsolatedFromAbove]> { let summary = "declares a reduction kind"; diff --git a/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp index fa54d01cfe23..b9ada0fa0f97 100644 --- a/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp +++ b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp @@ -239,21 +239,23 @@ void mlir::configureOpenMPToLLVMConversionLegality( ConversionTarget &target, LLVMTypeConverter &typeConverter) { target.addDynamicallyLegalOp< mlir::omp::AtomicReadOp, mlir::omp::AtomicWriteOp, mlir::omp::FlushOp, - mlir::omp::ThreadprivateOp, mlir::omp::YieldOp, mlir::omp::EnterDataOp, - mlir::omp::ExitDataOp, mlir::omp::UpdateDataOp, mlir::omp::DataBoundsOp, - mlir::omp::MapInfoOp>([&](Operation *op) { - return typeConverter.isLegal(op->getOperandTypes()) && - typeConverter.isLegal(op->getResultTypes()); - }); + mlir::omp::ThreadprivateOp, mlir::omp::YieldOp, + mlir::omp::TargetEnterDataOp, mlir::omp::TargetExitDataOp, + mlir::omp::TargetUpdateOp, mlir::omp::MapBoundsOp, mlir::omp::MapInfoOp>( + [&](Operation *op) { + return typeConverter.isLegal(op->getOperandTypes()) && + typeConverter.isLegal(op->getResultTypes()); + }); target.addDynamicallyLegalOp<mlir::omp::ReductionOp>([&](Operation *op) { return typeConverter.isLegal(op->getOperandTypes()); }); target.addDynamicallyLegalOp< mlir::omp::AtomicUpdateOp, mlir::omp::CriticalOp, mlir::omp::TargetOp, - mlir::omp::DataOp, mlir::omp::OrderedRegionOp, mlir::omp::ParallelOp, - mlir::omp::WsLoopOp, mlir::omp::SimdLoopOp, mlir::omp::MasterOp, - mlir::omp::SectionOp, mlir::omp::SectionsOp, mlir::omp::SingleOp, - mlir::omp::TaskGroupOp, mlir::omp::TaskOp, mlir::omp::ReductionDeclareOp, + mlir::omp::TargetDataOp, mlir::omp::OrderedRegionOp, + mlir::omp::ParallelOp, mlir::omp::WsloopOp, mlir::omp::SimdLoopOp, + mlir::omp::MasterOp, mlir::omp::SectionOp, mlir::omp::SectionsOp, + mlir::omp::SingleOp, mlir::omp::TaskgroupOp, mlir::omp::TaskOp, + mlir::omp::DeclareReductionOp, mlir::omp::PrivateClauseOp>([&](Operation *op) { return std::all_of(op->getRegions().begin(), op->getRegions().end(), [&](Region ®ion) { @@ -270,28 +272,28 @@ void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter, // bounds information for map clauses and the operation and type are // discarded on lowering to LLVM-IR from the OpenMP dialect. converter.addConversion( - [&](omp::DataBoundsType type) -> Type { return type; }); + [&](omp::MapBoundsType type) -> Type { return type; }); patterns.add< AtomicReadOpConversion, MapInfoOpConversion, ReductionOpConversion, - MultiRegionOpConversion<omp::ReductionDeclareOp>, + MultiRegionOpConversion<omp::DeclareReductionOp>, MultiRegionOpConversion<omp::PrivateClauseOp>, RegionOpConversion<omp::CriticalOp>, RegionOpConversion<omp::MasterOp>, ReductionOpConversion, RegionOpConversion<omp::OrderedRegionOp>, - RegionOpConversion<omp::ParallelOp>, RegionOpConversion<omp::WsLoopOp>, + RegionOpConversion<omp::ParallelOp>, RegionOpConversion<omp::WsloopOp>, RegionOpConversion<omp::SectionsOp>, RegionOpConversion<omp::SectionOp>, RegionOpConversion<omp::SimdLoopOp>, RegionOpConversion<omp::SingleOp>, - RegionOpConversion<omp::TaskGroupOp>, RegionOpConversion<omp::TaskOp>, - RegionOpConversion<omp::DataOp>, RegionOpConversion<omp::TargetOp>, + RegionOpConversion<omp::TaskgroupOp>, RegionOpConversion<omp::TaskOp>, + RegionOpConversion<omp::TargetDataOp>, RegionOpConversion<omp::TargetOp>, RegionLessOpWithVarOperandsConversion<omp::AtomicWriteOp>, RegionOpWithVarOperandsConversion<omp::AtomicUpdateOp>, RegionLessOpWithVarOperandsConversion<omp::FlushOp>, RegionLessOpWithVarOperandsConversion<omp::ThreadprivateOp>, RegionLessOpConversion<omp::YieldOp>, - RegionLessOpConversion<omp::EnterDataOp>, - RegionLessOpConversion<omp::ExitDataOp>, - RegionLessOpConversion<omp::UpdateDataOp>, - RegionLessOpWithVarOperandsConversion<omp::DataBoundsOp>>(converter); + RegionLessOpConversion<omp::TargetEnterDataOp>, + RegionLessOpConversion<omp::TargetExitDataOp>, + RegionLessOpConversion<omp::TargetUpdateOp>, + RegionLessOpWithVarOperandsConversion<omp::MapBoundsOp>>(converter); } namespace { diff --git a/mlir/lib/Conversion/SCFToOpenMP/SCFToOpenMP.cpp b/mlir/lib/Conversion/SCFToOpenMP/SCFToOpenMP.cpp index 464a647564ac..7f91367ad427 100644 --- a/mlir/lib/Conversion/SCFToOpenMP/SCFToOpenMP.cpp +++ b/mlir/lib/Conversion/SCFToOpenMP/SCFToOpenMP.cpp @@ -183,12 +183,12 @@ static Attribute minMaxValueForUnsignedInt(Type type, bool min) { /// symbol table. The declaration has a constant initializer with the neutral /// value `initValue`, and the `reductionIndex`-th reduction combiner carried /// over from `reduce`. -static omp::ReductionDeclareOp +static omp::DeclareReductionOp createDecl(PatternRewriter &builder, SymbolTable &symbolTable, scf::ReduceOp reduce, int64_t reductionIndex, Attribute initValue) { OpBuilder::InsertionGuard guard(builder); Type type = reduce.getOperands()[reductionIndex].getType(); - auto decl = builder.create<omp::ReductionDeclareOp>(reduce.getLoc(), + auto decl = builder.create<omp::DeclareReductionOp>(reduce.getLoc(), "__scf_reduction", type); symbolTable.insert(decl); @@ -215,9 +215,9 @@ createDecl(PatternRewriter &builder, SymbolTable &symbolTable, /// Adds an atomic reduction combiner to the given OpenMP reduction declaration /// using llvm.atomicrmw of the given kind. -static omp::ReductionDeclareOp addAtomicRMW(OpBuilder &builder, +static omp::DeclareReductionOp addAtomicRMW(OpBuilder &builder, LLVM::AtomicBinOp atomicKind, - omp::ReductionDeclareOp decl, + omp::DeclareReductionOp decl, scf::ReduceOp reduce, int64_t reductionIndex) { OpBuilder::InsertionGuard guard(builder); @@ -241,7 +241,7 @@ static omp::ReductionDeclareOp addAtomicRMW(OpBuilder &builder, /// reduction and returns it. Recognizes common reductions in order to identify /// the neutral value, necessary for the OpenMP declaration. If the reduction /// cannot be recognized, returns null. -static omp::ReductionDeclareOp declareReduction(PatternRewriter &builder, +static omp::DeclareReductionOp declareReduction(PatternRewriter &builder, scf::ReduceOp reduce, int64_t reductionIndex) { Operation *container = SymbolTable::getNearestSymbolTable(reduce); @@ -262,35 +262,35 @@ static omp::ReductionDeclareOp declareReduction(PatternRewriter &builder, Type type = reduce.getOperands()[reductionIndex].getType(); Block &reduction = reduce.getReductions()[reductionIndex].front(); if (matchSimpleReduction<arith::AddFOp, LLVM::FAddOp>(reduction)) { - omp::ReductionDeclareOp decl = + omp::DeclareReductionOp decl = createDecl(builder, symbolTable, reduce, reductionIndex, builder.getFloatAttr(type, 0.0)); return addAtomicRMW(builder, LLVM::AtomicBinOp::fadd, decl, reduce, reductionIndex); } if (matchSimpleReduction<arith::AddIOp, LLVM::AddOp>(reduction)) { - omp::ReductionDeclareOp decl = + omp::DeclareReductionOp decl = createDecl(builder, symbolTable, reduce, reductionIndex, builder.getIntegerAttr(type, 0)); return addAtomicRMW(builder, LLVM::AtomicBinOp::add, decl, reduce, reductionIndex); } if (matchSimpleReduction<arith::OrIOp, LLVM::OrOp>(reduction)) { - omp::ReductionDeclareOp decl = + omp::DeclareReductionOp decl = createDecl(builder, symbolTable, reduce, reductionIndex, builder.getIntegerAttr(type, 0)); return addAtomicRMW(builder, LLVM::AtomicBinOp::_or, decl, reduce, reductionIndex); } if (matchSimpleReduction<arith::XOrIOp, LLVM::XOrOp>(reduction)) { - omp::ReductionDeclareOp decl = + omp::DeclareReductionOp decl = createDecl(builder, symbolTable, reduce, reductionIndex, builder.getIntegerAttr(type, 0)); return addAtomicRMW(builder, LLVM::AtomicBinOp::_xor, decl, reduce, reductionIndex); } if (matchSimpleReduction<arith::AndIOp, LLVM::AndOp>(reduction)) { - omp::ReductionDeclareOp decl = createDecl( + omp::DeclareReductionOp decl = createDecl( builder, symbolTable, reduce, reductionIndex, builder.getIntegerAttr( type, llvm::APInt::getAllOnes(type.getIntOrFloatBitWidth()))); @@ -327,7 +327,7 @@ static omp::ReductionDeclareOp declareReduction(PatternRewriter &builder, matchSelectReduction<LLVM::ICmpOp, LLVM::SelectOp>( reduction, {LLVM::ICmpPredicate::slt, LLVM::ICmpPredicate::sle}, {LLVM::ICmpPredicate::sgt, LLVM::ICmpPredicate::sge}, isMin)) { - omp::ReductionDeclareOp decl = + omp::DeclareReductionOp decl = createDecl(builder, symbolTable, reduce, reductionIndex, minMaxValueForSignedInt(type, !isMin)); return addAtomicRMW(builder, @@ -340,7 +340,7 @@ static omp::ReductionDeclareOp declareReduction(PatternRewriter &builder, matchSelectReduction<LLVM::ICmpOp, LLVM::SelectOp>( reduction, {LLVM::ICmpPredicate::ugt, LLVM::ICmpPredicate::ule}, {LLVM::ICmpPredicate::ugt, LLVM::ICmpPredicate::uge}, isMin)) { - omp::ReductionDeclareOp decl = + omp::DeclareReductionOp decl = createDecl(builder, symbolTable, reduce, reductionIndex, minMaxValueForUnsignedInt(type, !isMin)); return addAtomicRMW( @@ -367,10 +367,10 @@ struct ParallelOpLowering : public OpRewritePattern<scf::ParallelOp> { // TODO: consider checking it here is already a compatible reduction // declaration and use it instead of redeclaring. SmallVector<Attribute> reductionDeclSymbols; - SmallVector<omp::ReductionDeclareOp> ompReductionDecls; + SmallVector<omp::DeclareReductionOp> ompReductionDecls; auto reduce = cast<scf::ReduceOp>(parallelOp.getBody()->getTerminator()); for (int64_t i = 0, e = parallelOp.getNumReductions(); i < e; ++i) { - omp::ReductionDeclareOp decl = declareReduction(rewriter, reduce, i); + omp::DeclareReductionOp decl = declareReduction(rewriter, reduce, i); ompReductionDecls.push_back(decl); if (!decl) return failure(); @@ -461,7 +461,7 @@ struct ParallelOpLowering : public OpRewritePattern<scf::ParallelOp> { // Replace the loop. { OpBuilder::InsertionGuard allocaGuard(rewriter); - auto loop = rewriter.create<omp::WsLoopOp>( + auto loop = rewriter.create<omp::WsloopOp>( parallelOp.getLoc(), parallelOp.getLowerBound(), parallelOp.getUpperBound(), parallelOp.getStep()); rewriter.create<omp::TerminatorOp>(loc); diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp index e7b899aec4af..bf5875071e0d 100644 --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -592,7 +592,7 @@ static LogicalResult verifyReductionVarList(Operation *op, Type varType = accum.getType(); auto symbolRef = llvm::cast<SymbolRefAttr>(std::get<1>(args)); auto decl = - SymbolTable::lookupNearestSymbolFrom<ReductionDeclareOp>(op, symbolRef); + SymbolTable::lookupNearestSymbolFrom<DeclareReductionOp>(op, symbolRef); if (!decl) return op->emitOpError() << "expected symbol reference " << symbolRef << " to point to a reduction declaration"; @@ -1112,18 +1112,18 @@ static LogicalResult verifyMapClause(Operation *op, OperandRange mapOperands) { bool implicit = mapTypeToBitFlag( mapTypeBits, llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT); - if ((isa<DataOp>(op) || isa<TargetOp>(op)) && del) + if ((isa<TargetDataOp>(op) || isa<TargetOp>(op)) && del) return emitError(op->getLoc(), "to, from, tofrom and alloc map types are permitted"); - if (isa<EnterDataOp>(op) && (from || del)) + if (isa<TargetEnterDataOp>(op) && (from || del)) return emitError(op->getLoc(), "to and alloc map types are permitted"); - if (isa<ExitDataOp>(op) && to) + if (isa<TargetExitDataOp>(op) && to) return emitError(op->getLoc(), "from, release and delete map types are permitted"); - if (isa<UpdateDataOp>(op)) { + if (isa<TargetUpdateOp>(op)) { if (del) { return emitError(op->getLoc(), "at least one of to or from map types must be " @@ -1161,7 +1161,7 @@ static LogicalResult verifyMapClause(Operation *op, OperandRange mapOperands) { return success(); } -LogicalResult DataOp::verify() { +LogicalResult TargetDataOp::verify() { if (getMapOperands().empty() && getUseDevicePtr().empty() && getUseDeviceAddr().empty()) { return ::emitError(this->getLoc(), "At least one of map, useDevicePtr, or " @@ -1170,21 +1170,21 @@ LogicalResult DataOp::verify() { return verifyMapClause(*this, getMapOperands()); } -LogicalResult EnterDataOp::verify() { +LogicalResult TargetEnterDataOp::verify() { LogicalResult verifyDependVars = verifyDependVarList(*this, getDepends(), getDependVars()); return failed(verifyDependVars) ? verifyDependVars : verifyMapClause(*this, getMapOperands()); } -LogicalResult ExitDataOp::verify() { +LogicalResult TargetExitDataOp::verify() { LogicalResult verifyDependVars = verifyDependVarList(*this, getDepends(), getDependVars()); return failed(verifyDependVars) ? verifyDependVars : verifyMapClause(*this, getMapOperands()); } -LogicalResult UpdateDataOp::verify() { +LogicalResult TargetUpdateOp::verify() { LogicalResult verifyDependVars = verifyDependVarList(*this, getDepends(), getDependVars()); return failed(verifyDependVars) ? verifyDependVars @@ -1345,14 +1345,14 @@ LogicalResult SingleOp::verify() { } //===----------------------------------------------------------------------===// -// WsLoopOp +// WsloopOp //===----------------------------------------------------------------------===// /// loop-control ::= `(` ssa-id-list `)` `:` type `=` loop-bounds /// loop-bounds := `(` ssa-id-list `)` to `(` ssa-id-list `)` inclusive? steps /// steps := `step` `(`ssa-id-list`)` ParseResult -parseWsLoop(OpAsmParser &parser, Region ®ion, +parseWsloop(OpAsmParser &parser, Region ®ion, SmallVectorImpl<OpAsmParser::UnresolvedOperand> &lowerBound, SmallVectorImpl<OpAsmParser::UnresolvedOperand> &upperBound, SmallVectorImpl<OpAsmParser::UnresolvedOperand> &steps, @@ -1405,7 +1405,7 @@ parseWsLoop(OpAsmParser &parser, Region ®ion, return parser.parseRegion(region, regionArgs); } -void printWsLoop(OpAsmPrinter &p, Operation *op, Region ®ion, +void printWsloop(OpAsmPrinter &p, Operation *op, Region ®ion, ValueRange lowerBound, ValueRange upperBound, ValueRange steps, TypeRange loopVarTypes, ValueRange reductionOperands, TypeRange reductionTypes, ArrayAttr reductionSymbols, @@ -1531,14 +1531,14 @@ static ParseResult parseAtomicReductionRegion(OpAsmParser &parser, } static void printAtomicReductionRegion(OpAsmPrinter &printer, - ReductionDeclareOp op, Region ®ion) { + DeclareReductionOp op, Region ®ion) { if (region.empty()) return; printer << "atomic "; printer.printRegion(region); } -LogicalResult ReductionDeclareOp::verifyRegions() { +LogicalResult DeclareReductionOp::verifyRegions() { if (getInitializerRegion().empty()) return emitOpError() << "expects non-empty initializer region"; Block &initializerEntryBlock = getInitializerRegion().front(); @@ -1617,17 +1617,17 @@ LogicalResult TaskOp::verify() { } //===----------------------------------------------------------------------===// -// TaskGroupOp +// TaskgroupOp //===----------------------------------------------------------------------===// -LogicalResult TaskGroupOp::verify() { +LogicalResult TaskgroupOp::verify() { return verifyReductionVarList(*this, getTaskReductions(), getTaskReductionVars()); } //===----------------------------------------------------------------------===// -// TaskLoopOp +// TaskloopOp //===----------------------------------------------------------------------===// -SmallVector<Value> TaskLoopOp::getAllReductionVars() { +SmallVector<Value> TaskloopOp::getAllReductionVars() { SmallVector<Value> allReductionNvars(getInReductionVars().begin(), getInReductionVars().end()); allReductionNvars.insert(allReductionNvars.end(), getReductionVars().begin(), @@ -1635,7 +1635,7 @@ SmallVector<Value> TaskLoopOp::getAllReductionVars() { return allReductionNvars; } -LogicalResult TaskLoopOp::verify() { +LogicalResult TaskloopOp::verify() { if (getAllocateVars().size() != getAllocatorsVars().size()) return emitError( "expected equal sizes for allocate and allocator variables"); @@ -1663,10 +1663,10 @@ LogicalResult TaskLoopOp::verify() { } //===----------------------------------------------------------------------===// -// WsLoopOp +// WsloopOp //===----------------------------------------------------------------------===// -void WsLoopOp::build(OpBuilder &builder, OperationState &state, +void WsloopOp::build(OpBuilder &builder, OperationState &state, ValueRange lowerBound, ValueRange upperBound, ValueRange step, ArrayRef<NamedAttribute> attributes) { build(builder, state, lowerBound, upperBound, step, @@ -1680,7 +1680,7 @@ void WsLoopOp::build(OpBuilder &builder, OperationState &state, state.addAttributes(attributes); } -LogicalResult WsLoopOp::verify() { +LogicalResult WsloopOp::verify() { return verifyReductionVarList(*this, getReductions(), getReductionVars()); } @@ -1711,7 +1711,7 @@ LogicalResult CriticalOp::verifySymbolUses(SymbolTableCollection &symbolTable) { //===----------------------------------------------------------------------===// LogicalResult OrderedOp::verify() { - auto container = (*this)->getParentOfType<WsLoopOp>(); + auto container = (*this)->getParentOfType<WsloopOp>(); if (!container || !container.getOrderedValAttr() || container.getOrderedValAttr().getInt() == 0) return emitOpError() << "ordered depend directive must be closely " @@ -1731,7 +1731,7 @@ LogicalResult OrderedRegionOp::verify() { if (getSimd()) return failure(); - if (auto container = (*this)->getParentOfType<WsLoopOp>()) { + if (auto container = (*this)->getParentOfType<WsloopOp>()) { if (!container.getOrderedValAttr() || container.getOrderedValAttr().getInt() != 0) return emitOpError() << "ordered region must be closely nested inside " @@ -1874,15 +1874,15 @@ LogicalResult CancelOp::verify() { << "inside a parallel region"; } if (cct == ClauseCancellationConstructType::Loop) { - if (!isa<WsLoopOp>(parentOp)) { + if (!isa<WsloopOp>(parentOp)) { return emitOpError() << "cancel loop must appear " << "inside a worksharing-loop region"; } - if (cast<WsLoopOp>(parentOp).getNowaitAttr()) { + if (cast<WsloopOp>(parentOp).getNowaitAttr()) { return emitError() << "A worksharing construct that is canceled " << "must not have a nowait clause"; } - if (cast<WsLoopOp>(parentOp).getOrderedValAttr()) { + if (cast<WsloopOp>(parentOp).getOrderedValAttr()) { return emitError() << "A worksharing construct that is canceled " << "must not have an ordered clause"; } @@ -1920,7 +1920,7 @@ LogicalResult CancellationPointOp::verify() { << "inside a parallel region"; } if ((cct == ClauseCancellationConstructType::Loop) && - !isa<WsLoopOp>(parentOp)) { + !isa<WsloopOp>(parentOp)) { return emitOpError() << "cancellation point loop must appear " << "inside a worksharing-loop region"; } @@ -1934,10 +1934,10 @@ LogicalResult CancellationPointOp::verify() { } //===----------------------------------------------------------------------===// -// DataBoundsOp +// MapBoundsOp //===----------------------------------------------------------------------===// -LogicalResult DataBoundsOp::verify() { +LogicalResult MapBoundsOp::verify() { auto extent = getExtent(); auto upperbound = getUpperBound(); if (!extent && !upperbound) diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp index 5027f2afe921..7df33470ea06 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -331,10 +331,10 @@ convertOmpCritical(Operation &opInst, llvm::IRBuilderBase &builder, /// Returns a reduction declaration that corresponds to the given reduction /// operation in the given container. Currently only supports reductions inside -/// WsLoopOp and ParallelOp but can be easily extended as long as the given +/// WsloopOp and ParallelOp but can be easily extended as long as the given /// construct implements getNumReductionVars. template <typename T> -static std::optional<omp::ReductionDeclareOp> +static std::optional<omp::DeclareReductionOp> findReductionDeclInContainer(T container, omp::ReductionOp reduction) { for (unsigned i = 0, e = container.getNumReductionVars(); i < e; ++i) { if (container.getReductionVars()[i] != reduction.getAccumulator()) @@ -343,7 +343,7 @@ findReductionDeclInContainer(T container, omp::ReductionOp reduction) { SymbolRefAttr reductionSymbol = cast<SymbolRefAttr>((*container.getReductions())[i]); auto declareOp = - SymbolTable::lookupNearestSymbolFrom<omp::ReductionDeclareOp>( + SymbolTable::lookupNearestSymbolFrom<omp::DeclareReductionOp>( container, reductionSymbol); return declareOp; } @@ -352,16 +352,16 @@ findReductionDeclInContainer(T container, omp::ReductionOp reduction) { /// Searches for a reduction in a provided region and the regions /// it is nested in -static omp::ReductionDeclareOp findReductionDecl(Operation &containerOp, +static omp::DeclareReductionOp findReductionDecl(Operation &containerOp, omp::ReductionOp reduction) { - std::optional<omp::ReductionDeclareOp> declareOp = std::nullopt; + std::optional<omp::DeclareReductionOp> declareOp = std::nullopt; Operation *container = &containerOp; while (!declareOp.has_value() && container) { // Check if current container is supported for reductions searches if (auto par = dyn_cast<omp::ParallelOp>(*container)) { declareOp = findReductionDeclInContainer(par, reduction); - } else if (auto loop = dyn_cast<omp::WsLoopOp>(*container)) { + } else if (auto loop = dyn_cast<omp::WsloopOp>(*container)) { declareOp = findReductionDeclInContainer(loop, reduction); } else { break; @@ -381,7 +381,7 @@ static omp::ReductionDeclareOp findReductionDecl(Operation &containerOp, template <typename T> static void collectReductionDecls(T loop, - SmallVectorImpl<omp::ReductionDeclareOp> &reductions) { + SmallVectorImpl<omp::DeclareReductionOp> &reductions) { std::optional<ArrayAttr> attr = loop.getReductions(); if (!attr) return; @@ -389,7 +389,7 @@ collectReductionDecls(T loop, reductions.reserve(reductions.size() + loop.getNumReductionVars()); for (auto symbolRef : attr->getAsRange<SymbolRefAttr>()) { reductions.push_back( - SymbolTable::lookupNearestSymbolFrom<omp::ReductionDeclareOp>( + SymbolTable::lookupNearestSymbolFrom<omp::DeclareReductionOp>( loop, symbolRef)); } } @@ -466,7 +466,7 @@ using OwningAtomicReductionGen = /// reduction declaration. The generator uses `builder` but ignores its /// insertion point. static OwningReductionGen -makeReductionGen(omp::ReductionDeclareOp decl, llvm::IRBuilderBase &builder, +makeReductionGen(omp::DeclareReductionOp decl, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) { // The lambda is mutable because we need access to non-const methods of decl // (which aren't actually mutating it), and we must capture decl by-value to @@ -496,7 +496,7 @@ makeReductionGen(omp::ReductionDeclareOp decl, llvm::IRBuilderBase &builder, /// insertion point. Returns null if there is no atomic region available in the /// reduction declaration. static OwningAtomicReductionGen -makeAtomicReductionGen(omp::ReductionDeclareOp decl, +makeAtomicReductionGen(omp::DeclareReductionOp decl, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) { if (decl.getAtomicReductionRegion().empty()) @@ -783,7 +783,7 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder, /// Converts an OpenMP taskgroup construct into LLVM IR using OpenMPIRBuilder. static LogicalResult -convertOmpTaskgroupOp(omp::TaskGroupOp tgOp, llvm::IRBuilderBase &builder, +convertOmpTaskgroupOp(omp::TaskgroupOp tgOp, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) { using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; LogicalResult bodyGenStatus = success(); @@ -808,7 +808,7 @@ static void allocByValReductionVars(T loop, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation, llvm::OpenMPIRBuilder::InsertPointTy &allocaIP, - SmallVector<omp::ReductionDeclareOp> &reductionDecls, + SmallVector<omp::DeclareReductionOp> &reductionDecls, SmallVector<llvm::Value *> &privateReductionVariables, DenseMap<Value, llvm::Value *> &reductionVariableMap) { llvm::IRBuilderBase::InsertPointGuard guard(builder); @@ -830,7 +830,7 @@ template <typename T> static void collectReductionInfo( T loop, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation, - SmallVector<omp::ReductionDeclareOp> &reductionDecls, + SmallVector<omp::DeclareReductionOp> &reductionDecls, SmallVector<OwningReductionGen> &owningReductionGens, SmallVector<OwningAtomicReductionGen> &owningAtomicReductionGens, const SmallVector<llvm::Value *> &privateReductionVariables, @@ -860,9 +860,9 @@ static void collectReductionInfo( /// Converts an OpenMP workshare loop into LLVM IR using OpenMPIRBuilder. static LogicalResult -convertOmpWsLoop(Operation &opInst, llvm::IRBuilderBase &builder, +convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) { - auto loop = cast<omp::WsLoopOp>(opInst); + auto loop = cast<omp::WsloopOp>(opInst); const bool isByRef = loop.getByref(); // TODO: this should be in the op verifier instead. if (loop.getLowerBound().empty()) @@ -882,7 +882,7 @@ convertOmpWsLoop(Operation &opInst, llvm::IRBuilderBase &builder, chunk = builder.CreateSExtOrTrunc(chunkVar, ivType); } - SmallVector<omp::ReductionDeclareOp> reductionDecls; + SmallVector<omp::DeclareReductionOp> reductionDecls; collectReductionDecls(loop, reductionDecls); llvm::OpenMPIRBuilder::InsertPointTy allocaIP = findAllocaInsertPoint(builder, moduleTranslation); @@ -962,9 +962,9 @@ convertOmpWsLoop(Operation &opInst, llvm::IRBuilderBase &builder, }; // Delegate actual loop construction to the OpenMP IRBuilder. - // TODO: this currently assumes WsLoop is semantically similar to SCF loop, + // TODO: this currently assumes Wsloop is semantically similar to SCF loop, // i.e. it has a positive step, uses signed integer semantics. Reconsider - // this code when WsLoop clearly supports more cases. + // this code when Wsloop clearly supports more cases. llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder(); for (unsigned i = 0, e = loop.getNumLoops(); i < e; ++i) { llvm::Value *lowerBound = @@ -1099,7 +1099,7 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder, auto bodyGenCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) { // Collect reduction declarations - SmallVector<omp::ReductionDeclareOp> reductionDecls; + SmallVector<omp::DeclareReductionOp> reductionDecls; collectReductionDecls(opInst, reductionDecls); // Allocate reduction vars @@ -1653,16 +1653,16 @@ convertOmpAtomicCapture(omp::AtomicCaptureOp atomicCaptureOp, /// Converts an OpenMP reduction operation using OpenMPIRBuilder. Expects the /// mapping between reduction variables and their private equivalents to have /// been stored on the ModuleTranslation stack. Currently only supports -/// reduction within WsLoopOp and ParallelOp, but can be easily extended. +/// reduction within WsloopOp and ParallelOp, but can be easily extended. static LogicalResult convertOmpReductionOp(omp::ReductionOp reductionOp, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) { // Find the declaration that corresponds to the reduction op. - omp::ReductionDeclareOp declaration; + omp::DeclareReductionOp declaration; Operation *reductionParent = reductionOp->getParentOp(); if (dyn_cast<omp::ParallelOp>(reductionParent) || - dyn_cast<omp::WsLoopOp>(reductionParent)) { + dyn_cast<omp::WsloopOp>(reductionParent)) { declaration = findReductionDecl(*reductionParent, reductionOp); } else { llvm_unreachable("Unhandled reduction container"); @@ -1894,7 +1894,7 @@ llvm::Value *getSizeInBytes(DataLayout &dl, const mlir::Type &type, if (!memberClause.getBounds().empty()) { llvm::Value *elementCount = builder.getInt64(1); for (auto bounds : memberClause.getBounds()) { - if (auto boundOp = mlir::dyn_cast_if_present<mlir::omp::DataBoundsOp>( + if (auto boundOp = mlir::dyn_cast_if_present<mlir::omp::MapBoundsOp>( bounds.getDefiningOp())) { // The below calculation for the size to be mapped calculated from the // map_info's bounds is: (elemCount * [UB - LB] + 1), later we @@ -2098,7 +2098,7 @@ static void processMapMembersWithParent( if (!memberClause.getBounds().empty()) { if (mapData.BaseType[memberDataIdx]->isArrayTy()) { for (int i = memberClause.getBounds().size() - 1; i >= 0; --i) { - if (auto boundOp = mlir::dyn_cast_if_present<mlir::omp::DataBoundsOp>( + if (auto boundOp = mlir::dyn_cast_if_present<mlir::omp::MapBoundsOp>( memberClause.getBounds()[i].getDefiningOp())) { idx.push_back( moduleTranslation.lookupValue(boundOp.getLowerBound())); @@ -2108,7 +2108,7 @@ static void processMapMembersWithParent( std::vector<llvm::Value *> dimensionIndexSizeOffset{ builder.getInt64(1)}; for (size_t i = 1; i < memberClause.getBounds().size(); ++i) { - if (auto boundOp = mlir::dyn_cast_if_present<mlir::omp::DataBoundsOp>( + if (auto boundOp = mlir::dyn_cast_if_present<mlir::omp::MapBoundsOp>( memberClause.getBounds()[i].getDefiningOp())) { dimensionIndexSizeOffset.push_back(builder.CreateMul( moduleTranslation.lookupValue(boundOp.getExtent()), @@ -2117,7 +2117,7 @@ static void processMapMembersWithParent( } for (int i = memberClause.getBounds().size() - 1; i >= 0; --i) { - if (auto boundOp = mlir::dyn_cast_if_present<mlir::omp::DataBoundsOp>( + if (auto boundOp = mlir::dyn_cast_if_present<mlir::omp::MapBoundsOp>( memberClause.getBounds()[i].getDefiningOp())) { if (!offsetAddress) offsetAddress = builder.CreateMul( @@ -2279,7 +2279,7 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder, LogicalResult result = llvm::TypeSwitch<Operation *, LogicalResult>(op) - .Case([&](omp::DataOp dataOp) { + .Case([&](omp::TargetDataOp dataOp) { if (auto ifExprVar = dataOp.getIfExpr()) ifCond = moduleTranslation.lookupValue(ifExprVar); @@ -2294,7 +2294,7 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder, useDevAddrOperands = dataOp.getUseDeviceAddr(); return success(); }) - .Case([&](omp::EnterDataOp enterDataOp) { + .Case([&](omp::TargetEnterDataOp enterDataOp) { if (enterDataOp.getNowait()) return (LogicalResult)(enterDataOp.emitError( "`nowait` is not supported yet")); @@ -2311,7 +2311,7 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder, mapOperands = enterDataOp.getMapOperands(); return success(); }) - .Case([&](omp::ExitDataOp exitDataOp) { + .Case([&](omp::TargetExitDataOp exitDataOp) { if (exitDataOp.getNowait()) return (LogicalResult)(exitDataOp.emitError( "`nowait` is not supported yet")); @@ -2329,7 +2329,7 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder, mapOperands = exitDataOp.getMapOperands(); return success(); }) - .Case([&](omp::UpdateDataOp updateDataOp) { + .Case([&](omp::TargetUpdateOp updateDataOp) { if (updateDataOp.getNowait()) return (LogicalResult)(updateDataOp.emitError( "`nowait` is not supported yet")); @@ -2366,7 +2366,7 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder, auto genMapInfoCB = [&](InsertPointTy codeGenIP) -> llvm::OpenMPIRBuilder::MapInfosTy & { builder.restoreIP(codeGenIP); - if (auto dataOp = dyn_cast<omp::DataOp>(op)) { + if (auto dataOp = dyn_cast<omp::TargetDataOp>(op)) { genMapInfos(builder, moduleTranslation, DL, combinedInfo, mapData, useDevPtrOperands, useDevAddrOperands); } else { @@ -2381,8 +2381,9 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder, using BodyGenTy = llvm::OpenMPIRBuilder::BodyGenTy; LogicalResult bodyGenStatus = success(); auto bodyGenCB = [&](InsertPointTy codeGenIP, BodyGenTy bodyGenType) { - assert(isa<omp::DataOp>(op) && "BodyGen requested for non DataOp"); - Region ®ion = cast<omp::DataOp>(op).getRegion(); + assert(isa<omp::TargetDataOp>(op) && + "BodyGen requested for non TargetDataOp"); + Region ®ion = cast<omp::TargetDataOp>(op).getRegion(); switch (bodyGenType) { case BodyGenTy::Priv: // Check if any device ptr/addr info is available @@ -2427,7 +2428,7 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder, llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder); llvm::OpenMPIRBuilder::InsertPointTy allocaIP = findAllocaInsertPoint(builder, moduleTranslation); - if (isa<omp::DataOp>(op)) { + if (isa<omp::TargetDataOp>(op)) { builder.restoreIP(ompBuilder->createTargetData( ompLoc, allocaIP, builder.saveIP(), builder.getInt64(deviceID), ifCond, info, genMapInfoCB, nullptr, bodyGenCB)); @@ -2698,7 +2699,7 @@ createAlteredByCaptureMap(MapInfoData &mapData, std::vector<llvm::Value *>{builder.getInt64(0)}; for (int i = mapOp.getBounds().size() - 1; i >= 0; --i) { if (auto boundOp = - mlir::dyn_cast_if_present<mlir::omp::DataBoundsOp>( + mlir::dyn_cast_if_present<mlir::omp::MapBoundsOp>( mapOp.getBounds()[i].getDefiningOp())) { idx.push_back( moduleTranslation.lookupValue(boundOp.getLowerBound())); @@ -3132,8 +3133,8 @@ LogicalResult OpenMPDialectLLVMIRTranslationInterface::convertOperation( .Case([&](omp::OrderedOp) { return convertOmpOrdered(*op, builder, moduleTranslation); }) - .Case([&](omp::WsLoopOp) { - return convertOmpWsLoop(*op, builder, moduleTranslation); + .Case([&](omp::WsloopOp) { + return convertOmpWsloop(*op, builder, moduleTranslation); }) .Case([&](omp::SimdLoopOp) { return convertOmpSimdLoop(*op, builder, moduleTranslation); @@ -3162,14 +3163,14 @@ LogicalResult OpenMPDialectLLVMIRTranslationInterface::convertOperation( .Case([&](omp::TaskOp op) { return convertOmpTaskOp(op, builder, moduleTranslation); }) - .Case([&](omp::TaskGroupOp op) { + .Case([&](omp::TaskgroupOp op) { return convertOmpTaskgroupOp(op, builder, moduleTranslation); }) - .Case<omp::YieldOp, omp::TerminatorOp, omp::ReductionDeclareOp, + .Case<omp::YieldOp, omp::TerminatorOp, omp::DeclareReductionOp, omp::CriticalDeclareOp>([](auto op) { // `yield` and `terminator` can be just omitted. The block structure // was created in the region that handles their parent operation. - // `reduction.declare` will be used by reductions and is not + // `declare_reduction` will be used by reductions and is not // converted directly, skip it. // `critical.declare` is only used to declare names of critical // sections which will be used by `critical` ops and hence can be @@ -3180,18 +3181,18 @@ LogicalResult OpenMPDialectLLVMIRTranslationInterface::convertOperation( .Case([&](omp::ThreadprivateOp) { return convertOmpThreadprivate(*op, builder, moduleTranslation); }) - .Case<omp::DataOp, omp::EnterDataOp, omp::ExitDataOp, omp::UpdateDataOp>( - [&](auto op) { - return convertOmpTargetData(op, builder, moduleTranslation); - }) + .Case<omp::TargetDataOp, omp::TargetEnterDataOp, omp::TargetExitDataOp, + omp::TargetUpdateOp>([&](auto op) { + return convertOmpTargetData(op, builder, moduleTranslation); + }) .Case([&](omp::TargetOp) { return convertOmpTarget(*op, builder, moduleTranslation); }) - .Case<omp::MapInfoOp, omp::DataBoundsOp, omp::PrivateClauseOp>( + .Case<omp::MapInfoOp, omp::MapBoundsOp, omp::PrivateClauseOp>( [&](auto op) { // No-op, should be handled by relevant owning operations e.g. - // TargetOp, EnterDataOp, ExitDataOp, DataOp etc. and then - // discarded + // TargetOp, TargetEnterDataOp, TargetExitDataOp, TargetDataOp etc. + // and then discarded return success(); }) .Default([&](Operation *inst) { diff --git a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir index 6cbc0c8f4be9..dc5d6969ca78 100644 --- a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir +++ b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir @@ -193,25 +193,25 @@ func.func @task_depend(%arg0: !llvm.ptr) { // CHECK-LABEL: @_QPomp_target_data // CHECK: (%[[ARG0:.*]]: !llvm.ptr, %[[ARG1:.*]]: !llvm.ptr, %[[ARG2:.*]]: !llvm.ptr, %[[ARG3:.*]]: !llvm.ptr) -// CHECK: %[[MAP0:.*]] = omp.map_info var_ptr(%[[ARG0]] : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} -// CHECK: %[[MAP1:.*]] = omp.map_info var_ptr(%[[ARG1]] : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} -// CHECK: %[[MAP2:.*]] = omp.map_info var_ptr(%[[ARG2]] : !llvm.ptr, i32) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) -> !llvm.ptr {name = ""} +// CHECK: %[[MAP0:.*]] = omp.map.info var_ptr(%[[ARG0]] : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} +// CHECK: %[[MAP1:.*]] = omp.map.info var_ptr(%[[ARG1]] : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} +// CHECK: %[[MAP2:.*]] = omp.map.info var_ptr(%[[ARG2]] : !llvm.ptr, i32) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) -> !llvm.ptr {name = ""} // CHECK: omp.target_enter_data map_entries(%[[MAP0]], %[[MAP1]], %[[MAP2]] : !llvm.ptr, !llvm.ptr, !llvm.ptr) -// CHECK: %[[MAP3:.*]] = omp.map_info var_ptr(%[[ARG0]] : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} -// CHECK: %[[MAP4:.*]] = omp.map_info var_ptr(%[[ARG1]] : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} -// CHECK: %[[MAP5:.*]] = omp.map_info var_ptr(%[[ARG2]] : !llvm.ptr, i32) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> !llvm.ptr {name = ""} -// CHECK: %[[MAP6:.*]] = omp.map_info var_ptr(%[[ARG3]] : !llvm.ptr, i32) map_clauses(always, delete) capture(ByRef) -> !llvm.ptr {name = ""} +// CHECK: %[[MAP3:.*]] = omp.map.info var_ptr(%[[ARG0]] : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} +// CHECK: %[[MAP4:.*]] = omp.map.info var_ptr(%[[ARG1]] : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} +// CHECK: %[[MAP5:.*]] = omp.map.info var_ptr(%[[ARG2]] : !llvm.ptr, i32) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> !llvm.ptr {name = ""} +// CHECK: %[[MAP6:.*]] = omp.map.info var_ptr(%[[ARG3]] : !llvm.ptr, i32) map_clauses(always, delete) capture(ByRef) -> !llvm.ptr {name = ""} // CHECK: omp.target_exit_data map_entries(%[[MAP3]], %[[MAP4]], %[[MAP5]], %[[MAP6]] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) llvm.func @_QPomp_target_data(%a : !llvm.ptr, %b : !llvm.ptr, %c : !llvm.ptr, %d : !llvm.ptr) { - %0 = omp.map_info var_ptr(%a : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} - %1 = omp.map_info var_ptr(%b : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} - %2 = omp.map_info var_ptr(%c : !llvm.ptr, i32) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) -> !llvm.ptr {name = ""} + %0 = omp.map.info var_ptr(%a : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} + %1 = omp.map.info var_ptr(%b : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} + %2 = omp.map.info var_ptr(%c : !llvm.ptr, i32) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) -> !llvm.ptr {name = ""} omp.target_enter_data map_entries(%0, %1, %2 : !llvm.ptr, !llvm.ptr, !llvm.ptr) {} - %3 = omp.map_info var_ptr(%a : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} - %4 = omp.map_info var_ptr(%b : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} - %5 = omp.map_info var_ptr(%c : !llvm.ptr, i32) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> !llvm.ptr {name = ""} - %6 = omp.map_info var_ptr(%d : !llvm.ptr, i32) map_clauses(always, delete) capture(ByRef) -> !llvm.ptr {name = ""} + %3 = omp.map.info var_ptr(%a : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} + %4 = omp.map.info var_ptr(%b : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} + %5 = omp.map.info var_ptr(%c : !llvm.ptr, i32) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> !llvm.ptr {name = ""} + %6 = omp.map.info var_ptr(%d : !llvm.ptr, i32) map_clauses(always, delete) capture(ByRef) -> !llvm.ptr {name = ""} omp.target_exit_data map_entries(%3, %4, %5, %6 : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) {} llvm.return } @@ -220,7 +220,7 @@ llvm.func @_QPomp_target_data(%a : !llvm.ptr, %b : !llvm.ptr, %c : !llvm.ptr, %d // CHECK-LABEL: @_QPomp_target_data_region // CHECK: (%[[ARG0:.*]]: !llvm.ptr, %[[ARG1:.*]]: !llvm.ptr) { -// CHECK: %[[MAP_0:.*]] = omp.map_info var_ptr(%[[ARG0]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} +// CHECK: %[[MAP_0:.*]] = omp.map.info var_ptr(%[[ARG0]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} // CHECK: omp.target_data map_entries(%[[MAP_0]] : !llvm.ptr) { // CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(10 : i32) : i32 // CHECK: llvm.store %[[VAL_1]], %[[ARG1]] : i32, !llvm.ptr @@ -229,7 +229,7 @@ llvm.func @_QPomp_target_data(%a : !llvm.ptr, %b : !llvm.ptr, %c : !llvm.ptr, %d // CHECK: llvm.return llvm.func @_QPomp_target_data_region(%a : !llvm.ptr, %i : !llvm.ptr) { - %1 = omp.map_info var_ptr(%a : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %1 = omp.map.info var_ptr(%a : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} omp.target_data map_entries(%1 : !llvm.ptr) { %2 = llvm.mlir.constant(10 : i32) : i32 llvm.store %2, %i : i32, !llvm.ptr @@ -244,8 +244,8 @@ llvm.func @_QPomp_target_data_region(%a : !llvm.ptr, %i : !llvm.ptr) { // CHECK: %[[ARG_0:.*]]: !llvm.ptr, // CHECK: %[[ARG_1:.*]]: !llvm.ptr) { // CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(64 : i32) : i32 -// CHECK: %[[MAP1:.*]] = omp.map_info var_ptr(%[[ARG_0]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} -// CHECK: %[[MAP2:.*]] = omp.map_info var_ptr(%[[ARG_1]] : !llvm.ptr, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !llvm.ptr {name = ""} +// CHECK: %[[MAP1:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} +// CHECK: %[[MAP2:.*]] = omp.map.info var_ptr(%[[ARG_1]] : !llvm.ptr, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !llvm.ptr {name = ""} // CHECK: omp.target thread_limit(%[[VAL_0]] : i32) map_entries(%[[MAP1]] -> %[[BB_ARG0:.*]], %[[MAP2]] -> %[[BB_ARG1:.*]] : !llvm.ptr, !llvm.ptr) { // CHECK: ^bb0(%[[BB_ARG0]]: !llvm.ptr, %[[BB_ARG1]]: !llvm.ptr): // CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(10 : i32) : i32 @@ -257,8 +257,8 @@ llvm.func @_QPomp_target_data_region(%a : !llvm.ptr, %i : !llvm.ptr) { llvm.func @_QPomp_target(%a : !llvm.ptr, %i : !llvm.ptr) { %0 = llvm.mlir.constant(64 : i32) : i32 - %1 = omp.map_info var_ptr(%a : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} - %3 = omp.map_info var_ptr(%i : !llvm.ptr, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !llvm.ptr {name = ""} + %1 = omp.map.info var_ptr(%a : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %3 = omp.map.info var_ptr(%i : !llvm.ptr, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !llvm.ptr {name = ""} omp.target thread_limit(%0 : i32) map_entries(%1 -> %arg0, %3 -> %arg1 : !llvm.ptr, !llvm.ptr) { ^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr): %2 = llvm.mlir.constant(10 : i32) : i32 @@ -304,7 +304,7 @@ llvm.func @_QPsb() { // ----- -// CHECK: omp.reduction.declare @eqv_reduction : i32 init +// CHECK: omp.declare_reduction @eqv_reduction : i32 init // CHECK: ^bb0(%{{.*}}: i32): // CHECK: %[[TRUE:.*]] = llvm.mlir.constant(true) : i1 // CHECK: %[[TRUE_EXT:.*]] = llvm.zext %[[TRUE]] : i1 to i32 @@ -329,7 +329,7 @@ llvm.func @_QPsb() { // CHECK: omp.terminator // CHECK: llvm.return -omp.reduction.declare @eqv_reduction : i32 init { +omp.declare_reduction @eqv_reduction : i32 init { ^bb0(%arg0: i32): %0 = llvm.mlir.constant(true) : i1 %1 = llvm.zext %0 : i1 to i32 @@ -420,8 +420,8 @@ llvm.func @sub_() { %1 = llvm.mlir.constant(1 : index) : i64 %2 = llvm.mlir.constant(1 : i64) : i64 %3 = llvm.alloca %2 x i32 {bindc_name = "i", in_type = i32, operandSegmentSizes = array<i32: 0, 0>, uniq_name = "_QFsubEi"} : (i64) -> !llvm.ptr -// CHECK: omp.ordered_region - omp.ordered_region { +// CHECK: omp.ordered.region + omp.ordered.region { %4 = llvm.trunc %1 : i64 to i32 llvm.br ^bb1(%4, %1 : i32, i64) ^bb1(%5: i32, %6: i64): // 2 preds: ^bb0, ^bb2 @@ -451,14 +451,14 @@ llvm.func @sub_() { // CHECK: %[[C_02:.*]] = llvm.mlir.constant(1 : index) : i64 // CHECK: %[[C_03:.*]] = llvm.mlir.constant(1 : index) : i64 // CHECK: %[[C_04:.*]] = llvm.mlir.constant(1 : index) : i64 -// CHECK: %[[BOUNDS0:.*]] = omp.bounds lower_bound(%[[C_02]] : i64) upper_bound(%[[C_01]] : i64) stride(%[[C_04]] : i64) start_idx(%[[C_04]] : i64) -// CHECK: %[[MAP0:.*]] = omp.map_info var_ptr(%[[ARG_1]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS0]]) -> !llvm.ptr {name = ""} +// CHECK: %[[BOUNDS0:.*]] = omp.map.bounds lower_bound(%[[C_02]] : i64) upper_bound(%[[C_01]] : i64) stride(%[[C_04]] : i64) start_idx(%[[C_04]] : i64) +// CHECK: %[[MAP0:.*]] = omp.map.info var_ptr(%[[ARG_1]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS0]]) -> !llvm.ptr {name = ""} // CHECK: %[[C_11:.*]] = llvm.mlir.constant(4 : index) : i64 // CHECK: %[[C_12:.*]] = llvm.mlir.constant(1 : index) : i64 // CHECK: %[[C_13:.*]] = llvm.mlir.constant(1 : index) : i64 // CHECK: %[[C_14:.*]] = llvm.mlir.constant(1 : index) : i64 -// CHECK: %[[BOUNDS1:.*]] = omp.bounds lower_bound(%[[C_12]] : i64) upper_bound(%[[C_11]] : i64) stride(%[[C_14]] : i64) start_idx(%[[C_14]] : i64) -// CHECK: %[[MAP1:.*]] = omp.map_info var_ptr(%[[ARG_2]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS1]]) -> !llvm.ptr {name = ""} +// CHECK: %[[BOUNDS1:.*]] = omp.map.bounds lower_bound(%[[C_12]] : i64) upper_bound(%[[C_11]] : i64) stride(%[[C_14]] : i64) start_idx(%[[C_14]] : i64) +// CHECK: %[[MAP1:.*]] = omp.map.info var_ptr(%[[ARG_2]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS1]]) -> !llvm.ptr {name = ""} // CHECK: omp.target map_entries(%[[MAP0]] -> %[[BB_ARG0:.*]], %[[MAP1]] -> %[[BB_ARG1:.*]] : !llvm.ptr, !llvm.ptr) { // CHECK: ^bb0(%[[BB_ARG0]]: !llvm.ptr, %[[BB_ARG1]]: !llvm.ptr): // CHECK: omp.terminator @@ -471,14 +471,14 @@ llvm.func @_QPtarget_map_with_bounds(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: %1 = llvm.mlir.constant(1 : index) : i64 %2 = llvm.mlir.constant(1 : index) : i64 %3 = llvm.mlir.constant(1 : index) : i64 - %4 = omp.bounds lower_bound(%1 : i64) upper_bound(%0 : i64) stride(%3 : i64) start_idx(%3 : i64) - %5 = omp.map_info var_ptr(%arg1 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%4) -> !llvm.ptr {name = ""} + %4 = omp.map.bounds lower_bound(%1 : i64) upper_bound(%0 : i64) stride(%3 : i64) start_idx(%3 : i64) + %5 = omp.map.info var_ptr(%arg1 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%4) -> !llvm.ptr {name = ""} %6 = llvm.mlir.constant(4 : index) : i64 %7 = llvm.mlir.constant(1 : index) : i64 %8 = llvm.mlir.constant(1 : index) : i64 %9 = llvm.mlir.constant(1 : index) : i64 - %10 = omp.bounds lower_bound(%7 : i64) upper_bound(%6 : i64) stride(%9 : i64) start_idx(%9 : i64) - %11 = omp.map_info var_ptr(%arg2 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%10) -> !llvm.ptr {name = ""} + %10 = omp.map.bounds lower_bound(%7 : i64) upper_bound(%6 : i64) stride(%9 : i64) start_idx(%9 : i64) + %11 = omp.map.info var_ptr(%arg2 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%10) -> !llvm.ptr {name = ""} omp.target map_entries(%5 -> %arg3, %11 -> %arg4: !llvm.ptr, !llvm.ptr) { ^bb0(%arg3: !llvm.ptr, %arg4: !llvm.ptr): omp.terminator diff --git a/mlir/test/Conversion/SCFToOpenMP/reductions.mlir b/mlir/test/Conversion/SCFToOpenMP/reductions.mlir index a6704644873f..3b6c145d62f1 100644 --- a/mlir/test/Conversion/SCFToOpenMP/reductions.mlir +++ b/mlir/test/Conversion/SCFToOpenMP/reductions.mlir @@ -1,6 +1,6 @@ // RUN: mlir-opt -convert-scf-to-openmp -split-input-file %s | FileCheck %s -// CHECK: omp.reduction.declare @[[$REDF:.*]] : f32 +// CHECK: omp.declare_reduction @[[$REDF:.*]] : f32 // CHECK: init // CHECK: %[[INIT:.*]] = llvm.mlir.constant(0.000000e+00 : f32) @@ -51,7 +51,7 @@ func.func @reduction1(%arg0 : index, %arg1 : index, %arg2 : index, // ----- // Only check the declaration here, the rest is same as above. -// CHECK: omp.reduction.declare @{{.*}} : f32 +// CHECK: omp.declare_reduction @{{.*}} : f32 // CHECK: init // CHECK: %[[INIT:.*]] = llvm.mlir.constant(1.000000e+00 : f32) @@ -87,7 +87,7 @@ func.func @reduction2(%arg0 : index, %arg1 : index, %arg2 : index, // Mostly, the same check as above, except for the types, // the name of the op and the init value. -// CHECK: omp.reduction.declare @[[$REDI:.*]] : i32 +// CHECK: omp.declare_reduction @[[$REDI:.*]] : i32 // CHECK: init // CHECK: %[[INIT:.*]] = llvm.mlir.constant(1 : i32) @@ -126,7 +126,7 @@ func.func @reduction_muli(%arg0 : index, %arg1 : index, %arg2 : index, // ----- // Only check the declaration here, the rest is same as above. -// CHECK: omp.reduction.declare @{{.*}} : f32 +// CHECK: omp.declare_reduction @{{.*}} : f32 // CHECK: init // CHECK: %[[INIT:.*]] = llvm.mlir.constant(-3.4 @@ -160,7 +160,7 @@ func.func @reduction3(%arg0 : index, %arg1 : index, %arg2 : index, // ----- -// CHECK: omp.reduction.declare @[[$REDF1:.*]] : f32 +// CHECK: omp.declare_reduction @[[$REDF1:.*]] : f32 // CHECK: init // CHECK: %[[INIT:.*]] = llvm.mlir.constant(-3.4 @@ -174,7 +174,7 @@ func.func @reduction3(%arg0 : index, %arg1 : index, %arg2 : index, // CHECK-NOT: atomic -// CHECK: omp.reduction.declare @[[$REDF2:.*]] : i64 +// CHECK: omp.declare_reduction @[[$REDF2:.*]] : i64 // CHECK: init // CHECK: %[[INIT:.*]] = llvm.mlir.constant diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir index d9261b89e24e..a00383cf4405 100644 --- a/mlir/test/Dialect/OpenMP/invalid.mlir +++ b/mlir/test/Dialect/OpenMP/invalid.mlir @@ -338,7 +338,7 @@ func.func @omp_simdloop_pretty_simdlen_safelen(%lb : index, %ub : index, %step : // ----- // expected-error @below {{op expects initializer region with one argument of the reduction type}} -omp.reduction.declare @add_f32 : f64 +omp.declare_reduction @add_f32 : f64 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -353,7 +353,7 @@ combiner { // ----- // expected-error @below {{expects initializer region to yield a value of the reduction type}} -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f64 @@ -368,7 +368,7 @@ combiner { // ----- // expected-error @below {{expects reduction region with two arguments of the reduction type}} -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -383,7 +383,7 @@ combiner { // ----- // expected-error @below {{expects reduction region to yield a value of the reduction type}} -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -399,7 +399,7 @@ combiner { // ----- // expected-error @below {{expects atomic reduction region with two arguments of the same type}} -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -418,7 +418,7 @@ atomic { // ----- // expected-error @below {{expects atomic reduction region arguments to be accumulators containing the reduction type}} -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -453,7 +453,7 @@ func.func @foo(%lb : index, %ub : index, %step : index) { // ----- -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -481,7 +481,7 @@ func.func @foo(%lb : index, %ub : index, %step : index) { // ----- -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -543,7 +543,7 @@ func.func @omp_ordered1(%arg1 : i32, %arg2 : i32, %arg3 : i32) -> () { omp.wsloop ordered(1) for (%0) : i32 = (%arg1) to (%arg2) step (%arg3) { // expected-error @below {{ordered region must be closely nested inside a worksharing-loop region with an ordered clause without parameter present}} - omp.ordered_region { + omp.ordered.region { omp.terminator } omp.yield @@ -556,7 +556,7 @@ func.func @omp_ordered1(%arg1 : i32, %arg2 : i32, %arg3 : i32) -> () { func.func @omp_ordered2(%arg1 : i32, %arg2 : i32, %arg3 : i32) -> () { omp.wsloop for (%0) : i32 = (%arg1) to (%arg2) step (%arg3) { // expected-error @below {{ordered region must be closely nested inside a worksharing-loop region with an ordered clause without parameter present}} - omp.ordered_region { + omp.ordered.region { omp.terminator } omp.yield @@ -1339,7 +1339,7 @@ func.func @omp_task(%ptr: !llvm.ptr) { // ----- -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -1363,7 +1363,7 @@ func.func @omp_task(%ptr: !llvm.ptr) { // ----- -omp.reduction.declare @add_i32 : i32 +omp.declare_reduction @add_i32 : i32 init { ^bb0(%arg: i32): %0 = arith.constant 0 : i32 @@ -1474,7 +1474,7 @@ func.func @omp_cancel5() -> () { func.func @omp_cancellationpoint() { omp.sections { // expected-error @below {{cancellation point parallel must appear inside a parallel region}} - omp.cancellationpoint cancellation_construct_type(parallel) + omp.cancellation_point cancellation_construct_type(parallel) // CHECK: omp.terminator omp.terminator } @@ -1486,7 +1486,7 @@ func.func @omp_cancellationpoint() { func.func @omp_cancellationpoint1() { omp.parallel { // expected-error @below {{cancellation point sections must appear inside a sections region}} - omp.cancellationpoint cancellation_construct_type(sections) + omp.cancellation_point cancellation_construct_type(sections) // CHECK: omp.terminator omp.terminator } @@ -1498,7 +1498,7 @@ func.func @omp_cancellationpoint1() { func.func @omp_cancellationpoint2() { omp.sections { // expected-error @below {{cancellation point loop must appear inside a worksharing-loop region}} - omp.cancellationpoint cancellation_construct_type(loop) + omp.cancellation_point cancellation_construct_type(loop) // CHECK: omp.terminator omp.terminator } @@ -1571,7 +1571,7 @@ func.func @taskloop(%lb: i32, %ub: i32, %step: i32) { // ----- -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -1596,7 +1596,7 @@ func.func @taskloop(%lb: i32, %ub: i32, %step: i32) { // ----- -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -1642,7 +1642,7 @@ func.func @omp_threadprivate() { // ----- func.func @omp_target(%map1: memref<?xi32>) { - %mapv = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(delete) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(delete) capture(ByRef) -> memref<?xi32> {name = ""} // expected-error @below {{to, from, tofrom and alloc map types are permitted}} omp.target map_entries(%mapv -> %arg0: memref<?xi32>) { ^bb0(%arg0: memref<?xi32>): @@ -1653,7 +1653,7 @@ func.func @omp_target(%map1: memref<?xi32>) { // ----- func.func @omp_target_data(%map1: memref<?xi32>) { - %mapv = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(delete) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(delete) capture(ByRef) -> memref<?xi32> {name = ""} // expected-error @below {{to, from, tofrom and alloc map types are permitted}} omp.target_data map_entries(%mapv : memref<?xi32>){} return @@ -1670,7 +1670,7 @@ func.func @omp_target_data() { // ----- func.func @omp_target_enter_data(%map1: memref<?xi32>) { - %mapv = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> {name = ""} // expected-error @below {{to and alloc map types are permitted}} omp.target_enter_data map_entries(%mapv : memref<?xi32>){} return @@ -1679,7 +1679,7 @@ func.func @omp_target_enter_data(%map1: memref<?xi32>) { // ----- func.func @omp_target_enter_data_depend(%a: memref<?xi32>) { - %0 = omp.map_info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> + %0 = omp.map.info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> // expected-error @below {{op expected as many depend values as depend variables}} omp.target_enter_data map_entries(%0: memref<?xi32> ) {operandSegmentSizes = array<i32: 0, 0, 1, 0>} return @@ -1688,7 +1688,7 @@ func.func @omp_target_enter_data_depend(%a: memref<?xi32>) { // ----- func.func @omp_target_exit_data(%map1: memref<?xi32>) { - %mapv = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> {name = ""} // expected-error @below {{from, release and delete map types are permitted}} omp.target_exit_data map_entries(%mapv : memref<?xi32>){} return @@ -1697,7 +1697,7 @@ func.func @omp_target_exit_data(%map1: memref<?xi32>) { // ----- func.func @omp_target_exit_data_depend(%a: memref<?xi32>) { - %0 = omp.map_info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> + %0 = omp.map.info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> // expected-error @below {{op expected as many depend values as depend variables}} omp.target_exit_data map_entries(%0: memref<?xi32> ) {operandSegmentSizes = array<i32: 0, 0, 1, 0>} return @@ -1706,71 +1706,71 @@ func.func @omp_target_exit_data_depend(%a: memref<?xi32>) { // ----- func.func @omp_target_update_invalid_motion_type(%map1 : memref<?xi32>) { - %mapv = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} // expected-error @below {{at least one of to or from map types must be specified, other map types are not permitted}} - omp.target_update_data motion_entries(%mapv : memref<?xi32>) + omp.target_update motion_entries(%mapv : memref<?xi32>) return } // ----- func.func @omp_target_update_invalid_motion_type_2(%map1 : memref<?xi32>) { - %mapv = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(delete) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(delete) capture(ByRef) -> memref<?xi32> {name = ""} // expected-error @below {{at least one of to or from map types must be specified, other map types are not permitted}} - omp.target_update_data motion_entries(%mapv : memref<?xi32>) + omp.target_update motion_entries(%mapv : memref<?xi32>) return } // ----- func.func @omp_target_update_invalid_motion_modifier(%map1 : memref<?xi32>) { - %mapv = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(always, to) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(always, to) capture(ByRef) -> memref<?xi32> {name = ""} // expected-error @below {{present, mapper and iterator map type modifiers are permitted}} - omp.target_update_data motion_entries(%mapv : memref<?xi32>) + omp.target_update motion_entries(%mapv : memref<?xi32>) return } // ----- func.func @omp_target_update_invalid_motion_modifier_2(%map1 : memref<?xi32>) { - %mapv = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(close, to) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(close, to) capture(ByRef) -> memref<?xi32> {name = ""} // expected-error @below {{present, mapper and iterator map type modifiers are permitted}} - omp.target_update_data motion_entries(%mapv : memref<?xi32>) + omp.target_update motion_entries(%mapv : memref<?xi32>) return } // ----- func.func @omp_target_update_invalid_motion_modifier_3(%map1 : memref<?xi32>) { - %mapv = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(implicit, to) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(implicit, to) capture(ByRef) -> memref<?xi32> {name = ""} // expected-error @below {{present, mapper and iterator map type modifiers are permitted}} - omp.target_update_data motion_entries(%mapv : memref<?xi32>) + omp.target_update motion_entries(%mapv : memref<?xi32>) return } // ----- func.func @omp_target_update_invalid_motion_modifier_4(%map1 : memref<?xi32>) { - %mapv = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(implicit, tofrom) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(implicit, tofrom) capture(ByRef) -> memref<?xi32> {name = ""} // expected-error @below {{either to or from map types can be specified, not both}} - omp.target_update_data motion_entries(%mapv : memref<?xi32>) + omp.target_update motion_entries(%mapv : memref<?xi32>) return } // ----- func.func @omp_target_update_invalid_motion_modifier_5(%map1 : memref<?xi32>) { - %mapv = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> {name = ""} - %mapv2 = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv2 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> {name = ""} // expected-error @below {{either to or from map types can be specified, not both}} - omp.target_update_data motion_entries(%mapv, %mapv2 : memref<?xi32>, memref<?xi32>) + omp.target_update motion_entries(%mapv, %mapv2 : memref<?xi32>, memref<?xi32>) return } llvm.mlir.global internal @_QFsubEx() : i32 @@ -1778,9 +1778,9 @@ llvm.mlir.global internal @_QFsubEx() : i32 // ----- func.func @omp_target_update_data_depend(%a: memref<?xi32>) { - %0 = omp.map_info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> + %0 = omp.map.info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> // expected-error @below {{op expected as many depend values as depend variables}} - omp.target_update_data motion_entries(%0: memref<?xi32> ) {operandSegmentSizes = array<i32: 0, 0, 1, 0>} + omp.target_update motion_entries(%0: memref<?xi32> ) {operandSegmentSizes = array<i32: 0, 0, 1, 0>} return } diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir index 211ff0ff9272..30ce77423005 100644 --- a/mlir/test/Dialect/OpenMP/ops.mlir +++ b/mlir/test/Dialect/OpenMP/ops.mlir @@ -520,20 +520,20 @@ func.func @omp_target(%if_cond : i1, %device : si32, %num_threads : i32, %map1: }) {nowait, operandSegmentSizes = array<i32: 1,1,1,0,0>} : ( i1, si32, i32 ) -> () // Test with optional map clause. - // CHECK: %[[MAP_A:.*]] = omp.map_info var_ptr(%[[VAL_1:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""} - // CHECK: %[[MAP_B:.*]] = omp.map_info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} + // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_1:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""} + // CHECK: %[[MAP_B:.*]] = omp.map.info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} // CHECK: omp.target map_entries(%[[MAP_A]] -> {{.*}}, %[[MAP_B]] -> {{.*}} : memref<?xi32>, memref<?xi32>) { - %mapv1 = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""} - %mapv2 = omp.map_info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv1 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv2 = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} omp.target map_entries(%mapv1 -> %arg0, %mapv2 -> %arg1 : memref<?xi32>, memref<?xi32>) { ^bb0(%arg0: memref<?xi32>, %arg1: memref<?xi32>): omp.terminator } - // CHECK: %[[MAP_C:.*]] = omp.map_info var_ptr(%[[VAL_1:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> {name = ""} - // CHECK: %[[MAP_D:.*]] = omp.map_info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""} + // CHECK: %[[MAP_C:.*]] = omp.map.info var_ptr(%[[VAL_1:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> {name = ""} + // CHECK: %[[MAP_D:.*]] = omp.map.info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""} // CHECK: omp.target map_entries(%[[MAP_C]] -> {{.*}}, %[[MAP_D]] -> {{.*}} : memref<?xi32>, memref<?xi32>) { - %mapv3 = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> {name = ""} - %mapv4 = omp.map_info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv3 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv4 = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""} omp.target map_entries(%mapv3 -> %arg0, %mapv4 -> %arg1 : memref<?xi32>, memref<?xi32>) { ^bb0(%arg0: memref<?xi32>, %arg1: memref<?xi32>): omp.terminator @@ -546,31 +546,31 @@ func.func @omp_target(%if_cond : i1, %device : si32, %num_threads : i32, %map1: // CHECK-LABEL: omp_target_data func.func @omp_target_data (%if_cond : i1, %device : si32, %device_ptr: memref<i32>, %device_addr: memref<?xi32>, %map1: memref<?xi32>, %map2: memref<?xi32>) -> () { - // CHECK: %[[MAP_A:.*]] = omp.map_info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""} + // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""} // CHECK: omp.target_data if(%[[VAL_0:.*]] : i1) device(%[[VAL_1:.*]] : si32) map_entries(%[[MAP_A]] : memref<?xi32>) - %mapv1 = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv1 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""} omp.target_data if(%if_cond : i1) device(%device : si32) map_entries(%mapv1 : memref<?xi32>){} - // CHECK: %[[MAP_A:.*]] = omp.map_info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(close, present, to) capture(ByRef) -> memref<?xi32> {name = ""} + // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(close, present, to) capture(ByRef) -> memref<?xi32> {name = ""} // CHECK: omp.target_data map_entries(%[[MAP_A]] : memref<?xi32>) use_device_ptr(%[[VAL_3:.*]] : memref<i32>) use_device_addr(%[[VAL_4:.*]] : memref<?xi32>) - %mapv2 = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(close, present, to) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv2 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(close, present, to) capture(ByRef) -> memref<?xi32> {name = ""} omp.target_data map_entries(%mapv2 : memref<?xi32>) use_device_ptr(%device_ptr : memref<i32>) use_device_addr(%device_addr : memref<?xi32>) {} - // CHECK: %[[MAP_A:.*]] = omp.map_info var_ptr(%[[VAL_1:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""} - // CHECK: %[[MAP_B:.*]] = omp.map_info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} + // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_1:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""} + // CHECK: %[[MAP_B:.*]] = omp.map.info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} // CHECK: omp.target_data map_entries(%[[MAP_A]], %[[MAP_B]] : memref<?xi32>, memref<?xi32>) - %mapv3 = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""} - %mapv4 = omp.map_info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv3 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv4 = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} omp.target_data map_entries(%mapv3, %mapv4 : memref<?xi32>, memref<?xi32>) {} - // CHECK: %[[MAP_A:.*]] = omp.map_info var_ptr(%[[VAL_3:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} + // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_3:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} // CHECK: omp.target_enter_data if(%[[VAL_0:.*]] : i1) device(%[[VAL_1:.*]] : si32) nowait map_entries(%[[MAP_A]] : memref<?xi32>) - %mapv5 = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv5 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} omp.target_enter_data if(%if_cond : i1) device(%device : si32) nowait map_entries(%mapv5 : memref<?xi32>) - // CHECK: %[[MAP_A:.*]] = omp.map_info var_ptr(%[[VAL_3:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} + // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_3:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} // CHECK: omp.target_exit_data if(%[[VAL_0:.*]] : i1) device(%[[VAL_1:.*]] : si32) nowait map_entries(%[[MAP_A]] : memref<?xi32>) - %mapv6 = omp.map_info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv6 = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> {name = ""} omp.target_exit_data if(%if_cond : i1) device(%device : si32) nowait map_entries(%mapv6 : memref<?xi32>) return @@ -591,7 +591,7 @@ func.func @omp_target_pretty(%if_cond : i1, %device : si32, %num_threads : i32) return } -// CHECK: omp.reduction.declare +// CHECK: omp.declare_reduction // CHECK-LABEL: @add_f32 // CHECK: : f32 // CHECK: init @@ -603,7 +603,7 @@ func.func @omp_target_pretty(%if_cond : i1, %device : si32, %num_threads : i32) // CHECK: atomic // CHECK: ^{{.+}}(%{{.+}}: !llvm.ptr, %{{.+}}: !llvm.ptr): // CHECK: omp.yield -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -773,9 +773,9 @@ func.func @sections_reduction() { return } -// CHECK: omp.reduction.declare +// CHECK: omp.declare_reduction // CHECK-LABEL: @add2_f32 -omp.reduction.declare @add2_f32 : f32 +omp.declare_reduction @add2_f32 : f32 // CHECK: init init { ^bb0(%arg: f32): @@ -904,15 +904,15 @@ func.func @omp_critical() -> () { func.func @omp_ordered(%arg1 : i32, %arg2 : i32, %arg3 : i32, %vec0 : i64, %vec1 : i64, %vec2 : i64, %vec3 : i64) -> () { - // CHECK: omp.ordered_region - omp.ordered_region { + // CHECK: omp.ordered.region + omp.ordered.region { // CHECK: omp.terminator omp.terminator } omp.wsloop ordered(0) for (%0) : i32 = (%arg1) to (%arg2) step (%arg3) { - omp.ordered_region { + omp.ordered.region { omp.terminator } omp.yield @@ -1815,8 +1815,8 @@ func.func @omp_cancel_sections() -> () { func.func @omp_cancellationpoint_parallel() -> () { omp.parallel { - // CHECK: omp.cancellationpoint cancellation_construct_type(parallel) - omp.cancellationpoint cancellation_construct_type(parallel) + // CHECK: omp.cancellation_point cancellation_construct_type(parallel) + omp.cancellation_point cancellation_construct_type(parallel) // CHECK: omp.cancel cancellation_construct_type(parallel) omp.cancel cancellation_construct_type(parallel) omp.terminator @@ -1827,8 +1827,8 @@ func.func @omp_cancellationpoint_parallel() -> () { func.func @omp_cancellationpoint_wsloop(%lb : index, %ub : index, %step : index) { omp.wsloop for (%iv) : index = (%lb) to (%ub) step (%step) { - // CHECK: omp.cancellationpoint cancellation_construct_type(loop) - omp.cancellationpoint cancellation_construct_type(loop) + // CHECK: omp.cancellation_point cancellation_construct_type(loop) + omp.cancellation_point cancellation_construct_type(loop) // CHECK: omp.cancel cancellation_construct_type(loop) omp.cancel cancellation_construct_type(loop) // CHECK: omp.terminator @@ -1840,8 +1840,8 @@ func.func @omp_cancellationpoint_wsloop(%lb : index, %ub : index, %step : index) func.func @omp_cancellationpoint_sections() -> () { omp.sections { omp.section { - // CHECK: omp.cancellationpoint cancellation_construct_type(sections) - omp.cancellationpoint cancellation_construct_type(sections) + // CHECK: omp.cancellation_point cancellation_construct_type(sections) + omp.cancellation_point cancellation_construct_type(sections) // CHECK: omp.cancel cancellation_construct_type(sections) omp.cancel cancellation_construct_type(sections) omp.terminator @@ -2088,7 +2088,7 @@ func.func @opaque_pointers_atomic_rwu(%v: !llvm.ptr, %x: !llvm.ptr) { // CHECK-LABEL: @opaque_pointers_reduction // CHECK: atomic { // CHECK-NEXT: ^{{[[:alnum:]]+}}(%{{.*}}: !llvm.ptr, %{{.*}}: !llvm.ptr): -omp.reduction.declare @opaque_pointers_reduction : f32 +omp.declare_reduction @opaque_pointers_reduction : f32 init { ^bb0(%arg: f32): %0 = arith.constant 0.0 : f32 @@ -2113,27 +2113,27 @@ func.func @omp_targets_with_map_bounds(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> () // CHECK: %[[C_01:.*]] = llvm.mlir.constant(1 : index) : i64 // CHECK: %[[C_02:.*]] = llvm.mlir.constant(1 : index) : i64 // CHECK: %[[C_03:.*]] = llvm.mlir.constant(1 : index) : i64 - // CHECK: %[[BOUNDS0:.*]] = omp.bounds lower_bound(%[[C_01]] : i64) upper_bound(%[[C_00]] : i64) stride(%[[C_02]] : i64) start_idx(%[[C_03]] : i64) - // CHECK: %[[MAP0:.*]] = omp.map_info var_ptr(%[[ARG0]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS0]]) -> !llvm.ptr {name = ""} + // CHECK: %[[BOUNDS0:.*]] = omp.map.bounds lower_bound(%[[C_01]] : i64) upper_bound(%[[C_00]] : i64) stride(%[[C_02]] : i64) start_idx(%[[C_03]] : i64) + // CHECK: %[[MAP0:.*]] = omp.map.info var_ptr(%[[ARG0]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS0]]) -> !llvm.ptr {name = ""} %0 = llvm.mlir.constant(4 : index) : i64 %1 = llvm.mlir.constant(1 : index) : i64 %2 = llvm.mlir.constant(1 : index) : i64 %3 = llvm.mlir.constant(1 : index) : i64 - %4 = omp.bounds lower_bound(%1 : i64) upper_bound(%0 : i64) stride(%2 : i64) start_idx(%3 : i64) + %4 = omp.map.bounds lower_bound(%1 : i64) upper_bound(%0 : i64) stride(%2 : i64) start_idx(%3 : i64) - %mapv1 = omp.map_info var_ptr(%arg0 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%4) -> !llvm.ptr {name = ""} + %mapv1 = omp.map.info var_ptr(%arg0 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%4) -> !llvm.ptr {name = ""} // CHECK: %[[C_10:.*]] = llvm.mlir.constant(9 : index) : i64 // CHECK: %[[C_11:.*]] = llvm.mlir.constant(1 : index) : i64 // CHECK: %[[C_12:.*]] = llvm.mlir.constant(2 : index) : i64 // CHECK: %[[C_13:.*]] = llvm.mlir.constant(2 : index) : i64 - // CHECK: %[[BOUNDS1:.*]] = omp.bounds lower_bound(%[[C_11]] : i64) upper_bound(%[[C_10]] : i64) stride(%[[C_12]] : i64) start_idx(%[[C_13]] : i64) - // CHECK: %[[MAP1:.*]] = omp.map_info var_ptr(%[[ARG1]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByCopy) bounds(%[[BOUNDS1]]) -> !llvm.ptr {name = ""} + // CHECK: %[[BOUNDS1:.*]] = omp.map.bounds lower_bound(%[[C_11]] : i64) upper_bound(%[[C_10]] : i64) stride(%[[C_12]] : i64) start_idx(%[[C_13]] : i64) + // CHECK: %[[MAP1:.*]] = omp.map.info var_ptr(%[[ARG1]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByCopy) bounds(%[[BOUNDS1]]) -> !llvm.ptr {name = ""} %6 = llvm.mlir.constant(9 : index) : i64 %7 = llvm.mlir.constant(1 : index) : i64 %8 = llvm.mlir.constant(2 : index) : i64 %9 = llvm.mlir.constant(2 : index) : i64 - %10 = omp.bounds lower_bound(%7 : i64) upper_bound(%6 : i64) stride(%8 : i64) start_idx(%9 : i64) - %mapv2 = omp.map_info var_ptr(%arg1 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByCopy) bounds(%10) -> !llvm.ptr {name = ""} + %10 = omp.map.bounds lower_bound(%7 : i64) upper_bound(%6 : i64) stride(%8 : i64) start_idx(%9 : i64) + %mapv2 = omp.map.info var_ptr(%arg1 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByCopy) bounds(%10) -> !llvm.ptr {name = ""} // CHECK: omp.target map_entries(%[[MAP0]] -> {{.*}}, %[[MAP1]] -> {{.*}} : !llvm.ptr, !llvm.ptr) omp.target map_entries(%mapv1 -> %arg2, %mapv2 -> %arg3 : !llvm.ptr, !llvm.ptr) { @@ -2144,14 +2144,14 @@ func.func @omp_targets_with_map_bounds(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> () // CHECK: omp.target_data map_entries(%[[MAP0]], %[[MAP1]] : !llvm.ptr, !llvm.ptr) omp.target_data map_entries(%mapv1, %mapv2 : !llvm.ptr, !llvm.ptr){} - // CHECK: %[[MAP2:.*]] = omp.map_info var_ptr(%[[ARG0]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(VLAType) bounds(%[[BOUNDS0]]) -> !llvm.ptr {name = ""} + // CHECK: %[[MAP2:.*]] = omp.map.info var_ptr(%[[ARG0]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(VLAType) bounds(%[[BOUNDS0]]) -> !llvm.ptr {name = ""} // CHECK: omp.target_enter_data map_entries(%[[MAP2]] : !llvm.ptr) - %mapv3 = omp.map_info var_ptr(%arg0 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(VLAType) bounds(%4) -> !llvm.ptr {name = ""} + %mapv3 = omp.map.info var_ptr(%arg0 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(VLAType) bounds(%4) -> !llvm.ptr {name = ""} omp.target_enter_data map_entries(%mapv3 : !llvm.ptr){} - // CHECK: %[[MAP3:.*]] = omp.map_info var_ptr(%[[ARG1]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(This) bounds(%[[BOUNDS1]]) -> !llvm.ptr {name = ""} + // CHECK: %[[MAP3:.*]] = omp.map.info var_ptr(%[[ARG1]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(This) bounds(%[[BOUNDS1]]) -> !llvm.ptr {name = ""} // CHECK: omp.target_exit_data map_entries(%[[MAP3]] : !llvm.ptr) - %mapv4 = omp.map_info var_ptr(%arg1 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(This) bounds(%10) -> !llvm.ptr {name = ""} + %mapv4 = omp.map.info var_ptr(%arg1 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(exit_release_or_enter_alloc) capture(This) bounds(%10) -> !llvm.ptr {name = ""} omp.target_exit_data map_entries(%mapv4 : !llvm.ptr){} return @@ -2159,22 +2159,22 @@ func.func @omp_targets_with_map_bounds(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> () // CHECK-LABEL: omp_target_update_data func.func @omp_target_update_data (%if_cond : i1, %device : si32, %map1: memref<?xi32>, %map2: memref<?xi32>) -> () { - %mapv_from = omp.map_info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv_from = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> {name = ""} - %mapv_to = omp.map_info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(present, to) capture(ByRef) -> memref<?xi32> {name = ""} + %mapv_to = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(present, to) capture(ByRef) -> memref<?xi32> {name = ""} - // CHECK: omp.target_update_data if(%[[VAL_0:.*]] : i1) device(%[[VAL_1:.*]] : si32) nowait motion_entries(%{{.*}}, %{{.*}} : memref<?xi32>, memref<?xi32>) - omp.target_update_data if(%if_cond : i1) device(%device : si32) nowait motion_entries(%mapv_from , %mapv_to : memref<?xi32>, memref<?xi32>) + // CHECK: omp.target_update if(%[[VAL_0:.*]] : i1) device(%[[VAL_1:.*]] : si32) nowait motion_entries(%{{.*}}, %{{.*}} : memref<?xi32>, memref<?xi32>) + omp.target_update if(%if_cond : i1) device(%device : si32) nowait motion_entries(%mapv_from , %mapv_to : memref<?xi32>, memref<?xi32>) return } // CHECK-LABEL: omp_targets_is_allocatable // CHECK-SAME: (%[[ARG0:.*]]: !llvm.ptr, %[[ARG1:.*]]: !llvm.ptr) func.func @omp_targets_is_allocatable(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> () { - // CHECK: %[[MAP0:.*]] = omp.map_info var_ptr(%[[ARG0]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} - %mapv1 = omp.map_info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} - // CHECK: %[[MAP1:.*]] = omp.map_info var_ptr(%[[ARG1]] : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(tofrom) capture(ByRef) members(%[[MAP0]] : !llvm.ptr) -> !llvm.ptr {name = ""} - %mapv2 = omp.map_info var_ptr(%arg1 : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(tofrom) capture(ByRef) members(%mapv1 : !llvm.ptr) -> !llvm.ptr {name = ""} + // CHECK: %[[MAP0:.*]] = omp.map.info var_ptr(%[[ARG0]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %mapv1 = omp.map.info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + // CHECK: %[[MAP1:.*]] = omp.map.info var_ptr(%[[ARG1]] : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(tofrom) capture(ByRef) members(%[[MAP0]] : !llvm.ptr) -> !llvm.ptr {name = ""} + %mapv2 = omp.map.info var_ptr(%arg1 : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(tofrom) capture(ByRef) members(%mapv1 : !llvm.ptr) -> !llvm.ptr {name = ""} // CHECK: omp.target map_entries(%[[MAP0]] -> {{.*}}, %[[MAP1]] -> {{.*}} : !llvm.ptr, !llvm.ptr) omp.target map_entries(%mapv1 -> %arg2, %mapv2 -> %arg3 : !llvm.ptr, !llvm.ptr) { ^bb0(%arg2: !llvm.ptr, %arg3 : !llvm.ptr): @@ -2186,12 +2186,12 @@ func.func @omp_targets_is_allocatable(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> () // CHECK-LABEL: func @omp_target_enter_update_exit_data_depend // CHECK-SAME:([[ARG0:%.*]]: memref<?xi32>, [[ARG1:%.*]]: memref<?xi32>, [[ARG2:%.*]]: memref<?xi32>) { func.func @omp_target_enter_update_exit_data_depend(%a: memref<?xi32>, %b: memref<?xi32>, %c: memref<?xi32>) { -// CHECK-NEXT: [[MAP0:%.*]] = omp.map_info -// CHECK-NEXT: [[MAP1:%.*]] = omp.map_info -// CHECK-NEXT: [[MAP2:%.*]] = omp.map_info - %map_a = omp.map_info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> - %map_b = omp.map_info var_ptr(%b: memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> - %map_c = omp.map_info var_ptr(%c: memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> +// CHECK-NEXT: [[MAP0:%.*]] = omp.map.info +// CHECK-NEXT: [[MAP1:%.*]] = omp.map.info +// CHECK-NEXT: [[MAP2:%.*]] = omp.map.info + %map_a = omp.map.info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> + %map_b = omp.map.info var_ptr(%b: memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> + %map_c = omp.map.info var_ptr(%c: memref<?xi32>, tensor<?xi32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) -> memref<?xi32> // Do some work on the host that writes to 'a' omp.task depend(taskdependout -> %a : memref<?xi32>) { @@ -2217,11 +2217,11 @@ func.func @omp_target_enter_update_exit_data_depend(%a: memref<?xi32>, %b: memre } // Copy the updated 'a' onto the target - // CHECK: omp.target_update_data nowait motion_entries([[MAP0]] : memref<?xi32>) depend(taskdependin -> [[ARG0]] : memref<?xi32>) - omp.target_update_data motion_entries(%map_a : memref<?xi32>) depend(taskdependin -> %a : memref<?xi32>) nowait + // CHECK: omp.target_update nowait motion_entries([[MAP0]] : memref<?xi32>) depend(taskdependin -> [[ARG0]] : memref<?xi32>) + omp.target_update motion_entries(%map_a : memref<?xi32>) depend(taskdependin -> %a : memref<?xi32>) nowait // Compute 'c' on the target and copy it back - %map_c_from = omp.map_info var_ptr(%c: memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> + %map_c_from = omp.map.info var_ptr(%c: memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> omp.target map_entries(%map_a -> %arg0, %map_c_from -> %arg1 : memref<?xi32>, memref<?xi32>) depend(taskdependout -> %c : memref<?xi32>) { ^bb0(%arg0 : memref<?xi32>, %arg1 : memref<?xi32>) : "test.foobar"() : ()->() diff --git a/mlir/test/Target/LLVMIR/omptarget-array-sectioning-host.mlir b/mlir/test/Target/LLVMIR/omptarget-array-sectioning-host.mlir index 307d8a02ce61..08ccbf04014a 100644 --- a/mlir/test/Target/LLVMIR/omptarget-array-sectioning-host.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-array-sectioning-host.mlir @@ -14,10 +14,10 @@ module attributes {omp.is_target_device = false} { %2 = llvm.mlir.constant(1 : index) : i64 %3 = llvm.mlir.constant(0 : index) : i64 %4 = llvm.mlir.constant(2 : index) : i64 - %5 = omp.bounds lower_bound(%3 : i64) upper_bound(%4 : i64) stride(%2 : i64) start_idx(%2 : i64) - %6 = omp.bounds lower_bound(%2 : i64) upper_bound(%2 : i64) stride(%2 : i64) start_idx(%2 : i64) - %7 = omp.map_info var_ptr(%0 : !llvm.ptr, !llvm.array<3 x array<3 x array<3 x i32>>>) map_clauses(tofrom) capture(ByRef) bounds(%5, %5, %6) -> !llvm.ptr {name = "inarray(1:3,1:3,2:2)"} - %8 = omp.map_info var_ptr(%1 : !llvm.ptr, !llvm.array<3 x array<3 x array<3 x i32>>>) map_clauses(tofrom) capture(ByRef) bounds(%5, %5, %5) -> !llvm.ptr {name = "outarray(1:3,1:3,1:3)"} + %5 = omp.map.bounds lower_bound(%3 : i64) upper_bound(%4 : i64) stride(%2 : i64) start_idx(%2 : i64) + %6 = omp.map.bounds lower_bound(%2 : i64) upper_bound(%2 : i64) stride(%2 : i64) start_idx(%2 : i64) + %7 = omp.map.info var_ptr(%0 : !llvm.ptr, !llvm.array<3 x array<3 x array<3 x i32>>>) map_clauses(tofrom) capture(ByRef) bounds(%5, %5, %6) -> !llvm.ptr {name = "inarray(1:3,1:3,2:2)"} + %8 = omp.map.info var_ptr(%1 : !llvm.ptr, !llvm.array<3 x array<3 x array<3 x i32>>>) map_clauses(tofrom) capture(ByRef) bounds(%5, %5, %5) -> !llvm.ptr {name = "outarray(1:3,1:3,1:3)"} omp.target map_entries(%7 -> %arg0, %8 -> %arg1 : !llvm.ptr, !llvm.ptr) { ^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr): %9 = llvm.mlir.constant(0 : i64) : i64 diff --git a/mlir/test/Target/LLVMIR/omptarget-byref-bycopy-generation-device.mlir b/mlir/test/Target/LLVMIR/omptarget-byref-bycopy-generation-device.mlir index 875d04f584ca..5931da7582fd 100644 --- a/mlir/test/Target/LLVMIR/omptarget-byref-bycopy-generation-device.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-byref-bycopy-generation-device.mlir @@ -4,8 +4,8 @@ module attributes {omp.is_target_device = true} { llvm.func @_QQmain() attributes {fir.bindc_name = "main"} { %0 = llvm.mlir.addressof @_QFEi : !llvm.ptr %1 = llvm.mlir.addressof @_QFEsp : !llvm.ptr - %2 = omp.map_info var_ptr(%1 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "sp"} - %3 = omp.map_info var_ptr(%0 : !llvm.ptr, i32) map_clauses(to) capture(ByCopy) -> !llvm.ptr {name = "i"} + %2 = omp.map.info var_ptr(%1 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "sp"} + %3 = omp.map.info var_ptr(%0 : !llvm.ptr, i32) map_clauses(to) capture(ByCopy) -> !llvm.ptr {name = "i"} omp.target map_entries(%2 -> %arg0, %3 -> %arg1 : !llvm.ptr, !llvm.ptr) { ^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr): %4 = llvm.load %arg1 : !llvm.ptr -> i32 diff --git a/mlir/test/Target/LLVMIR/omptarget-byref-bycopy-generation-host.mlir b/mlir/test/Target/LLVMIR/omptarget-byref-bycopy-generation-host.mlir index c8fb4e232f06..8635ea495670 100644 --- a/mlir/test/Target/LLVMIR/omptarget-byref-bycopy-generation-host.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-byref-bycopy-generation-host.mlir @@ -4,8 +4,8 @@ module attributes {omp.is_target_device = false} { llvm.func @_QQmain() attributes {fir.bindc_name = "main"} { %0 = llvm.mlir.addressof @_QFEi : !llvm.ptr %1 = llvm.mlir.addressof @_QFEsp : !llvm.ptr - %2 = omp.map_info var_ptr(%1 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "sp"} - %3 = omp.map_info var_ptr(%0 : !llvm.ptr, i32) map_clauses(to) capture(ByCopy) -> !llvm.ptr {name = "i"} + %2 = omp.map.info var_ptr(%1 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "sp"} + %3 = omp.map.info var_ptr(%0 : !llvm.ptr, i32) map_clauses(to) capture(ByCopy) -> !llvm.ptr {name = "i"} omp.target map_entries(%2 -> %arg0, %3 -> %arg1 : !llvm.ptr, !llvm.ptr) { ^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr): %4 = llvm.load %arg1 : !llvm.ptr -> i32 diff --git a/mlir/test/Target/LLVMIR/omptarget-constant-alloca-raise.mlir b/mlir/test/Target/LLVMIR/omptarget-constant-alloca-raise.mlir index be521fbe1f01..7a785301eb16 100644 --- a/mlir/test/Target/LLVMIR/omptarget-constant-alloca-raise.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-constant-alloca-raise.mlir @@ -14,7 +14,7 @@ module attributes {omp.is_target_device = true} { llvm.func @_QQmain() attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>} { %1 = llvm.mlir.constant(1 : i64) : i64 %2 = llvm.alloca %1 x !llvm.struct<(ptr)> : (i64) -> !llvm.ptr - %3 = omp.map_info var_ptr(%2 : !llvm.ptr, !llvm.struct<(ptr)>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr + %3 = omp.map.info var_ptr(%2 : !llvm.ptr, !llvm.struct<(ptr)>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr omp.target map_entries(%3 -> %arg0 : !llvm.ptr) { ^bb0(%arg0: !llvm.ptr): %4 = llvm.mlir.constant(1 : i32) : i32 diff --git a/mlir/test/Target/LLVMIR/omptarget-constant-indexing-device-region.mlir b/mlir/test/Target/LLVMIR/omptarget-constant-indexing-device-region.mlir index 5c0ac79271a6..be8145dc9075 100644 --- a/mlir/test/Target/LLVMIR/omptarget-constant-indexing-device-region.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-constant-indexing-device-region.mlir @@ -7,8 +7,8 @@ module attributes {omp.is_target_device = true} { %2 = llvm.mlir.constant(1 : index) : i64 %3 = llvm.mlir.constant(0 : index) : i64 %4 = llvm.mlir.constant(9 : index) : i64 - %5 = omp.bounds lower_bound(%3 : i64) upper_bound(%4 : i64) extent(%1 : i64) stride(%2 : i64) start_idx(%2 : i64) - %6 = omp.map_info var_ptr(%0 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%5) -> !llvm.ptr {name = "sp"} + %5 = omp.map.bounds lower_bound(%3 : i64) upper_bound(%4 : i64) extent(%1 : i64) stride(%2 : i64) start_idx(%2 : i64) + %6 = omp.map.info var_ptr(%0 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%5) -> !llvm.ptr {name = "sp"} omp.target map_entries(%6 -> %arg0 : !llvm.ptr) { ^bb0(%arg0: !llvm.ptr): %7 = llvm.mlir.constant(20 : i32) : i32 diff --git a/mlir/test/Target/LLVMIR/omptarget-declare-target-llvm-device.mlir b/mlir/test/Target/LLVMIR/omptarget-declare-target-llvm-device.mlir index cf08761981fb..bb32000cc945 100644 --- a/mlir/test/Target/LLVMIR/omptarget-declare-target-llvm-device.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-declare-target-llvm-device.mlir @@ -21,7 +21,7 @@ module attributes {omp.is_target_device = true} { // CHECK-DAG: %[[V:.*]] = load ptr, ptr @_QMtest_0Esp_decl_tgt_ref_ptr, align 8 // CHECK-DAG: store i32 1, ptr %[[V]], align 4 // CHECK-DAG: br label %omp.region.cont - %map = omp.map_info var_ptr(%0 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map = omp.map.info var_ptr(%0 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} omp.target map_entries(%map -> %arg0 : !llvm.ptr) { ^bb0(%arg0: !llvm.ptr): %1 = llvm.mlir.constant(1 : i32) : i32 diff --git a/mlir/test/Target/LLVMIR/omptarget-fortran-allocatable-types-host.mlir b/mlir/test/Target/LLVMIR/omptarget-fortran-allocatable-types-host.mlir index 831cd05871c4..e8c388627a0a 100644 --- a/mlir/test/Target/LLVMIR/omptarget-fortran-allocatable-types-host.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-fortran-allocatable-types-host.mlir @@ -3,7 +3,7 @@ // This test checks the offload sizes, map types and base pointers and pointers // provided to the OpenMP kernel argument structure are correct when lowering // to LLVM-IR from MLIR when the fortran allocatables flag is switched on and -// a fortran allocatable descriptor type is provided alongside the omp.map_info, +// a fortran allocatable descriptor type is provided alongside the omp.map.info, // the test utilises mapping of array sections, full arrays and individual // allocated scalars. @@ -24,10 +24,10 @@ module attributes {omp.is_target_device = false} { %12 = llvm.getelementptr %3[0, 7, %7, 2] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)> %13 = llvm.load %12 : !llvm.ptr -> i64 %14 = llvm.sub %11, %2 : i64 - %15 = omp.bounds lower_bound(%7 : i64) upper_bound(%14 : i64) extent(%11 : i64) stride(%13 : i64) start_idx(%9 : i64) {stride_in_bytes = true} + %15 = omp.map.bounds lower_bound(%7 : i64) upper_bound(%14 : i64) extent(%11 : i64) stride(%13 : i64) start_idx(%9 : i64) {stride_in_bytes = true} %16 = llvm.getelementptr %3[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)> - %17 = omp.map_info var_ptr(%16 : !llvm.ptr, f32) map_clauses(tofrom) capture(ByRef) bounds(%15) -> !llvm.ptr {name = "full_arr"} - %18 = omp.map_info var_ptr(%3 : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>) map_clauses(tofrom) capture(ByRef) members(%17 : !llvm.ptr) -> !llvm.ptr {name = "full_arr"} + %17 = omp.map.info var_ptr(%16 : !llvm.ptr, f32) map_clauses(tofrom) capture(ByRef) bounds(%15) -> !llvm.ptr {name = "full_arr"} + %18 = omp.map.info var_ptr(%3 : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>) map_clauses(tofrom) capture(ByRef) members(%17 : !llvm.ptr) -> !llvm.ptr {name = "full_arr"} %19 = llvm.getelementptr %6[0, 7, %7, 0] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)> %20 = llvm.load %19 : !llvm.ptr -> i64 %21 = llvm.getelementptr %6[0, 7, %7, 1] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)> @@ -36,13 +36,13 @@ module attributes {omp.is_target_device = false} { %24 = llvm.load %23 : !llvm.ptr -> i64 %25 = llvm.sub %1, %20 : i64 %26 = llvm.sub %0, %20 : i64 - %27 = omp.bounds lower_bound(%25 : i64) upper_bound(%26 : i64) extent(%22 : i64) stride(%24 : i64) start_idx(%20 : i64) {stride_in_bytes = true} + %27 = omp.map.bounds lower_bound(%25 : i64) upper_bound(%26 : i64) extent(%22 : i64) stride(%24 : i64) start_idx(%20 : i64) {stride_in_bytes = true} %28 = llvm.getelementptr %6[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)> - %29 = omp.map_info var_ptr(%6 : !llvm.ptr, i32) var_ptr_ptr(%28 : !llvm.ptr) map_clauses(tofrom) capture(ByRef) bounds(%27) -> !llvm.ptr {name = "sect_arr(2:5)"} - %30 = omp.map_info var_ptr(%6 : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>) map_clauses(tofrom) capture(ByRef) members(%29 : !llvm.ptr) -> !llvm.ptr {name = "sect_arr(2:5)"} + %29 = omp.map.info var_ptr(%6 : !llvm.ptr, i32) var_ptr_ptr(%28 : !llvm.ptr) map_clauses(tofrom) capture(ByRef) bounds(%27) -> !llvm.ptr {name = "sect_arr(2:5)"} + %30 = omp.map.info var_ptr(%6 : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>) map_clauses(tofrom) capture(ByRef) members(%29 : !llvm.ptr) -> !llvm.ptr {name = "sect_arr(2:5)"} %31 = llvm.getelementptr %5[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> - %32 = omp.map_info var_ptr(%5 : !llvm.ptr, f32) var_ptr_ptr(%31 : !llvm.ptr) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "scalar"} - %33 = omp.map_info var_ptr(%5 : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(tofrom) capture(ByRef) members(%32 : !llvm.ptr) -> !llvm.ptr {name = "scalar"} + %32 = omp.map.info var_ptr(%5 : !llvm.ptr, f32) var_ptr_ptr(%31 : !llvm.ptr) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "scalar"} + %33 = omp.map.info var_ptr(%5 : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(tofrom) capture(ByRef) members(%32 : !llvm.ptr) -> !llvm.ptr {name = "scalar"} omp.target map_entries(%17 -> %arg0, %18 -> %arg1, %29 -> %arg2, %30 -> %arg3, %32 -> %arg4, %33 -> %arg5 : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) { ^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: !llvm.ptr, %arg4: !llvm.ptr, %arg5: !llvm.ptr): omp.terminator diff --git a/mlir/test/Target/LLVMIR/omptarget-llvm.mlir b/mlir/test/Target/LLVMIR/omptarget-llvm.mlir index b089d47f795d..4b1d5d58f14e 100644 --- a/mlir/test/Target/LLVMIR/omptarget-llvm.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-llvm.mlir @@ -3,7 +3,7 @@ llvm.func @_QPopenmp_target_data() { %0 = llvm.mlir.constant(1 : i64) : i64 %1 = llvm.alloca %0 x i32 {bindc_name = "i", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFopenmp_target_dataEi"} : (i64) -> !llvm.ptr - %2 = omp.map_info var_ptr(%1 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %2 = omp.map.info var_ptr(%1 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} omp.target_data map_entries(%2 : !llvm.ptr) { %3 = llvm.mlir.constant(99 : i32) : i32 llvm.store %3, %1 : i32, !llvm.ptr @@ -43,8 +43,8 @@ llvm.func @_QPopenmp_target_data_region(%0 : !llvm.ptr) { %2 = llvm.mlir.constant(0 : index) : i64 %3 = llvm.mlir.constant(1024 : index) : i64 %4 = llvm.mlir.constant(1 : index) : i64 - %5 = omp.bounds lower_bound(%2 : i64) upper_bound(%1 : i64) extent(%3 : i64) stride(%4 : i64) start_idx(%4 : i64) - %6 = omp.map_info var_ptr(%0 : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%5) -> !llvm.ptr {name = ""} + %5 = omp.map.bounds lower_bound(%2 : i64) upper_bound(%1 : i64) extent(%3 : i64) stride(%4 : i64) start_idx(%4 : i64) + %6 = omp.map.info var_ptr(%0 : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%5) -> !llvm.ptr {name = ""} omp.target_data map_entries(%6 : !llvm.ptr) { %7 = llvm.mlir.constant(99 : i32) : i32 %8 = llvm.mlir.constant(1 : i64) : i64 @@ -101,14 +101,14 @@ llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr, %3 : !llvm.ptr) { %15 = llvm.mlir.constant(0 : index) : i64 %16 = llvm.mlir.constant(1024 : index) : i64 %17 = llvm.mlir.constant(1 : index) : i64 - %18 = omp.bounds lower_bound(%15 : i64) upper_bound(%14 : i64) extent(%16 : i64) stride(%17 : i64) start_idx(%17 : i64) - %map1 = omp.map_info var_ptr(%1 : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%18) -> !llvm.ptr {name = ""} + %18 = omp.map.bounds lower_bound(%15 : i64) upper_bound(%14 : i64) extent(%16 : i64) stride(%17 : i64) start_idx(%17 : i64) + %map1 = omp.map.info var_ptr(%1 : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%18) -> !llvm.ptr {name = ""} %19 = llvm.mlir.constant(511 : index) : i64 %20 = llvm.mlir.constant(0 : index) : i64 %21 = llvm.mlir.constant(512 : index) : i64 %22 = llvm.mlir.constant(1 : index) : i64 - %23 = omp.bounds lower_bound(%20 : i64) upper_bound(%19 : i64) extent(%21 : i64) stride(%22 : i64) start_idx(%22 : i64) - %map2 = omp.map_info var_ptr(%3 : !llvm.ptr, !llvm.array<512 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%23) -> !llvm.ptr {name = ""} + %23 = omp.map.bounds lower_bound(%20 : i64) upper_bound(%19 : i64) extent(%21 : i64) stride(%22 : i64) start_idx(%22 : i64) + %map2 = omp.map.info var_ptr(%3 : !llvm.ptr, !llvm.array<512 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%23) -> !llvm.ptr {name = ""} omp.target_enter_data if(%12 : i1) device(%13 : i32) map_entries(%map1, %map2 : !llvm.ptr, !llvm.ptr) %24 = llvm.load %7 : !llvm.ptr -> i32 %25 = llvm.mlir.constant(10 : i32) : i32 @@ -118,14 +118,14 @@ llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr, %3 : !llvm.ptr) { %29 = llvm.mlir.constant(0 : index) : i64 %30 = llvm.mlir.constant(1024 : index) : i64 %31 = llvm.mlir.constant(1 : index) : i64 - %32 = omp.bounds lower_bound(%29 : i64) upper_bound(%28 : i64) extent(%30 : i64) stride(%31 : i64) start_idx(%31 : i64) - %map3 = omp.map_info var_ptr(%1 : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%32) -> !llvm.ptr {name = ""} + %32 = omp.map.bounds lower_bound(%29 : i64) upper_bound(%28 : i64) extent(%30 : i64) stride(%31 : i64) start_idx(%31 : i64) + %map3 = omp.map.info var_ptr(%1 : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%32) -> !llvm.ptr {name = ""} %33 = llvm.mlir.constant(511 : index) : i64 %34 = llvm.mlir.constant(0 : index) : i64 %35 = llvm.mlir.constant(512 : index) : i64 %36 = llvm.mlir.constant(1 : index) : i64 - %37 = omp.bounds lower_bound(%34 : i64) upper_bound(%33 : i64) extent(%35 : i64) stride(%36 : i64) start_idx(%36 : i64) - %map4 = omp.map_info var_ptr(%3 : !llvm.ptr, !llvm.array<512 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%37) -> !llvm.ptr {name = ""} + %37 = omp.map.bounds lower_bound(%34 : i64) upper_bound(%33 : i64) extent(%35 : i64) stride(%36 : i64) start_idx(%36 : i64) + %map4 = omp.map.info var_ptr(%3 : !llvm.ptr, !llvm.array<512 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%37) -> !llvm.ptr {name = ""} omp.target_exit_data if(%26 : i1) device(%27 : i32) map_entries(%map3, %map4 : !llvm.ptr, !llvm.ptr) llvm.return } @@ -203,7 +203,7 @@ llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr, %3 : !llvm.ptr) { llvm.func @_QPopenmp_target_use_dev_ptr() { %0 = llvm.mlir.constant(1 : i64) : i64 %a = llvm.alloca %0 x !llvm.ptr : (i64) -> !llvm.ptr - %map1 = omp.map_info var_ptr(%a : !llvm.ptr, !llvm.ptr) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} + %map1 = omp.map.info var_ptr(%a : !llvm.ptr, !llvm.ptr) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} omp.target_data map_entries(%map1 : !llvm.ptr) use_device_ptr(%a : !llvm.ptr) { ^bb0(%arg0: !llvm.ptr): %1 = llvm.mlir.constant(10 : i32) : i32 @@ -247,7 +247,7 @@ llvm.func @_QPopenmp_target_use_dev_ptr() { llvm.func @_QPopenmp_target_use_dev_addr() { %0 = llvm.mlir.constant(1 : i64) : i64 %a = llvm.alloca %0 x !llvm.ptr : (i64) -> !llvm.ptr - %map = omp.map_info var_ptr(%a : !llvm.ptr, !llvm.ptr) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} + %map = omp.map.info var_ptr(%a : !llvm.ptr, !llvm.ptr) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} omp.target_data map_entries(%map : !llvm.ptr) use_device_addr(%a : !llvm.ptr) { ^bb0(%arg0: !llvm.ptr): %1 = llvm.mlir.constant(10 : i32) : i32 @@ -289,7 +289,7 @@ llvm.func @_QPopenmp_target_use_dev_addr() { llvm.func @_QPopenmp_target_use_dev_addr_no_ptr() { %0 = llvm.mlir.constant(1 : i64) : i64 %a = llvm.alloca %0 x i32 : (i64) -> !llvm.ptr - %map = omp.map_info var_ptr(%a : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map = omp.map.info var_ptr(%a : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} omp.target_data map_entries(%map : !llvm.ptr) use_device_addr(%a : !llvm.ptr) { ^bb0(%arg0: !llvm.ptr): %1 = llvm.mlir.constant(10 : i32) : i32 @@ -331,7 +331,7 @@ llvm.func @_QPopenmp_target_use_dev_addr_nomap() { %a = llvm.alloca %0 x !llvm.ptr : (i64) -> !llvm.ptr %1 = llvm.mlir.constant(1 : i64) : i64 %b = llvm.alloca %0 x !llvm.ptr : (i64) -> !llvm.ptr - %map = omp.map_info var_ptr(%b : !llvm.ptr, !llvm.ptr) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} + %map = omp.map.info var_ptr(%b : !llvm.ptr, !llvm.ptr) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} omp.target_data map_entries(%map : !llvm.ptr) use_device_addr(%a : !llvm.ptr) { ^bb0(%arg0: !llvm.ptr): %2 = llvm.mlir.constant(10 : i32) : i32 @@ -387,8 +387,8 @@ llvm.func @_QPopenmp_target_use_dev_both() { %a = llvm.alloca %0 x !llvm.ptr : (i64) -> !llvm.ptr %1 = llvm.mlir.constant(1 : i64) : i64 %b = llvm.alloca %0 x !llvm.ptr : (i64) -> !llvm.ptr - %map = omp.map_info var_ptr(%a : !llvm.ptr, !llvm.ptr) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} - %map1 = omp.map_info var_ptr(%b : !llvm.ptr, !llvm.ptr) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map = omp.map.info var_ptr(%a : !llvm.ptr, !llvm.ptr) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map1 = omp.map.info var_ptr(%b : !llvm.ptr, !llvm.ptr) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} omp.target_data map_entries(%map, %map1 : !llvm.ptr, !llvm.ptr) use_device_ptr(%a : !llvm.ptr) use_device_addr(%b : !llvm.ptr) { ^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr): %2 = llvm.mlir.constant(10 : i32) : i32 @@ -445,14 +445,14 @@ llvm.func @_QPopenmp_target_use_dev_both() { llvm.func @_QPopenmp_target_data_update() { %0 = llvm.mlir.constant(1 : i64) : i64 %1 = llvm.alloca %0 x i32 {bindc_name = "i", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFopenmp_target_dataEi"} : (i64) -> !llvm.ptr - %2 = omp.map_info var_ptr(%1 : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} + %2 = omp.map.info var_ptr(%1 : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} omp.target_data map_entries(%2 : !llvm.ptr) { %3 = llvm.mlir.constant(99 : i32) : i32 llvm.store %3, %1 : i32, !llvm.ptr omp.terminator } - omp.target_update_data motion_entries(%2 : !llvm.ptr) + omp.target_update motion_entries(%2 : !llvm.ptr) llvm.return } diff --git a/mlir/test/Target/LLVMIR/omptarget-nowait-llvm.mlir b/mlir/test/Target/LLVMIR/omptarget-nowait-llvm.mlir index 50c2f0702e63..f0d88f5c1353 100644 --- a/mlir/test/Target/LLVMIR/omptarget-nowait-llvm.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-nowait-llvm.mlir @@ -3,10 +3,10 @@ llvm.func @_QPopenmp_target_data_update() { %0 = llvm.mlir.constant(1 : i64) : i64 %1 = llvm.alloca %0 x i32 {bindc_name = "i", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFopenmp_target_dataEi"} : (i64) -> !llvm.ptr - %2 = omp.map_info var_ptr(%1 : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} + %2 = omp.map.info var_ptr(%1 : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} // CHECK: error: `nowait` is not supported yet - omp.target_update_data motion_entries(%2 : !llvm.ptr) nowait + omp.target_update motion_entries(%2 : !llvm.ptr) nowait llvm.return } @@ -16,7 +16,7 @@ llvm.func @_QPopenmp_target_data_update() { llvm.func @_QPopenmp_target_data_enter() { %0 = llvm.mlir.constant(1 : i64) : i64 %1 = llvm.alloca %0 x i32 {bindc_name = "i", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFopenmp_target_dataEi"} : (i64) -> !llvm.ptr - %2 = omp.map_info var_ptr(%1 : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} + %2 = omp.map.info var_ptr(%1 : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""} // CHECK: error: `nowait` is not supported yet omp.target_enter_data map_entries(%2 : !llvm.ptr) nowait @@ -30,7 +30,7 @@ llvm.func @_QPopenmp_target_data_enter() { llvm.func @_QPopenmp_target_data_exit() { %0 = llvm.mlir.constant(1 : i64) : i64 %1 = llvm.alloca %0 x i32 {bindc_name = "i", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFopenmp_target_dataEi"} : (i64) -> !llvm.ptr - %2 = omp.map_info var_ptr(%1 : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} + %2 = omp.map.info var_ptr(%1 : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""} // CHECK: error: `nowait` is not supported yet omp.target_exit_data map_entries(%2 : !llvm.ptr) nowait diff --git a/mlir/test/Target/LLVMIR/omptarget-parallel-llvm.mlir b/mlir/test/Target/LLVMIR/omptarget-parallel-llvm.mlir index 6c148944e034..f22bc12d6b94 100644 --- a/mlir/test/Target/LLVMIR/omptarget-parallel-llvm.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-parallel-llvm.mlir @@ -5,7 +5,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memory_space", 5 : ui32>>, llvm.data_layout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9", llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_gpu = true, omp.is_target_device = true} { llvm.func @_QQmain_omp_outline_1(%arg0: !llvm.ptr) attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>} { - %0 = omp.map_info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = "d"} + %0 = omp.map.info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = "d"} omp.target map_entries(%0 -> %arg2 : !llvm.ptr) { ^bb0(%arg2: !llvm.ptr): omp.parallel { @@ -19,7 +19,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo } llvm.func @_test_num_threads(%arg0: !llvm.ptr) attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>} { - %0 = omp.map_info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = "d"} + %0 = omp.map.info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = "d"} omp.target map_entries(%0 -> %arg2 : !llvm.ptr) { ^bb0(%arg2: !llvm.ptr): %1 = llvm.mlir.constant(156 : i32) : i32 @@ -36,8 +36,8 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo llvm.func @parallel_if(%arg0: !llvm.ptr {fir.bindc_name = "ifcond"}) { %0 = llvm.mlir.constant(1 : i64) : i64 %1 = llvm.alloca %0 x i32 {bindc_name = "d"} : (i64) -> !llvm.ptr - %2 = omp.map_info var_ptr(%1 : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = "d"} - %3 = omp.map_info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !llvm.ptr {name = "ifcond"} + %2 = omp.map.info var_ptr(%1 : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = "d"} + %3 = omp.map.info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !llvm.ptr {name = "ifcond"} omp.target map_entries(%2 -> %arg1, %3 -> %arg2 : !llvm.ptr, !llvm.ptr) { ^bb0(%arg1: !llvm.ptr, %arg2: !llvm.ptr): %4 = llvm.mlir.constant(10 : i32) : i32 diff --git a/mlir/test/Target/LLVMIR/omptarget-region-device-llvm.mlir b/mlir/test/Target/LLVMIR/omptarget-region-device-llvm.mlir index f537eb5c3f57..ca8a2e6a5b98 100644 --- a/mlir/test/Target/LLVMIR/omptarget-region-device-llvm.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-region-device-llvm.mlir @@ -12,9 +12,9 @@ module attributes {omp.is_target_device = true} { %7 = llvm.alloca %6 x i32 {bindc_name = "c", in_type = i32, operandSegmentSizes = array<i32: 0, 0>, uniq_name = "_QFomp_target_regionEc"} : (i64) -> !llvm.ptr llvm.store %1, %3 : i32, !llvm.ptr llvm.store %0, %5 : i32, !llvm.ptr - %map1 = omp.map_info var_ptr(%3 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} - %map2 = omp.map_info var_ptr(%5 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} - %map3 = omp.map_info var_ptr(%7 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map1 = omp.map.info var_ptr(%3 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map2 = omp.map.info var_ptr(%5 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map3 = omp.map.info var_ptr(%7 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} omp.target map_entries(%map1 -> %arg0, %map2 -> %arg1, %map3 -> %arg2 : !llvm.ptr, !llvm.ptr, !llvm.ptr) { ^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr): %8 = llvm.load %arg0 : !llvm.ptr -> i32 diff --git a/mlir/test/Target/LLVMIR/omptarget-region-llvm.mlir b/mlir/test/Target/LLVMIR/omptarget-region-llvm.mlir index b861dd7a7d31..a32ee3e184e2 100644 --- a/mlir/test/Target/LLVMIR/omptarget-region-llvm.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-region-llvm.mlir @@ -12,9 +12,9 @@ module attributes {omp.is_target_device = false} { %7 = llvm.alloca %6 x i32 {bindc_name = "c", in_type = i32, operandSegmentSizes = array<i32: 0, 0>, uniq_name = "_QFomp_target_regionEc"} : (i64) -> !llvm.ptr llvm.store %1, %3 : i32, !llvm.ptr llvm.store %0, %5 : i32, !llvm.ptr - %map1 = omp.map_info var_ptr(%3 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} - %map2 = omp.map_info var_ptr(%5 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} - %map3 = omp.map_info var_ptr(%7 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map1 = omp.map.info var_ptr(%3 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map2 = omp.map.info var_ptr(%5 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map3 = omp.map.info var_ptr(%7 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} omp.target map_entries(%map1 -> %arg0, %map2 -> %arg1, %map3 -> %arg2 : !llvm.ptr, !llvm.ptr, !llvm.ptr) { ^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr): %8 = llvm.load %arg0 : !llvm.ptr -> i32 diff --git a/mlir/test/Target/LLVMIR/omptarget-region-parallel-llvm.mlir b/mlir/test/Target/LLVMIR/omptarget-region-parallel-llvm.mlir index c80ea1f0a47b..4072150a8eab 100644 --- a/mlir/test/Target/LLVMIR/omptarget-region-parallel-llvm.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-region-parallel-llvm.mlir @@ -12,9 +12,9 @@ module attributes {omp.is_target_device = false} { %7 = llvm.alloca %6 x i32 {bindc_name = "c", in_type = i32, operandSegmentSizes = array<i32: 0, 0>, uniq_name = "_QFomp_target_regionEc"} : (i64) -> !llvm.ptr llvm.store %1, %3 : i32, !llvm.ptr llvm.store %0, %5 : i32, !llvm.ptr - %map1 = omp.map_info var_ptr(%3 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} - %map2 = omp.map_info var_ptr(%5 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} - %map3 = omp.map_info var_ptr(%7 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map1 = omp.map.info var_ptr(%3 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map2 = omp.map.info var_ptr(%5 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} + %map3 = omp.map.info var_ptr(%7 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""} omp.target map_entries( %map1 -> %arg0, %map2 -> %arg1, %map3 -> %arg2 : !llvm.ptr, !llvm.ptr, !llvm.ptr) { ^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr): omp.parallel { diff --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir index 12bd108ba86c..4cb99c1f1a28 100644 --- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir +++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir @@ -1191,7 +1191,7 @@ llvm.func @omp_ordered(%arg0 : i32, %arg1 : i32, %arg2 : i32, %arg3 : i64, // CHECK: [[OMP_THREAD:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]) // CHECK-NEXT: call void @__kmpc_ordered(ptr @[[GLOB1]], i32 [[OMP_THREAD]]) - omp.ordered_region { + omp.ordered.region { omp.terminator // CHECK: call void @__kmpc_end_ordered(ptr @[[GLOB1]], i32 [[OMP_THREAD]]) } @@ -1199,7 +1199,7 @@ llvm.func @omp_ordered(%arg0 : i32, %arg1 : i32, %arg2 : i32, %arg3 : i64, omp.wsloop ordered(0) for (%arg7) : i32 = (%arg0) to (%arg1) step (%arg2) { // CHECK: call void @__kmpc_ordered(ptr @[[GLOB3:[0-9]+]], i32 [[OMP_THREAD2:%.*]]) - omp.ordered_region { + omp.ordered.region { omp.terminator // CHECK: call void @__kmpc_end_ordered(ptr @[[GLOB3]], i32 [[OMP_THREAD2]]) } diff --git a/mlir/test/Target/LLVMIR/openmp-reduction-byref.mlir b/mlir/test/Target/LLVMIR/openmp-reduction-byref.mlir index 4ac1ebd43e1e..e720969e82c1 100644 --- a/mlir/test/Target/LLVMIR/openmp-reduction-byref.mlir +++ b/mlir/test/Target/LLVMIR/openmp-reduction-byref.mlir @@ -1,6 +1,6 @@ // RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s - omp.reduction.declare @add_reduction_i_32 : !llvm.ptr init { + omp.declare_reduction @add_reduction_i_32 : !llvm.ptr init { ^bb0(%arg0: !llvm.ptr): %0 = llvm.mlir.constant(0 : i32) : i32 %1 = llvm.mlir.constant(1 : i64) : i64 diff --git a/mlir/test/Target/LLVMIR/openmp-reduction-call.mlir b/mlir/test/Target/LLVMIR/openmp-reduction-call.mlir index 9aa9ac7e4b5a..da240f4a6fff 100644 --- a/mlir/test/Target/LLVMIR/openmp-reduction-call.mlir +++ b/mlir/test/Target/LLVMIR/openmp-reduction-call.mlir @@ -2,7 +2,7 @@ // Test that we don't crash when there is a call operation in the combiner -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = llvm.mlir.constant(0.0 : f32) : f32 diff --git a/mlir/test/Target/LLVMIR/openmp-reduction.mlir b/mlir/test/Target/LLVMIR/openmp-reduction.mlir index 8c3c9cd1aa26..39b64d71a227 100644 --- a/mlir/test/Target/LLVMIR/openmp-reduction.mlir +++ b/mlir/test/Target/LLVMIR/openmp-reduction.mlir @@ -3,7 +3,7 @@ // Only check the overall shape of the code and the presence of relevant // runtime calls. Actual IR checking is done at the OpenMPIRBuilder level. -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = llvm.mlir.constant(0.0 : f32) : f32 @@ -78,7 +78,7 @@ llvm.func @simple_reduction(%lb : i64, %ub : i64, %step : i64) { // ----- -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = llvm.mlir.constant(0.0 : f32) : f32 @@ -170,7 +170,7 @@ llvm.func @reuse_declaration(%lb : i64, %ub : i64, %step : i64) { // ----- -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = llvm.mlir.constant(0.0 : f32) : f32 @@ -255,7 +255,7 @@ llvm.func @missing_omp_reduction(%lb : i64, %ub : i64, %step : i64) { // ----- -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = llvm.mlir.constant(0.0 : f32) : f32 @@ -338,7 +338,7 @@ llvm.func @double_reference(%lb : i64, %ub : i64, %step : i64) { // ----- -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = llvm.mlir.constant(0.0 : f32) : f32 @@ -356,7 +356,7 @@ atomic { omp.yield } -omp.reduction.declare @mul_f32 : f32 +omp.declare_reduction @mul_f32 : f32 init { ^bb0(%arg: f32): %0 = llvm.mlir.constant(1.0 : f32) : f32 @@ -435,7 +435,7 @@ llvm.func @no_atomic(%lb : i64, %ub : i64, %step : i64) { // ----- -omp.reduction.declare @add_f32 : f32 +omp.declare_reduction @add_f32 : f32 init { ^bb0(%arg: f32): %0 = llvm.mlir.constant(0.0 : f32) : f32 @@ -504,7 +504,7 @@ llvm.func @simple_reduction_parallel() { // ----- -omp.reduction.declare @add_i32 : i32 +omp.declare_reduction @add_i32 : i32 init { ^bb0(%arg: i32): %0 = llvm.mlir.constant(0 : i32) : i32 -- GitLab From 7ccb31a5bcd60d6e691a57bf02ebd1e1ebfbe675 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <llvm-dev@redking.me.uk> Date: Wed, 20 Mar 2024 11:14:31 +0000 Subject: [PATCH 223/307] [X86] splitVectorOp - share the same SDLoc argument instead of recreating it over and over again. --- llvm/lib/Target/X86/X86ISelLowering.cpp | 95 +++++++++++++------------ 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 8a6594230f0a..35f756ea5e1d 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -4070,10 +4070,9 @@ static std::pair<SDValue, SDValue> splitVector(SDValue Op, SelectionDAG &DAG, } /// Break an operation into 2 half sized ops and then concatenate the results. -static SDValue splitVectorOp(SDValue Op, SelectionDAG &DAG) { +static SDValue splitVectorOp(SDValue Op, SelectionDAG &DAG, const SDLoc &dl) { unsigned NumOps = Op.getNumOperands(); EVT VT = Op.getValueType(); - SDLoc dl(Op); // Extract the LHS Lo/Hi vectors SmallVector<SDValue> LoOps(NumOps, SDValue()); @@ -4096,7 +4095,8 @@ static SDValue splitVectorOp(SDValue Op, SelectionDAG &DAG) { /// Break an unary integer operation into 2 half sized ops and then /// concatenate the result back. -static SDValue splitVectorIntUnary(SDValue Op, SelectionDAG &DAG) { +static SDValue splitVectorIntUnary(SDValue Op, SelectionDAG &DAG, + const SDLoc &dl) { // Make sure we only try to split 256/512-bit types to avoid creating // narrow vectors. EVT VT = Op.getValueType(); @@ -4107,19 +4107,20 @@ static SDValue splitVectorIntUnary(SDValue Op, SelectionDAG &DAG) { assert(Op.getOperand(0).getValueType().getVectorNumElements() == VT.getVectorNumElements() && "Unexpected VTs!"); - return splitVectorOp(Op, DAG); + return splitVectorOp(Op, DAG, dl); } /// Break a binary integer operation into 2 half sized ops and then /// concatenate the result back. -static SDValue splitVectorIntBinary(SDValue Op, SelectionDAG &DAG) { +static SDValue splitVectorIntBinary(SDValue Op, SelectionDAG &DAG, + const SDLoc &dl) { // Assert that all the types match. EVT VT = Op.getValueType(); (void)VT; assert(Op.getOperand(0).getValueType() == VT && Op.getOperand(1).getValueType() == VT && "Unexpected VTs!"); assert((VT.is256BitVector() || VT.is512BitVector()) && "Unsupported VT!"); - return splitVectorOp(Op, DAG); + return splitVectorOp(Op, DAG, dl); } // Helper for splitting operands of an operation to legal target size and @@ -20075,7 +20076,7 @@ static SDValue LowerAVXExtend(SDValue Op, SelectionDAG &DAG, if (VT == MVT::v32i16 && !Subtarget.hasBWI()) { assert(InVT == MVT::v32i8 && "Unexpected VT!"); - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, dl); } if (Subtarget.hasInt256()) @@ -20656,7 +20657,7 @@ SDValue X86TargetLowering::LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const { if (Subtarget.hasAVX512()) { if (InVT == MVT::v32i16 && !Subtarget.hasBWI()) { assert(VT == MVT::v32i8 && "Unexpected VT!"); - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, DL); } // word to byte only under BWI. Otherwise we have to promoted to v16i32 @@ -21636,7 +21637,8 @@ SDValue X86TargetLowering::LowerFP_TO_BF16(SDValue Op, /// Depending on uarch and/or optimizing for size, we might prefer to use a /// vector operation in place of the typical scalar operation. -static SDValue lowerAddSubToHorizontalOp(SDValue Op, SelectionDAG &DAG, +static SDValue lowerAddSubToHorizontalOp(SDValue Op, const SDLoc &DL, + SelectionDAG &DAG, const X86Subtarget &Subtarget) { // If both operands have other uses, this is probably not profitable. SDValue LHS = Op.getOperand(0); @@ -21692,7 +21694,6 @@ static SDValue lowerAddSubToHorizontalOp(SDValue Op, SelectionDAG &DAG, // Creating a 256-bit horizontal op would be wasteful, and there is no 512-bit // equivalent, so extract the 256/512-bit source op to 128-bit if we can. - SDLoc DL(Op); if (BitWidth == 256 || BitWidth == 512) { unsigned LaneIdx = LExtIndex / NumEltsPerLane; X = extract128BitVector(X, LaneIdx * NumEltsPerLane, DAG, DL); @@ -21713,7 +21714,7 @@ static SDValue lowerAddSubToHorizontalOp(SDValue Op, SelectionDAG &DAG, SDValue X86TargetLowering::lowerFaddFsub(SDValue Op, SelectionDAG &DAG) const { assert((Op.getValueType() == MVT::f32 || Op.getValueType() == MVT::f64) && "Only expecting float/double"); - return lowerAddSubToHorizontalOp(Op, DAG, Subtarget); + return lowerAddSubToHorizontalOp(Op, SDLoc(Op), DAG, Subtarget); } /// ISD::FROUND is defined to round to nearest with ties rounding away from 0. @@ -24470,7 +24471,7 @@ static SDValue LowerSIGN_EXTEND(SDValue Op, const X86Subtarget &Subtarget, if (VT == MVT::v32i16 && !Subtarget.hasBWI()) { assert(InVT == MVT::v32i8 && "Unexpected VT!"); - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, dl); } if (Subtarget.hasInt256()) @@ -27833,7 +27834,7 @@ static SDValue LowerVectorCTLZ_AVX512CDI(SDValue Op, SelectionDAG &DAG, // Split vector, it's Lo and Hi parts will be handled in next iteration. if (NumElems > 16 || (NumElems == 16 && !Subtarget.canExtendTo512DQ())) - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, dl); MVT NewVT = MVT::getVectorVT(MVT::i32, NumElems); assert((NewVT.is256BitVector() || NewVT.is512BitVector()) && @@ -27943,11 +27944,11 @@ static SDValue LowerVectorCTLZ(SDValue Op, const SDLoc &DL, // Decompose 256-bit ops into smaller 128-bit ops. if (VT.is256BitVector() && !Subtarget.hasInt256()) - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, DL); // Decompose 512-bit ops into smaller 256-bit ops. if (VT.is512BitVector() && !Subtarget.hasBWI()) - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, DL); assert(Subtarget.hasSSSE3() && "Expected SSSE3 support for PSHUFB"); return LowerVectorCTLZInRegLUT(Op, DL, Subtarget, DAG); @@ -28020,16 +28021,18 @@ static SDValue LowerCTTZ(SDValue Op, const X86Subtarget &Subtarget, static SDValue lowerAddSub(SDValue Op, SelectionDAG &DAG, const X86Subtarget &Subtarget) { MVT VT = Op.getSimpleValueType(); + SDLoc DL(Op); + if (VT == MVT::i16 || VT == MVT::i32) - return lowerAddSubToHorizontalOp(Op, DAG, Subtarget); + return lowerAddSubToHorizontalOp(Op, DL, DAG, Subtarget); if (VT == MVT::v32i16 || VT == MVT::v64i8) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, DL); assert(Op.getSimpleValueType().is256BitVector() && Op.getSimpleValueType().isInteger() && "Only handle AVX 256-bit vector integer operation"); - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, DL); } static SDValue LowerADDSAT_SUBSAT(SDValue Op, SelectionDAG &DAG, @@ -28043,7 +28046,7 @@ static SDValue LowerADDSAT_SUBSAT(SDValue Op, SelectionDAG &DAG, (VT.is256BitVector() && !Subtarget.hasInt256())) { assert(Op.getSimpleValueType().isInteger() && "Only handle AVX vector integer operation"); - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, DL); } // Avoid the generic expansion with min/max if we don't have pminu*/pmaxu*. @@ -28105,10 +28108,11 @@ static SDValue LowerADDSAT_SUBSAT(SDValue Op, SelectionDAG &DAG, static SDValue LowerABS(SDValue Op, const X86Subtarget &Subtarget, SelectionDAG &DAG) { MVT VT = Op.getSimpleValueType(); + SDLoc DL(Op); + if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64) { // Since X86 does not have CMOV for 8-bit integer, we don't convert // 8-bit integer abs to NEG and CMOV. - SDLoc DL(Op); SDValue N0 = Op.getOperand(0); SDValue Neg = DAG.getNode(X86ISD::SUB, DL, DAG.getVTList(VT, MVT::i32), DAG.getConstant(0, DL, VT), N0); @@ -28119,7 +28123,6 @@ static SDValue LowerABS(SDValue Op, const X86Subtarget &Subtarget, // ABS(vXi64 X) --> VPBLENDVPD(X, 0-X, X). if ((VT == MVT::v2i64 || VT == MVT::v4i64) && Subtarget.hasSSE41()) { - SDLoc DL(Op); SDValue Src = Op.getOperand(0); SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Src); @@ -28129,11 +28132,11 @@ static SDValue LowerABS(SDValue Op, const X86Subtarget &Subtarget, if (VT.is256BitVector() && !Subtarget.hasInt256()) { assert(VT.isInteger() && "Only handle AVX 256-bit vector integer operation"); - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, DL); } if ((VT == MVT::v32i16 || VT == MVT::v64i8) && !Subtarget.hasBWI()) - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, DL); // Default to expand. return SDValue(); @@ -28142,13 +28145,14 @@ static SDValue LowerABS(SDValue Op, const X86Subtarget &Subtarget, static SDValue LowerAVG(SDValue Op, const X86Subtarget &Subtarget, SelectionDAG &DAG) { MVT VT = Op.getSimpleValueType(); + SDLoc DL(Op); // For AVX1 cases, split to use legal ops. if (VT.is256BitVector() && !Subtarget.hasInt256()) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, DL); if (VT == MVT::v32i16 || VT == MVT::v64i8) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, DL); // Default to expand. return SDValue(); @@ -28157,13 +28161,14 @@ static SDValue LowerAVG(SDValue Op, const X86Subtarget &Subtarget, static SDValue LowerMINMAX(SDValue Op, const X86Subtarget &Subtarget, SelectionDAG &DAG) { MVT VT = Op.getSimpleValueType(); + SDLoc DL(Op); // For AVX1 cases, split to use legal ops. if (VT.is256BitVector() && !Subtarget.hasInt256()) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, DL); if (VT == MVT::v32i16 || VT == MVT::v64i8) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, DL); // Default to expand. return SDValue(); @@ -28320,15 +28325,15 @@ static SDValue LowerFMINIMUM_FMAXIMUM(SDValue Op, const X86Subtarget &Subtarget, static SDValue LowerABD(SDValue Op, const X86Subtarget &Subtarget, SelectionDAG &DAG) { MVT VT = Op.getSimpleValueType(); + SDLoc dl(Op); // For AVX1 cases, split to use legal ops. if (VT.is256BitVector() && !Subtarget.hasInt256()) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, dl); if ((VT == MVT::v32i16 || VT == MVT::v64i8) && !Subtarget.useBWIRegs()) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, dl); - SDLoc dl(Op); bool IsSigned = Op.getOpcode() == ISD::ABDS; const TargetLowering &TLI = DAG.getTargetLoweringInfo(); @@ -28371,10 +28376,10 @@ static SDValue LowerMUL(SDValue Op, const X86Subtarget &Subtarget, // Decompose 256-bit ops into 128-bit ops. if (VT.is256BitVector() && !Subtarget.hasInt256()) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, dl); if ((VT == MVT::v32i16 || VT == MVT::v64i8) && !Subtarget.hasBWI()) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, dl); SDValue A = Op.getOperand(0); SDValue B = Op.getOperand(1); @@ -28597,10 +28602,10 @@ static SDValue LowerMULH(SDValue Op, const X86Subtarget &Subtarget, // Decompose 256-bit ops into 128-bit ops. if (VT.is256BitVector() && !Subtarget.hasInt256()) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, dl); if ((VT == MVT::v32i16 || VT == MVT::v64i8) && !Subtarget.hasBWI()) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, dl); if (VT == MVT::v4i32 || VT == MVT::v8i32 || VT == MVT::v16i32) { assert((VT == MVT::v4i32 && Subtarget.hasSSE2()) || @@ -29778,10 +29783,10 @@ static SDValue LowerShift(SDValue Op, const X86Subtarget &Subtarget, // Decompose 256-bit shifts into 128-bit shifts. if (VT.is256BitVector()) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, dl); if (VT == MVT::v32i16 || VT == MVT::v64i8) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, dl); return SDValue(); } @@ -29858,7 +29863,7 @@ static SDValue LowerFunnelShift(SDValue Op, const X86Subtarget &Subtarget, EltSizeInBits < 32)) { // Pre-mask the amount modulo using the wider vector. Op = DAG.getNode(Op.getOpcode(), DL, VT, Op0, Op1, AmtMod); - return splitVectorOp(Op, DAG); + return splitVectorOp(Op, DAG, DL); } // Attempt to fold scalar shift as unpack(y,x) << zext(splat(z)) @@ -30020,7 +30025,7 @@ static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget, // Split 256-bit integers on XOP/pre-AVX2 targets. if (VT.is256BitVector() && (Subtarget.hasXOP() || !Subtarget.hasAVX2())) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, DL); // XOP has 128-bit vector variable + immediate rotates. // +ve/-ve Amt = rotate left/right - just need to handle ISD::ROTL. @@ -30056,7 +30061,7 @@ static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget, // Split 512-bit integers on non 512-bit BWI targets. if (VT.is512BitVector() && !Subtarget.useBWIRegs()) - return splitVectorIntBinary(Op, DAG); + return splitVectorIntBinary(Op, DAG, DL); assert( (VT == MVT::v4i32 || VT == MVT::v8i16 || VT == MVT::v16i8 || @@ -31136,11 +31141,11 @@ static SDValue LowerVectorCTPOP(SDValue Op, const SDLoc &DL, // Decompose 256-bit ops into smaller 128-bit ops. if (VT.is256BitVector() && !Subtarget.hasInt256()) - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, DL); // Decompose 512-bit ops into smaller 256-bit ops. if (VT.is512BitVector() && !Subtarget.hasBWI()) - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, DL); // For element types greater than i8, do vXi8 pop counts and a bytesum. if (VT.getScalarType() != MVT::i8) { @@ -31264,7 +31269,7 @@ static SDValue LowerBITREVERSE_XOP(SDValue Op, SelectionDAG &DAG) { // Decompose 256-bit ops into smaller 128-bit ops. if (VT.is256BitVector()) - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, DL); assert(VT.is128BitVector() && "Only 128-bit vector bitreverse lowering supported."); @@ -31303,11 +31308,11 @@ static SDValue LowerBITREVERSE(SDValue Op, const X86Subtarget &Subtarget, // Split 512-bit ops without BWI so that we can still use the PSHUFB lowering. if (VT.is512BitVector() && !Subtarget.hasBWI()) - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, DL); // Decompose 256-bit ops into smaller 128-bit ops on pre-AVX2. if (VT.is256BitVector() && !Subtarget.hasInt256()) - return splitVectorIntUnary(Op, DAG); + return splitVectorIntUnary(Op, DAG, DL); // Lower vXi16/vXi32/vXi64 as BSWAP + vXi8 BITREVERSE. if (VT.getScalarType() != MVT::i8) { @@ -55980,7 +55985,7 @@ static SDValue combineEXTRACT_SUBVECTOR(SDNode *N, SelectionDAG &DAG, if (isConcatenatedNot(InVecBC.getOperand(0)) || isConcatenatedNot(InVecBC.getOperand(1))) { // extract (and v4i64 X, (not (concat Y1, Y2))), n -> andnp v2i64 X(n), Y1 - SDValue Concat = splitVectorIntBinary(InVecBC, DAG); + SDValue Concat = splitVectorIntBinary(InVecBC, DAG, SDLoc(InVecBC)); return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, DAG.getBitcast(InVecVT, Concat), N->getOperand(1)); } -- GitLab From f24d68a1078c4330a764a837eff58e9934637c1a Mon Sep 17 00:00:00 2001 From: Jay Foad <jay.foad@amd.com> Date: Wed, 20 Mar 2024 10:45:57 +0000 Subject: [PATCH 224/307] [AMDGPU] Remove FLAT_Real_AllAddr_gfx11 in favor of GLOBAL_Real_AllAddr_gfx11 Plus some related cleanups. NFC. --- llvm/lib/Target/AMDGPU/FLATInstructions.td | 66 +++++++++------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/FLATInstructions.td b/llvm/lib/Target/AMDGPU/FLATInstructions.td index 6526a7f9fc41..c91fa1477098 100644 --- a/llvm/lib/Target/AMDGPU/FLATInstructions.td +++ b/llvm/lib/Target/AMDGPU/FLATInstructions.td @@ -2365,12 +2365,6 @@ multiclass FLAT_Real_Base_gfx11<bits<7> op, FLAT_Aliases_gfx11<name>, FLAT_Real_gfx11<op, name>; -multiclass FLAT_Real_AllAddr_gfx11<bits<7> op, - string name = get_FLAT_ps<NAME>.Mnemonic> : - FLAT_Real_Base_gfx11<op, name> { - defm _SADDR : FLAT_Real_gfx11<op, name>; -} - multiclass FLAT_Real_Atomics_gfx11<bits<7> op, string name = get_FLAT_ps<NAME>.Mnemonic> : FLAT_Real_Base_gfx11<op, name> { @@ -2379,8 +2373,7 @@ multiclass FLAT_Real_Atomics_gfx11<bits<7> op, multiclass GLOBAL_Real_AllAddr_gfx11<bits<7> op, string name = get_FLAT_ps<NAME>.Mnemonic> : - FLAT_Aliases_gfx11<name>, - FLAT_Real_gfx11<op, name> { + FLAT_Real_Base_gfx11<op, name> { defm _SADDR : FLAT_Real_gfx11<op, name>; } @@ -2393,8 +2386,7 @@ multiclass GLOBAL_Real_Atomics_gfx11<bits<7> op, multiclass SCRATCH_Real_AllAddr_gfx11<bits<7> op, string name = get_FLAT_ps<NAME>.Mnemonic> : - FLAT_Aliases_gfx11<name>, - FLAT_Real_gfx11<op, name> { + FLAT_Real_Base_gfx11<op, name> { defm _SADDR : FLAT_Real_gfx11<op, name>; defm _ST : FLAT_Real_gfx11<op, name>; defm _SVS : FLAT_Real_gfx11<op, name>; @@ -2455,30 +2447,30 @@ defm FLAT_ATOMIC_FMAX : FLAT_Real_Atomics_gfx11<0x052, "flat_atomic_ma defm FLAT_ATOMIC_ADD_F32 : FLAT_Real_Atomics_gfx11<0x056>; // ENC_FLAT_GLBL. -defm GLOBAL_LOAD_UBYTE : FLAT_Real_AllAddr_gfx11<0x010, "global_load_u8">; -defm GLOBAL_LOAD_SBYTE : FLAT_Real_AllAddr_gfx11<0x011, "global_load_i8">; -defm GLOBAL_LOAD_USHORT : FLAT_Real_AllAddr_gfx11<0x012, "global_load_u16">; -defm GLOBAL_LOAD_SSHORT : FLAT_Real_AllAddr_gfx11<0x013, "global_load_i16">; -defm GLOBAL_LOAD_DWORD : FLAT_Real_AllAddr_gfx11<0x014, "global_load_b32">; -defm GLOBAL_LOAD_DWORDX2 : FLAT_Real_AllAddr_gfx11<0x015, "global_load_b64">; -defm GLOBAL_LOAD_DWORDX3 : FLAT_Real_AllAddr_gfx11<0x016, "global_load_b96">; -defm GLOBAL_LOAD_DWORDX4 : FLAT_Real_AllAddr_gfx11<0x017, "global_load_b128">; -defm GLOBAL_STORE_BYTE : FLAT_Real_AllAddr_gfx11<0x018, "global_store_b8">; -defm GLOBAL_STORE_SHORT : FLAT_Real_AllAddr_gfx11<0x019, "global_store_b16">; -defm GLOBAL_STORE_DWORD : FLAT_Real_AllAddr_gfx11<0x01a, "global_store_b32">; -defm GLOBAL_STORE_DWORDX2 : FLAT_Real_AllAddr_gfx11<0x01b, "global_store_b64">; -defm GLOBAL_STORE_DWORDX3 : FLAT_Real_AllAddr_gfx11<0x01c, "global_store_b96">; -defm GLOBAL_STORE_DWORDX4 : FLAT_Real_AllAddr_gfx11<0x01d, "global_store_b128">; -defm GLOBAL_LOAD_UBYTE_D16 : FLAT_Real_AllAddr_gfx11<0x01e, "global_load_d16_u8">; -defm GLOBAL_LOAD_SBYTE_D16 : FLAT_Real_AllAddr_gfx11<0x01f, "global_load_d16_i8">; -defm GLOBAL_LOAD_SHORT_D16 : FLAT_Real_AllAddr_gfx11<0x020, "global_load_d16_b16">; -defm GLOBAL_LOAD_UBYTE_D16_HI : FLAT_Real_AllAddr_gfx11<0x021, "global_load_d16_hi_u8">; -defm GLOBAL_LOAD_SBYTE_D16_HI : FLAT_Real_AllAddr_gfx11<0x022, "global_load_d16_hi_i8">; -defm GLOBAL_LOAD_SHORT_D16_HI : FLAT_Real_AllAddr_gfx11<0x023, "global_load_d16_hi_b16">; -defm GLOBAL_STORE_BYTE_D16_HI : FLAT_Real_AllAddr_gfx11<0x024, "global_store_d16_hi_b8">; -defm GLOBAL_STORE_SHORT_D16_HI : FLAT_Real_AllAddr_gfx11<0x025, "global_store_d16_hi_b16">; -defm GLOBAL_LOAD_DWORD_ADDTID : FLAT_Real_AllAddr_gfx11<0x028, "global_load_addtid_b32">; -defm GLOBAL_STORE_DWORD_ADDTID : FLAT_Real_AllAddr_gfx11<0x029, "global_store_addtid_b32">; +defm GLOBAL_LOAD_UBYTE : GLOBAL_Real_AllAddr_gfx11<0x010, "global_load_u8">; +defm GLOBAL_LOAD_SBYTE : GLOBAL_Real_AllAddr_gfx11<0x011, "global_load_i8">; +defm GLOBAL_LOAD_USHORT : GLOBAL_Real_AllAddr_gfx11<0x012, "global_load_u16">; +defm GLOBAL_LOAD_SSHORT : GLOBAL_Real_AllAddr_gfx11<0x013, "global_load_i16">; +defm GLOBAL_LOAD_DWORD : GLOBAL_Real_AllAddr_gfx11<0x014, "global_load_b32">; +defm GLOBAL_LOAD_DWORDX2 : GLOBAL_Real_AllAddr_gfx11<0x015, "global_load_b64">; +defm GLOBAL_LOAD_DWORDX3 : GLOBAL_Real_AllAddr_gfx11<0x016, "global_load_b96">; +defm GLOBAL_LOAD_DWORDX4 : GLOBAL_Real_AllAddr_gfx11<0x017, "global_load_b128">; +defm GLOBAL_STORE_BYTE : GLOBAL_Real_AllAddr_gfx11<0x018, "global_store_b8">; +defm GLOBAL_STORE_SHORT : GLOBAL_Real_AllAddr_gfx11<0x019, "global_store_b16">; +defm GLOBAL_STORE_DWORD : GLOBAL_Real_AllAddr_gfx11<0x01a, "global_store_b32">; +defm GLOBAL_STORE_DWORDX2 : GLOBAL_Real_AllAddr_gfx11<0x01b, "global_store_b64">; +defm GLOBAL_STORE_DWORDX3 : GLOBAL_Real_AllAddr_gfx11<0x01c, "global_store_b96">; +defm GLOBAL_STORE_DWORDX4 : GLOBAL_Real_AllAddr_gfx11<0x01d, "global_store_b128">; +defm GLOBAL_LOAD_UBYTE_D16 : GLOBAL_Real_AllAddr_gfx11<0x01e, "global_load_d16_u8">; +defm GLOBAL_LOAD_SBYTE_D16 : GLOBAL_Real_AllAddr_gfx11<0x01f, "global_load_d16_i8">; +defm GLOBAL_LOAD_SHORT_D16 : GLOBAL_Real_AllAddr_gfx11<0x020, "global_load_d16_b16">; +defm GLOBAL_LOAD_UBYTE_D16_HI : GLOBAL_Real_AllAddr_gfx11<0x021, "global_load_d16_hi_u8">; +defm GLOBAL_LOAD_SBYTE_D16_HI : GLOBAL_Real_AllAddr_gfx11<0x022, "global_load_d16_hi_i8">; +defm GLOBAL_LOAD_SHORT_D16_HI : GLOBAL_Real_AllAddr_gfx11<0x023, "global_load_d16_hi_b16">; +defm GLOBAL_STORE_BYTE_D16_HI : GLOBAL_Real_AllAddr_gfx11<0x024, "global_store_d16_hi_b8">; +defm GLOBAL_STORE_SHORT_D16_HI : GLOBAL_Real_AllAddr_gfx11<0x025, "global_store_d16_hi_b16">; +defm GLOBAL_LOAD_DWORD_ADDTID : GLOBAL_Real_AllAddr_gfx11<0x028, "global_load_addtid_b32">; +defm GLOBAL_STORE_DWORD_ADDTID : GLOBAL_Real_AllAddr_gfx11<0x029, "global_store_addtid_b32">; defm GLOBAL_ATOMIC_SWAP : GLOBAL_Real_Atomics_gfx11<0x033, "global_atomic_swap_b32">; defm GLOBAL_ATOMIC_CMPSWAP : GLOBAL_Real_Atomics_gfx11<0x034, "global_atomic_cmpswap_b32">; defm GLOBAL_ATOMIC_ADD : GLOBAL_Real_Atomics_gfx11<0x035, "global_atomic_add_u32">; @@ -2574,8 +2566,7 @@ multiclass VFLAT_Real_Atomics_gfx12<bits<8> op, multiclass VGLOBAL_Real_AllAddr_gfx12<bits<8> op, string name = get_FLAT_ps<NAME>.Mnemonic, string alias = name> : - VFLAT_Aliases_gfx12<name, alias>, - VFLAT_Real_gfx12<op, name> { + VFLAT_Real_Base_gfx12<op, name, alias> { defm _SADDR : VFLAT_Real_gfx12<op, name>; } @@ -2598,8 +2589,7 @@ multiclass VGLOBAL_Real_Atomics_gfx12<bits<8> op, multiclass VSCRATCH_Real_AllAddr_gfx12<bits<8> op, string name = get_FLAT_ps<NAME>.Mnemonic> : - VFLAT_Aliases_gfx12<name>, - VFLAT_Real_gfx12<op, name> { + VFLAT_Real_Base_gfx12<op, name> { defm _SADDR : VFLAT_Real_gfx12<op, name>; defm _ST : VFLAT_Real_gfx12<op, name>; defm _SVS : VFLAT_Real_gfx12<op, name>; -- GitLab From e66cfebb04ff4fcf313905f49dbd863e7113432c Mon Sep 17 00:00:00 2001 From: Andreas Jonson <andjo403@hotmail.com> Date: Wed, 20 Mar 2024 12:43:00 +0100 Subject: [PATCH 225/307] [ValueTracking] Handle range attributes (#85143) Handle the range attribute in ValueTracking. --- llvm/include/llvm/IR/Argument.h | 7 + llvm/include/llvm/IR/InstrTypes.h | 7 +- llvm/lib/Analysis/InstructionSimplify.cpp | 13 +- llvm/lib/Analysis/ValueTracking.cpp | 38 ++++- llvm/lib/IR/Function.cpp | 8 + llvm/lib/IR/Instructions.cpp | 8 + .../Analysis/ValueTracking/known-non-zero.ll | 147 ++++++++++++++++++ .../Transforms/InstSimplify/icmp-constant.ll | 128 +++++++++++++++ .../InstSimplify/shift-knownbits.ll | 139 +++++++++++++++++ 9 files changed, 481 insertions(+), 14 deletions(-) diff --git a/llvm/include/llvm/IR/Argument.h b/llvm/include/llvm/IR/Argument.h index f0c0ce75d2b7..3349f1306970 100644 --- a/llvm/include/llvm/IR/Argument.h +++ b/llvm/include/llvm/IR/Argument.h @@ -16,9 +16,12 @@ #include "llvm/ADT/Twine.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Value.h" +#include <optional> namespace llvm { +class ConstantRange; + /// This class represents an incoming formal argument to a Function. A formal /// argument, since it is ``formal'', does not contain an actual value but /// instead represents the type, argument number, and attributes of an argument @@ -67,6 +70,10 @@ public: /// disallowed floating-point values. Otherwise, fcNone is returned. FPClassTest getNoFPClass() const; + /// If this argument has a range attribute, return the value range of the + /// argument. Otherwise, std::nullopt is returned. + std::optional<ConstantRange> getRange() const; + /// Return true if this argument has the byval attribute. bool hasByValAttr() const; diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index fed21b992e3d..e8c2cba8418d 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -43,6 +43,7 @@ namespace llvm { class StringRef; class Type; class Value; +class ConstantRange; namespace Intrinsic { typedef unsigned ID; @@ -1917,7 +1918,7 @@ public: // Look at the callee, if available. if (const Function *F = getCalledFunction()) - return F->getAttributes().getRetAttr(Kind); + return F->getRetAttribute(Kind); return Attribute(); } @@ -2154,6 +2155,10 @@ public: /// parameter. FPClassTest getParamNoFPClass(unsigned i) const; + /// If this return value has a range attribute, return the value range of the + /// argument. Otherwise, std::nullopt is returned. + std::optional<ConstantRange> getRange() const; + /// Return true if the return value is known to be not null. /// This may be because it has the nonnull attribute, or because at least /// one byte is dereferenceable and the pointer is in addrspace(0). diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 06283cb4bb93..7a37ae86c7f3 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3736,15 +3736,10 @@ static std::optional<ConstantRange> getRange(Value *V, if (MDNode *MD = IIQ.getMetadata(I, LLVMContext::MD_range)) return getConstantRangeFromMetadata(*MD); - Attribute Range; - if (const Argument *A = dyn_cast<Argument>(V)) { - Range = A->getAttribute(llvm::Attribute::Range); - } else if (const CallBase *CB = dyn_cast<CallBase>(V)) { - Range = CB->getRetAttr(llvm::Attribute::Range); - } - - if (Range.isValid()) - return Range.getRange(); + if (const Argument *A = dyn_cast<Argument>(V)) + return A->getRange(); + else if (const CallBase *CB = dyn_cast<CallBase>(V)) + return CB->getRange(); return std::nullopt; } diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 58bc68b576b0..797665cf06c8 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1500,14 +1500,20 @@ static void computeKnownBitsFromOperator(const Operator *I, break; } case Instruction::Call: - case Instruction::Invoke: + case Instruction::Invoke: { // If range metadata is attached to this call, set known bits from that, // and then intersect with known bits based on other properties of the // function. if (MDNode *MD = Q.IIQ.getMetadata(cast<Instruction>(I), LLVMContext::MD_range)) computeKnownBitsFromRangeMetadata(*MD, Known); - if (const Value *RV = cast<CallBase>(I)->getReturnedArgOperand()) { + + const auto *CB = cast<CallBase>(I); + + if (std::optional<ConstantRange> Range = CB->getRange()) + Known = Known.unionWith(Range->toKnownBits()); + + if (const Value *RV = CB->getReturnedArgOperand()) { if (RV->getType() == I->getType()) { computeKnownBits(RV, Known2, Depth + 1, Q); Known = Known.unionWith(Known2); @@ -1679,6 +1685,7 @@ static void computeKnownBitsFromOperator(const Operator *I, } } break; + } case Instruction::ShuffleVector: { auto *Shuf = dyn_cast<ShuffleVectorInst>(I); // FIXME: Do we need to handle ConstantExpr involving shufflevectors? @@ -1933,6 +1940,10 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts, // assumptions. Confirm that we've handled them all. assert(!isa<ConstantData>(V) && "Unhandled constant data!"); + if (const auto *A = dyn_cast<Argument>(V)) + if (std::optional<ConstantRange> Range = A->getRange()) + Known = Range->toKnownBits(); + // All recursive calls that increase depth must come after this. if (Depth == MaxAnalysisRecursionDepth) return; @@ -2783,6 +2794,11 @@ static bool isKnownNonZeroFromOperator(const Operator *I, } else { if (MDNode *Ranges = Q.IIQ.getMetadata(Call, LLVMContext::MD_range)) return rangeMetadataExcludesValue(Ranges, APInt::getZero(BitWidth)); + if (std::optional<ConstantRange> Range = Call->getRange()) { + const APInt ZeroValue(Range->getBitWidth(), 0); + if (!Range->contains(ZeroValue)) + return true; + } if (const Value *RV = Call->getReturnedArgOperand()) if (RV->getType() == I->getType() && isKnownNonZero(RV, Depth, Q)) return true; @@ -2921,6 +2937,13 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, return false; } + if (const auto *A = dyn_cast<Argument>(V)) + if (std::optional<ConstantRange> Range = A->getRange()) { + const APInt ZeroValue(Range->getBitWidth(), 0); + if (!Range->contains(ZeroValue)) + return true; + } + if (!isa<Constant>(V) && isKnownNonZeroFromAssume(V, Q)) return true; @@ -9146,12 +9169,19 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned, // TODO: Return ConstantRange. setLimitForFPToI(cast<Instruction>(V), Lower, Upper); CR = ConstantRange::getNonEmpty(Lower, Upper); - } + } else if (const auto *A = dyn_cast<Argument>(V)) + if (std::optional<ConstantRange> Range = A->getRange()) + CR = *Range; - if (auto *I = dyn_cast<Instruction>(V)) + if (auto *I = dyn_cast<Instruction>(V)) { if (auto *Range = IIQ.getMetadata(I, LLVMContext::MD_range)) CR = CR.intersectWith(getConstantRangeFromMetadata(*Range)); + if (const auto *CB = dyn_cast<CallBase>(V)) + if (std::optional<ConstantRange> Range = CB->getRange()) + CR = CR.intersectWith(*Range); + } + if (CtxI && AC) { // Try to restrict the range based on information from assumptions. for (auto &AssumeVH : AC->assumptionsFor(V)) { diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index d22e1c123111..eb126f182ead 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -24,6 +24,7 @@ #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/GlobalValue.h" @@ -256,6 +257,13 @@ FPClassTest Argument::getNoFPClass() const { return getParent()->getParamNoFPClass(getArgNo()); } +std::optional<ConstantRange> Argument::getRange() const { + const Attribute RangeAttr = getAttribute(llvm::Attribute::Range); + if (RangeAttr.isValid()) + return RangeAttr.getRange(); + return std::nullopt; +} + bool Argument::hasNestAttr() const { if (!getType()->isPointerTy()) return false; return hasAttribute(Attribute::Nest); diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index c55d6cff84ed..494d50f89e37 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -19,6 +19,7 @@ #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" @@ -395,6 +396,13 @@ FPClassTest CallBase::getParamNoFPClass(unsigned i) const { return Mask; } +std::optional<ConstantRange> CallBase::getRange() const { + const Attribute RangeAttr = getRetAttr(llvm::Attribute::Range); + if (RangeAttr.isValid()) + return RangeAttr.getRange(); + return std::nullopt; +} + bool CallBase::isReturnNonNull() const { if (hasRetAttr(Attribute::NonNull)) return true; diff --git a/llvm/test/Analysis/ValueTracking/known-non-zero.ll b/llvm/test/Analysis/ValueTracking/known-non-zero.ll index 30d340dc725a..0159050d925c 100644 --- a/llvm/test/Analysis/ValueTracking/known-non-zero.ll +++ b/llvm/test/Analysis/ValueTracking/known-non-zero.ll @@ -1303,4 +1303,151 @@ define <2 x i1> @range_metadata_vec(ptr %p, <2 x i32> %x) { ret <2 x i1> %cmp } +define i1 @range_attr(i8 range(i8 1, 0) %x, i8 %y) { +; CHECK-LABEL: @range_attr( +; CHECK-NEXT: ret i1 false +; + %or = or i8 %y, %x + %cmp = icmp eq i8 %or, 0 + ret i1 %cmp +} + +define i1 @neg_range_attr(i8 range(i8 -1, 1) %x, i8 %y) { +; CHECK-LABEL: @neg_range_attr( +; CHECK-NEXT: [[I:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %or = or i8 %y, %x + %cmp = icmp eq i8 %or, 0 + ret i1 %cmp +} + +declare range(i8 1, 0) i8 @returns_non_zero_range_helper() +declare range(i8 -1, 1) i8 @returns_contain_zero_range_helper() + +define i1 @range_return(i8 %y) { +; CHECK-LABEL: @range_return( +; CHECK-NEXT: [[I:%.*]] = call i8 @returns_non_zero_range_helper() +; CHECK-NEXT: ret i1 false +; + %x = call i8 @returns_non_zero_range_helper() + %or = or i8 %y, %x + %cmp = icmp eq i8 %or, 0 + ret i1 %cmp +} + +define i1 @neg_range_return(i8 %y) { +; CHECK-LABEL: @neg_range_return( +; CHECK-NEXT: [[I:%.*]] = call i8 @returns_contain_zero_range_helper() +; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], [[I]] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %x = call i8 @returns_contain_zero_range_helper() + %or = or i8 %y, %x + %cmp = icmp eq i8 %or, 0 + ret i1 %cmp +} + +declare i8 @returns_i8_helper() + +define i1 @range_call(i8 %y) { +; CHECK-LABEL: @range_call( +; CHECK-NEXT: [[I:%.*]] = call range(i8 1, 0) i8 @returns_i8_helper() +; CHECK-NEXT: ret i1 false +; + %x = call range(i8 1, 0) i8 @returns_i8_helper() + %or = or i8 %y, %x + %cmp = icmp eq i8 %or, 0 + ret i1 %cmp +} + +define i1 @neg_range_call(i8 %y) { +; CHECK-LABEL: @neg_range_call( +; CHECK-NEXT: [[I:%.*]] = call range(i8 -1, 1) i8 @returns_i8_helper() +; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], [[I]] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %x = call range(i8 -1, 1) i8 @returns_i8_helper() + %or = or i8 %y, %x + %cmp = icmp eq i8 %or, 0 + ret i1 %cmp +} + +define <2 x i1> @range_attr_vec(<2 x i8> range(i8 1, 0) %x, <2 x i8> %y) { +; CHECK-LABEL: @range_attr_vec( +; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> +; + %or = or <2 x i8> %y, %x + %cmp = icmp ne <2 x i8> %or, zeroinitializer + ret <2 x i1> %cmp +} + +define <2 x i1> @neg_range_attr_vec(<2 x i8> range(i8 -1, 1) %x, <2 x i8> %y) { +; CHECK-LABEL: @neg_range_attr_vec( +; CHECK-NEXT: [[OR:%.*]] = or <2 x i8> [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[OR]], zeroinitializer +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %or = or <2 x i8> %y, %x + %cmp = icmp ne <2 x i8> %or, zeroinitializer + ret <2 x i1> %cmp +} + +declare range(i8 1, 0) <2 x i8> @returns_non_zero_range_helper_vec() +declare range(i8 -1, 1) <2 x i8> @returns_contain_zero_range_helper_vec() + +define <2 x i1> @range_return_vec(<2 x i8> %y) { +; CHECK-LABEL: @range_return_vec( +; CHECK-NEXT: [[I:%.*]] = call <2 x i8> @returns_non_zero_range_helper_vec() +; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> +; + %x = call <2 x i8> @returns_non_zero_range_helper_vec() + %or = or <2 x i8> %y, %x + %cmp = icmp ne <2 x i8> %or, zeroinitializer + ret <2 x i1> %cmp +} + +define <2 x i1> @neg_range_return_vec(<2 x i8> %y) { +; CHECK-LABEL: @neg_range_return_vec( +; CHECK-NEXT: [[I:%.*]] = call <2 x i8> @returns_contain_zero_range_helper_vec() +; CHECK-NEXT: [[OR:%.*]] = or <2 x i8> [[Y:%.*]], [[I]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[OR]], zeroinitializer +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %x = call <2 x i8> @returns_contain_zero_range_helper_vec() + %or = or <2 x i8> %y, %x + %cmp = icmp ne <2 x i8> %or, zeroinitializer + ret <2 x i1> %cmp +} + +declare <2 x i8> @returns_i8_helper_vec() + +define <2 x i1> @range_call_vec(<2 x i8> %y) { +; CHECK-LABEL: @range_call_vec( +; CHECK-NEXT: [[I:%.*]] = call range(i8 1, 0) <2 x i8> @returns_i8_helper_vec() +; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> +; + %x = call range(i8 1, 0) <2 x i8> @returns_i8_helper_vec() + %or = or <2 x i8> %y, %x + %cmp = icmp ne <2 x i8> %or, zeroinitializer + ret <2 x i1> %cmp +} + +define <2 x i1> @neg_range_call_vec(<2 x i8> %y) { +; CHECK-LABEL: @neg_range_call_vec( +; CHECK-NEXT: [[I:%.*]] = call range(i8 -1, 1) <2 x i8> @returns_i8_helper_vec() +; CHECK-NEXT: [[OR:%.*]] = or <2 x i8> [[Y:%.*]], [[I]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[OR]], zeroinitializer +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %x = call range(i8 -1, 1) <2 x i8> @returns_i8_helper_vec() + %or = or <2 x i8> %y, %x + %cmp = icmp ne <2 x i8> %or, zeroinitializer + ret <2 x i1> %cmp +} + + declare i32 @llvm.experimental.get.vector.length.i32(i32, i32, i1) diff --git a/llvm/test/Transforms/InstSimplify/icmp-constant.ll b/llvm/test/Transforms/InstSimplify/icmp-constant.ll index 04261f6f40b7..99bf11bd4e8c 100644 --- a/llvm/test/Transforms/InstSimplify/icmp-constant.ll +++ b/llvm/test/Transforms/InstSimplify/icmp-constant.ll @@ -1140,3 +1140,131 @@ define <2 x i1> @heterogeneous_constvector(<2 x i8> %x) { %c = icmp ult <2 x i8> %x, <i8 undef, i8 poison> ret <2 x i1> %c } + +define i1 @icmp_eq_constant_range_attr(i8 range(i8 0, 10) %i) { +; CHECK-LABEL: @icmp_eq_constant_range_attr( +; CHECK-NEXT: ret i1 false +; + %cmp = icmp eq i8 %i, 10 + ret i1 %cmp +} + +define i1 @neg_icmp_eq_constant_range_attr(i8 range(i8 0, 11) %i) { +; CHECK-LABEL: @neg_icmp_eq_constant_range_attr( +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I:%.*]], 10 +; CHECK-NEXT: ret i1 [[CMP]] +; + %cmp = icmp eq i8 %i, 10 + ret i1 %cmp +} + +declare range(i8 1, 0) i8 @returns_non_ten_range_helper() +declare range(i8 -1, 1) i8 @returns_contain_ten_range_helper() + +define i1 @icmp_eq_constant_range_return() { +; CHECK-LABEL: @icmp_eq_constant_range_return( +; CHECK-NEXT: [[I:%.*]] = call i8 @returns_non_ten_range_helper() +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 10 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i = call i8 @returns_non_ten_range_helper() + %cmp = icmp eq i8 %i, 10 + ret i1 %cmp +} + +define i1 @neg_icmp_eq_constant_range_return() { +; CHECK-LABEL: @neg_icmp_eq_constant_range_return( +; CHECK-NEXT: [[I:%.*]] = call i8 @returns_contain_ten_range_helper() +; CHECK-NEXT: ret i1 false +; + %i = call i8 @returns_contain_ten_range_helper() + %cmp = icmp eq i8 %i, 10 + ret i1 %cmp +} + +declare i8 @returns_i8_helper() + +define i1 @icmp_eq_constant_range_call() { +; CHECK-LABEL: @icmp_eq_constant_range_call( +; CHECK-NEXT: [[I:%.*]] = call range(i8 0, 10) i8 @returns_i8_helper() +; CHECK-NEXT: ret i1 false +; + %i = call range(i8 0, 10) i8 @returns_i8_helper() + %cmp = icmp eq i8 %i, 10 + ret i1 %cmp +} + +define i1 @neg_icmp_eq_constant_range_call() { +; CHECK-LABEL: @neg_icmp_eq_constant_range_call( +; CHECK-NEXT: [[I:%.*]] = call range(i8 0, 11) i8 @returns_i8_helper() +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 10 +; CHECK-NEXT: ret i1 [[CMP]] +; + %i = call range(i8 0, 11) i8 @returns_i8_helper() + %cmp = icmp eq i8 %i, 10 + ret i1 %cmp +} + +define <2 x i1> @icmp_eq_constant_range_attr_vec(<2 x i8> range(i8 0, 10) %i) { +; CHECK-LABEL: @icmp_eq_constant_range_attr_vec( +; CHECK-NEXT: ret <2 x i1> zeroinitializer +; + %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> + ret <2 x i1> %cmp +} + +define <2 x i1> @neg_icmp_eq_constant_range_attr_vec(<2 x i8> range(i8 0, 11) %i) { +; CHECK-LABEL: @neg_icmp_eq_constant_range_attr_vec( +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[I:%.*]], <i8 10, i8 10> +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> + ret <2 x i1> %cmp +} + +declare range(i8 0, 10) <2 x i8> @returns_non_ten_range_helper_vec() +declare range(i8 0, 11) <2 x i8> @returns_contain_ten_range_helper_vec() + +define <2 x i1> @icmp_eq_constant_range_return_vec() { +; CHECK-LABEL: @icmp_eq_constant_range_return_vec( +; CHECK-NEXT: [[I:%.*]] = call <2 x i8> @returns_non_ten_range_helper_vec() +; CHECK-NEXT: ret <2 x i1> zeroinitializer +; + %i = call <2 x i8> @returns_non_ten_range_helper_vec() + %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> + ret <2 x i1> %cmp +} + +define <2 x i1> @neg_icmp_eq_constant_range_return_vec() { +; CHECK-LABEL: @neg_icmp_eq_constant_range_return_vec( +; CHECK-NEXT: [[I:%.*]] = call <2 x i8> @returns_contain_ten_range_helper_vec() +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[I]], <i8 10, i8 10> +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %i = call <2 x i8> @returns_contain_ten_range_helper_vec() + %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> + ret <2 x i1> %cmp +} + +declare <2 x i8> @returns_i8_helper_vec() + +define <2 x i1> @icmp_eq_constant_range_call_vec() { +; CHECK-LABEL: @icmp_eq_constant_range_call_vec( +; CHECK-NEXT: [[I:%.*]] = call range(i8 0, 10) <2 x i8> @returns_i8_helper_vec() +; CHECK-NEXT: ret <2 x i1> zeroinitializer +; + %i = call range(i8 0, 10) <2 x i8> @returns_i8_helper_vec() + %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> + ret <2 x i1> %cmp +} + +define <2 x i1> @neg_icmp_eq_constant_range_call_vec() { +; CHECK-LABEL: @neg_icmp_eq_constant_range_call_vec( +; CHECK-NEXT: [[I:%.*]] = call range(i8 0, 11) <2 x i8> @returns_i8_helper_vec() +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[I]], <i8 10, i8 10> +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %i = call range(i8 0, 11) <2 x i8> @returns_i8_helper_vec() + %cmp = icmp eq <2 x i8> %i, <i8 10, i8 10> + ret <2 x i1> %cmp +} diff --git a/llvm/test/Transforms/InstSimplify/shift-knownbits.ll b/llvm/test/Transforms/InstSimplify/shift-knownbits.ll index c2256f4b14af..6bf03779379e 100644 --- a/llvm/test/Transforms/InstSimplify/shift-knownbits.ll +++ b/llvm/test/Transforms/InstSimplify/shift-knownbits.ll @@ -14,6 +14,145 @@ define i32 @shl_amount_is_known_bogus(i32 %a, i32 %b) { ret i32 %shl } +define i32 @shl_amount_is_known_bogus_range_attr(i32 %a, i32 range(i32 32, 64) %b) { +; CHECK-LABEL: @shl_amount_is_known_bogus_range_attr( +; CHECK-NEXT: ret i32 poison +; + %shl = shl i32 %a, %b + ret i32 %shl +} + +define i32 @neg_shl_amount_is_known_bogus_range_attr(i32 %a, i32 range(i32 0, 32) %b) { +; CHECK-LABEL: @neg_shl_amount_is_known_bogus_range_attr( +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: ret i32 [[SHL]] +; + %shl = shl i32 %a, %b + ret i32 %shl +} + +declare range(i32 32, 64) i32 @returns_out_of_range_helper() +declare range(i32 0, 32) i32 @returns_in_range_helper() + +define i32 @shl_amount_is_known_bogus_range_return(i32 %a) { +; CHECK-LABEL: @shl_amount_is_known_bogus_range_return( +; CHECK-NEXT: [[B:%.*]] = call i32 @returns_out_of_range_helper() +; CHECK-NEXT: ret i32 poison +; + %b = call i32 @returns_out_of_range_helper() + %shl = shl i32 %a, %b + ret i32 %shl +} + +define i32 @neg_shl_amount_is_known_bogus_range_return(i32 %a) { +; CHECK-LABEL: @neg_shl_amount_is_known_bogus_range_return( +; CHECK-NEXT: [[B:%.*]] = call i32 @returns_in_range_helper() +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[B]] +; CHECK-NEXT: ret i32 [[SHL]] +; + %b = call i32 @returns_in_range_helper() + %shl = shl i32 %a, %b + ret i32 %shl +} + +declare i32 @returns_i32_helper() + +define i32 @shl_amount_is_known_bogus_range_call(i32 %a) { +; CHECK-LABEL: @shl_amount_is_known_bogus_range_call( +; CHECK-NEXT: [[B:%.*]] = call range(i32 32, 64) i32 @returns_i32_helper() +; CHECK-NEXT: ret i32 poison +; + %b = call range(i32 32, 64) i32 @returns_i32_helper() + %shl = shl i32 %a, %b + ret i32 %shl +} + +define i32 @neg_shl_amount_is_known_bogus_range_call(i32 %a) { +; CHECK-LABEL: @neg_shl_amount_is_known_bogus_range_call( +; CHECK-NEXT: [[B:%.*]] = call range(i32 0, 32) i32 @returns_i32_helper() +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[B]] +; CHECK-NEXT: ret i32 [[SHL]] +; + %b = call range(i32 0, 32) i32 @returns_i32_helper() + %shl = shl i32 %a, %b + ret i32 %shl +} + +define <2 x i32> @shl_amount_is_known_bogus_range_attr_vec(<2 x i32> %a, <2 x i32> range(i32 32, 64) %b) { +; CHECK-LABEL: @shl_amount_is_known_bogus_range_attr_vec( +; CHECK-NEXT: ret <2 x i32> poison +; + %shl = shl <2 x i32> %a, %b + ret <2 x i32> %shl +} + +define <2 x i32> @neg_shl_amount_is_known_bogus_range_attr_vec(<2 x i32> %a, <2 x i32> range(i32 0, 32) %b) { +; CHECK-LABEL: @neg_shl_amount_is_known_bogus_range_attr_vec( +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: ret <2 x i32> [[SHL]] +; + %shl = shl <2 x i32> %a, %b + ret <2 x i32> %shl +} + +declare range(i32 32, 64) <2 x i32> @returns_out_of_range_helper_vec() +declare range(i32 0, 32) <2 x i32> @returns_in_range_helper_vec() + +define <2 x i32> @shl_amount_is_known_bogus_range_return_vec(<2 x i32> %a) { +; CHECK-LABEL: @shl_amount_is_known_bogus_range_return_vec( +; CHECK-NEXT: [[B:%.*]] = call <2 x i32> @returns_out_of_range_helper_vec() +; CHECK-NEXT: ret <2 x i32> poison +; + %b = call <2 x i32> @returns_out_of_range_helper_vec() + %shl = shl <2 x i32> %a, %b + ret <2 x i32> %shl +} + +define <2 x i32> @neg_shl_amount_is_known_bogus_range_return_vec(<2 x i32> %a) { +; CHECK-LABEL: @neg_shl_amount_is_known_bogus_range_return_vec( +; CHECK-NEXT: [[B:%.*]] = call <2 x i32> @returns_in_range_helper_vec() +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[A:%.*]], [[B]] +; CHECK-NEXT: ret <2 x i32> [[SHL]] +; + %b = call <2 x i32> @returns_in_range_helper_vec() + %shl = shl <2 x i32> %a, %b + ret <2 x i32> %shl +} + +declare <2 x i32> @returns_i32_helper_vec() + +define <2 x i32> @shl_amount_is_known_bogus_range_call_vec(<2 x i32> %a) { +; CHECK-LABEL: @shl_amount_is_known_bogus_range_call_vec( +; CHECK-NEXT: [[B:%.*]] = call range(i32 32, 64) <2 x i32> @returns_i32_helper_vec() +; CHECK-NEXT: ret <2 x i32> poison +; + %b = call range(i32 32, 64) <2 x i32> @returns_i32_helper_vec() + %shl = shl <2 x i32> %a, %b + ret <2 x i32> %shl +} + +define <2 x i32> @neg_shl_amount_is_known_bogus_range_call_vec(<2 x i32> %a) { +; CHECK-LABEL: @neg_shl_amount_is_known_bogus_range_call_vec( +; CHECK-NEXT: [[B:%.*]] = call range(i32 0, 32) <2 x i32> @returns_i32_helper_vec() +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[A:%.*]], [[B]] +; CHECK-NEXT: ret <2 x i32> [[SHL]] +; + %b = call range(i32 0, 32) <2 x i32> @returns_i32_helper_vec() + %shl = shl <2 x i32> %a, %b + ret <2 x i32> %shl +} + +define i32 @shl_amount_is_not_known_bogus_range_call_and_range_metadata(i32 %a) { +; CHECK-LABEL: @shl_amount_is_not_known_bogus_range_call_and_range_metadata( +; CHECK-NEXT: [[B:%.*]] = call range(i32 0, 32) i32 @returns_i32_helper(), !range [[RNG0:![0-9]+]] +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], [[B]] +; CHECK-NEXT: ret i32 [[SHL]] +; + %b = call range(i32 0, 32) i32 @returns_i32_helper(), !range !{ i32 32, i32 64 } + %shl = shl i32 %a, %b + ret i32 %shl +} + ; Check some weird types and the other shift ops. define i31 @lshr_amount_is_known_bogus(i31 %a, i31 %b) { -- GitLab From 4b369ff076d9205ddbcfcdef89276a737a83ce0e Mon Sep 17 00:00:00 2001 From: Fraser Cormack <fraser@codeplay.com> Date: Wed, 20 Mar 2024 11:43:13 +0000 Subject: [PATCH 226/307] [analyzer][NFC] Fix unused variable warning --- clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp index 1a9d6d3127fb..b36fa95bc73f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp @@ -43,8 +43,7 @@ tryToFindPtrOrigin(const Expr *E, bool StopAtFirstRefCountedObj) { if (auto *call = dyn_cast<CallExpr>(E)) { if (auto *memberCall = dyn_cast<CXXMemberCallExpr>(call)) { if (auto *decl = memberCall->getMethodDecl()) { - std::optional<bool> IsGetterOfRefCt = - isGetterOfRefCounted(memberCall->getMethodDecl()); + std::optional<bool> IsGetterOfRefCt = isGetterOfRefCounted(decl); if (IsGetterOfRefCt && *IsGetterOfRefCt) { E = memberCall->getImplicitObjectArgument(); if (StopAtFirstRefCountedObj) { -- GitLab From e52a68787122f8f17f2923818b98f3cea4e881a1 Mon Sep 17 00:00:00 2001 From: Pravin Jagtap <prjagtap@amd.com> Date: Wed, 20 Mar 2024 17:29:42 +0530 Subject: [PATCH 227/307] [AMDGPU][NFC] Test clean up (#85922) Authored-by: Pravin Jagtap <Pravin.Jagtap@amd.com> --- llvm/test/CodeGen/AMDGPU/bf16-conversions.ll | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/AMDGPU/bf16-conversions.ll b/llvm/test/CodeGen/AMDGPU/bf16-conversions.ll index 1eb2771618dc..7108f3d65768 100644 --- a/llvm/test/CodeGen/AMDGPU/bf16-conversions.ll +++ b/llvm/test/CodeGen/AMDGPU/bf16-conversions.ll @@ -2,6 +2,7 @@ ; RUN: llc -march=amdgcn -mcpu=gfx940 < %s | FileCheck --check-prefixes=GCN %s ; TODO: Add global-isel when it can support bf16 + define amdgpu_ps float @v_test_cvt_bf16_f32_v(bfloat %v) { ; GCN-LABEL: v_test_cvt_bf16_f32_v: ; GCN: ; %bb.0: @@ -10,6 +11,7 @@ define amdgpu_ps float @v_test_cvt_bf16_f32_v(bfloat %v) { %cvt = fpext bfloat %v to float ret float %cvt } + define amdgpu_ps float @v_test_cvt_bf16_f32_s(bfloat inreg %v) { ; GCN-LABEL: v_test_cvt_bf16_f32_s: ; GCN: ; %bb.0: @@ -19,6 +21,7 @@ define amdgpu_ps float @v_test_cvt_bf16_f32_s(bfloat inreg %v) { %cvt = fpext bfloat %v to float ret float %cvt } + define amdgpu_ps float @v_test_cvt_v2f32_v2bf16_v(<2 x float> %src) { ; GCN-LABEL: v_test_cvt_v2f32_v2bf16_v: ; GCN: ; %bb.0: @@ -42,6 +45,7 @@ define amdgpu_ps float @v_test_cvt_v2f32_v2bf16_v(<2 x float> %src) { %cast = bitcast <2 x bfloat> %res to float ret float %cast } + define amdgpu_ps float @v_test_cvt_v2f32_v2bf16_s(<2 x float> inreg %src) { ; GCN-LABEL: v_test_cvt_v2f32_v2bf16_s: ; GCN: ; %bb.0: @@ -66,6 +70,7 @@ define amdgpu_ps float @v_test_cvt_v2f32_v2bf16_s(<2 x float> inreg %src) { %cast = bitcast <2 x bfloat> %res to float ret float %cast } + define amdgpu_ps float @v_test_cvt_f32_bf16_v(float %src) { ; GCN-LABEL: v_test_cvt_f32_bf16_v: ; GCN: ; %bb.0: @@ -82,6 +87,7 @@ define amdgpu_ps float @v_test_cvt_f32_bf16_v(float %src) { %ext = fpext bfloat %trunc to float ret float %ext } + define amdgpu_ps float @v_test_cvt_v2f64_v2bf16_v(<2 x double> %src) { ; GCN-LABEL: v_test_cvt_v2f64_v2bf16_v: ; GCN: ; %bb.0: @@ -128,6 +134,7 @@ define amdgpu_ps float @v_test_cvt_v2f64_v2bf16_v(<2 x double> %src) { %cast = bitcast <2 x bfloat> %res to float ret float %cast } + define amdgpu_ps float @fptrunc_f32_f32_to_v2bf16(float %a, float %b) { ; GCN-LABEL: fptrunc_f32_f32_to_v2bf16: ; GCN: ; %bb.0: ; %entry @@ -155,6 +162,7 @@ entry: %ret = bitcast <2 x bfloat> %v2.2 to float ret float %ret } + define amdgpu_ps float @fptrunc_f32_f32_to_v2bf16_mods(float %a, float %b) { ; GCN-LABEL: fptrunc_f32_f32_to_v2bf16_mods: ; GCN: ; %bb.0: ; %entry @@ -186,6 +194,7 @@ entry: %ret = bitcast <2 x bfloat> %v2.2 to float ret float %ret } + define amdgpu_ps void @fptrunc_f32_to_bf16(float %a, ptr %out) { ; GCN-LABEL: fptrunc_f32_to_bf16: ; GCN: ; %bb.0: ; %entry @@ -205,6 +214,7 @@ entry: store bfloat %a.cvt, ptr %out ret void } + define amdgpu_ps void @fptrunc_f32_to_bf16_abs(float %a, ptr %out) { ; GCN-LABEL: fptrunc_f32_to_bf16_abs: ; GCN: ; %bb.0: ; %entry @@ -226,6 +236,7 @@ entry: store bfloat %a.cvt, ptr %out ret void } + define amdgpu_ps void @fptrunc_f32_to_bf16_neg(float %a, ptr %out) { ; GCN-LABEL: fptrunc_f32_to_bf16_neg: ; GCN: ; %bb.0: ; %entry @@ -247,6 +258,7 @@ entry: store bfloat %a.cvt, ptr %out ret void } + define amdgpu_ps void @fptrunc_f64_to_bf16(double %a, ptr %out) { ; GCN-LABEL: fptrunc_f64_to_bf16: ; GCN: ; %bb.0: ; %entry @@ -276,6 +288,7 @@ entry: store bfloat %a.cvt, ptr %out ret void } + define amdgpu_ps void @fptrunc_f64_to_bf16_neg(double %a, ptr %out) { ; GCN-LABEL: fptrunc_f64_to_bf16_neg: ; GCN: ; %bb.0: ; %entry @@ -307,6 +320,7 @@ entry: store bfloat %a.cvt, ptr %out ret void } + define amdgpu_ps void @fptrunc_f64_to_bf16_abs(double %a, ptr %out) { ; GCN-LABEL: fptrunc_f64_to_bf16_abs: ; GCN: ; %bb.0: ; %entry @@ -341,4 +355,3 @@ entry: declare float @llvm.fabs.f32(float) declare double @llvm.fabs.f64(double) - -- GitLab From 3a90cb4c1819c5ad90ba1cba266c5e94cc4ce230 Mon Sep 17 00:00:00 2001 From: Alexey Bataev <a.bataev@outlook.com> Date: Wed, 20 Mar 2024 04:40:03 -0700 Subject: [PATCH 228/307] Revert "[SLP]Do extra analysis int minbitwidth if some checks return false." This reverts commit da118c93b40f74f6770cf8550903721555d3c97b to fix crashes reported in https://github.com/llvm/llvm-project/pull/84363. --- .../Transforms/Vectorize/SLPVectorizer.cpp | 95 ++++++++----------- .../SLPVectorizer/AArch64/horizontal.ll | 20 ++-- 2 files changed, 51 insertions(+), 64 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index ac16fcf76745..e3711fe63efe 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -13988,6 +13988,15 @@ bool BoUpSLP::collectValuesToDemote( // If the value is not a vectorized instruction in the expression and not used // by the insertelement instruction and not used in multiple vector nodes, it // cannot be demoted. + // TODO: improve handling of gathered values and others. + auto *I = dyn_cast<Instruction>(V); + const TreeEntry *ITE = I ? getTreeEntry(I) : nullptr; + if (!ITE || !Visited.insert(I).second || MultiNodeScalars.contains(I) || + all_of(I->users(), [&](User *U) { + return isa<InsertElementInst>(U) && !getTreeEntry(U); + })) + return false; + auto IsPotentiallyTruncated = [&](Value *V, unsigned &BitWidth) -> bool { if (MultiNodeScalars.contains(V)) return false; @@ -14002,44 +14011,8 @@ bool BoUpSLP::collectValuesToDemote( BitWidth = std::max(BitWidth, BitWidth1); return BitWidth > 0 && OrigBitWidth >= (BitWidth * 2); }; - auto FinalAnalysis = [&](const TreeEntry *ITE = nullptr) { - if (!IsProfitableToDemote) - return false; - return (ITE && ITE->UserTreeIndices.size() > 1) || - IsPotentiallyTruncated(V, BitWidth); - }; - // TODO: improve handling of gathered values and others. - auto *I = dyn_cast<Instruction>(V); - const TreeEntry *ITE = I ? getTreeEntry(I) : nullptr; - if (!ITE || !Visited.insert(I).second || MultiNodeScalars.contains(I) || - all_of(I->users(), [&](User *U) { - return isa<InsertElementInst>(U) && !getTreeEntry(U); - })) - return FinalAnalysis(); - unsigned Start = 0; unsigned End = I->getNumOperands(); - - auto ProcessOperands = [&](ArrayRef<Value *> Operands, bool &NeedToExit) { - NeedToExit = false; - unsigned InitLevel = MaxDepthLevel; - for (Value *IncValue : Operands) { - unsigned Level = InitLevel; - if (!collectValuesToDemote(IncValue, IsProfitableToDemoteRoot, BitWidth, - ToDemote, DemotedConsts, Visited, Level, - IsProfitableToDemote, IsTruncRoot)) { - if (!IsProfitableToDemote) - return false; - NeedToExit = true; - if (!FinalAnalysis(ITE)) - return false; - continue; - } - MaxDepthLevel = std::max(MaxDepthLevel, Level); - } - return true; - }; - bool NeedToExit = false; switch (I->getOpcode()) { // We can always demote truncations and extensions. Since truncations can @@ -14065,21 +14038,35 @@ bool BoUpSLP::collectValuesToDemote( case Instruction::And: case Instruction::Or: case Instruction::Xor: { - if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) - return false; - if (!ProcessOperands({I->getOperand(0), I->getOperand(1)}, NeedToExit)) + unsigned Level1 = MaxDepthLevel, Level2 = MaxDepthLevel; + if ((ITE->UserTreeIndices.size() > 1 && + !IsPotentiallyTruncated(I, BitWidth)) || + !collectValuesToDemote(I->getOperand(0), IsProfitableToDemoteRoot, + BitWidth, ToDemote, DemotedConsts, Visited, + Level1, IsProfitableToDemote, IsTruncRoot) || + !collectValuesToDemote(I->getOperand(1), IsProfitableToDemoteRoot, + BitWidth, ToDemote, DemotedConsts, Visited, + Level2, IsProfitableToDemote, IsTruncRoot)) return false; + MaxDepthLevel = std::max(Level1, Level2); break; } // We can demote selects if we can demote their true and false values. case Instruction::Select: { - if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) - return false; Start = 1; - auto *SI = cast<SelectInst>(I); - if (!ProcessOperands({SI->getTrueValue(), SI->getFalseValue()}, NeedToExit)) + unsigned Level1 = MaxDepthLevel, Level2 = MaxDepthLevel; + SelectInst *SI = cast<SelectInst>(I); + if ((ITE->UserTreeIndices.size() > 1 && + !IsPotentiallyTruncated(I, BitWidth)) || + !collectValuesToDemote(SI->getTrueValue(), IsProfitableToDemoteRoot, + BitWidth, ToDemote, DemotedConsts, Visited, + Level1, IsProfitableToDemote, IsTruncRoot) || + !collectValuesToDemote(SI->getFalseValue(), IsProfitableToDemoteRoot, + BitWidth, ToDemote, DemotedConsts, Visited, + Level2, IsProfitableToDemote, IsTruncRoot)) return false; + MaxDepthLevel = std::max(Level1, Level2); break; } @@ -14089,20 +14076,23 @@ bool BoUpSLP::collectValuesToDemote( PHINode *PN = cast<PHINode>(I); if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) return false; - SmallVector<Value *> Ops(PN->incoming_values().begin(), - PN->incoming_values().end()); - if (!ProcessOperands(Ops, NeedToExit)) - return false; + unsigned InitLevel = MaxDepthLevel; + for (Value *IncValue : PN->incoming_values()) { + unsigned Level = InitLevel; + if (!collectValuesToDemote(IncValue, IsProfitableToDemoteRoot, BitWidth, + ToDemote, DemotedConsts, Visited, Level, + IsProfitableToDemote, IsTruncRoot)) + return false; + MaxDepthLevel = std::max(MaxDepthLevel, Level); + } break; } // Otherwise, conservatively give up. default: MaxDepthLevel = 1; - return FinalAnalysis(); + return IsProfitableToDemote && IsPotentiallyTruncated(I, BitWidth); } - if (NeedToExit) - return true; ++MaxDepthLevel; // Gather demoted constant operands. @@ -14141,7 +14131,6 @@ void BoUpSLP::computeMinimumValueSizes() { // The first value node for store/insertelement is sext/zext/trunc? Skip it, // resize to the final type. - bool IsTruncRoot = false; bool IsProfitableToDemoteRoot = !IsStoreOrInsertElt; if (NodeIdx != 0 && VectorizableTree[NodeIdx]->State == TreeEntry::Vectorize && @@ -14149,9 +14138,8 @@ void BoUpSLP::computeMinimumValueSizes() { VectorizableTree[NodeIdx]->getOpcode() == Instruction::SExt || VectorizableTree[NodeIdx]->getOpcode() == Instruction::Trunc)) { assert(IsStoreOrInsertElt && "Expected store/insertelement seeded graph."); - IsTruncRoot = VectorizableTree[NodeIdx]->getOpcode() == Instruction::Trunc; - IsProfitableToDemoteRoot = true; ++NodeIdx; + IsProfitableToDemoteRoot = true; } // Analyzed in reduction already and not profitable - exit. @@ -14283,6 +14271,7 @@ void BoUpSLP::computeMinimumValueSizes() { ReductionBitWidth = bit_ceil(ReductionBitWidth); } bool IsTopRoot = NodeIdx == 0; + bool IsTruncRoot = false; while (NodeIdx < VectorizableTree.size() && VectorizableTree[NodeIdx]->State == TreeEntry::Vectorize && VectorizableTree[NodeIdx]->getOpcode() == Instruction::Trunc) { diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll index 7c5f9847db1f..1986b51ec948 100644 --- a/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll +++ b/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll @@ -228,7 +228,7 @@ for.end: ; preds = %for.end.loopexit, % ; YAML-NEXT: Function: test_unrolled_select ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'Vectorized horizontal reduction with cost ' -; YAML-NEXT: - Cost: '-41' +; YAML-NEXT: - Cost: '-36' ; YAML-NEXT: - String: ' and with tree size ' ; YAML-NEXT: - TreeSize: '10' @@ -246,17 +246,15 @@ define i32 @test_unrolled_select(ptr noalias nocapture readonly %blk1, ptr noali ; CHECK-NEXT: [[P2_045:%.*]] = phi ptr [ [[BLK2:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR88:%.*]], [[IF_END_86]] ] ; CHECK-NEXT: [[P1_044:%.*]] = phi ptr [ [[BLK1:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR:%.*]], [[IF_END_86]] ] ; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[P1_044]], align 1 -; CHECK-NEXT: [[TMP1:%.*]] = zext <8 x i8> [[TMP0]] to <8 x i16> +; CHECK-NEXT: [[TMP1:%.*]] = zext <8 x i8> [[TMP0]] to <8 x i32> ; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i8>, ptr [[P2_045]], align 1 -; CHECK-NEXT: [[TMP3:%.*]] = zext <8 x i8> [[TMP2]] to <8 x i16> -; CHECK-NEXT: [[TMP4:%.*]] = sub <8 x i16> [[TMP1]], [[TMP3]] -; CHECK-NEXT: [[TMP5:%.*]] = sext <8 x i16> [[TMP4]] to <8 x i32> -; CHECK-NEXT: [[TMP6:%.*]] = icmp slt <8 x i32> [[TMP5]], zeroinitializer -; CHECK-NEXT: [[TMP7:%.*]] = sub <8 x i16> zeroinitializer, [[TMP4]] -; CHECK-NEXT: [[TMP8:%.*]] = select <8 x i1> [[TMP6]], <8 x i16> [[TMP7]], <8 x i16> [[TMP4]] -; CHECK-NEXT: [[TMP9:%.*]] = sext <8 x i16> [[TMP8]] to <8 x i32> -; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[TMP9]]) -; CHECK-NEXT: [[OP_RDX]] = add i32 [[TMP10]], [[S_047]] +; CHECK-NEXT: [[TMP3:%.*]] = zext <8 x i8> [[TMP2]] to <8 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = sub nsw <8 x i32> [[TMP1]], [[TMP3]] +; CHECK-NEXT: [[TMP5:%.*]] = icmp slt <8 x i32> [[TMP4]], zeroinitializer +; CHECK-NEXT: [[TMP6:%.*]] = sub nsw <8 x i32> zeroinitializer, [[TMP4]] +; CHECK-NEXT: [[TMP7:%.*]] = select <8 x i1> [[TMP5]], <8 x i32> [[TMP6]], <8 x i32> [[TMP4]] +; CHECK-NEXT: [[TMP8:%.*]] = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[TMP7]]) +; CHECK-NEXT: [[OP_RDX]] = add i32 [[TMP8]], [[S_047]] ; CHECK-NEXT: [[CMP83:%.*]] = icmp slt i32 [[OP_RDX]], [[LIM:%.*]] ; CHECK-NEXT: br i1 [[CMP83]], label [[IF_END_86]], label [[FOR_END_LOOPEXIT:%.*]] ; CHECK: if.end.86: -- GitLab From 81ec95ff983afd7f31c2713891bbc37bd630a100 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Wed, 20 Mar 2024 13:06:29 +0100 Subject: [PATCH 229/307] Silence -Wswitch warnings TypeSystemClang.cpp:4074:11: error: enumeration value 'CountAttributed' not handled in switch [-Werror,-Wswitch] 4074 | switch (qual_type->getTypeClass()) { | ^~~~~~~~~~~~~~~~~~~~~~~~~ TypeSystemClang.cpp:4755:11: error: enumeration value 'CountAttributed' not handled in switch [-Werror,-Wswitch] 4755 | switch (qual_type->getTypeClass()) { | ^~~~~~~~~~~~~~~~~~~~~~~~~ TypeSystemClang.cpp:5088:11: error: enumeration value 'CountAttributed' not handled in switch [-Werror,-Wswitch] 5088 | switch (qual_type->getTypeClass()) { | ^~~~~~~~~~~~~~~~~~~~~~~~~ --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 68d9165b90a4..3ac1cf91932c 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -4074,6 +4074,7 @@ TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) { switch (qual_type->getTypeClass()) { case clang::Type::Atomic: case clang::Type::Auto: + case clang::Type::CountAttributed: case clang::Type::Decltype: case clang::Type::Elaborated: case clang::Type::Paren: @@ -4755,6 +4756,7 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type, switch (qual_type->getTypeClass()) { case clang::Type::Atomic: case clang::Type::Auto: + case clang::Type::CountAttributed: case clang::Type::Decltype: case clang::Type::Elaborated: case clang::Type::Paren: @@ -5088,6 +5090,7 @@ lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) { switch (qual_type->getTypeClass()) { case clang::Type::Atomic: case clang::Type::Auto: + case clang::Type::CountAttributed: case clang::Type::Decltype: case clang::Type::Elaborated: case clang::Type::Paren: -- GitLab From 357f00dddbe069f75e126188e35cb20edef32a5f Mon Sep 17 00:00:00 2001 From: Joseph Huber <huberjn@outlook.com> Date: Wed, 20 Mar 2024 07:15:49 -0500 Subject: [PATCH 230/307] [HIP] Correctly omit bundling with the new driver (#85842) Summary: The HIP phases do not emit the offload bundler output when we do not invoke the final linker phase in device only mode. Check this propery. --- clang/lib/Driver/Driver.cpp | 16 ++++++++++------ clang/test/Driver/hip-phases.hip | 12 ++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 1daf588142b3..767c1cd47e8c 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -4645,13 +4645,17 @@ Action *Driver::BuildOffloadingActions(Compilation &C, } } + // HIP code in non-RDC mode will bundle the output if it invoked the linker. + bool ShouldBundleHIP = + C.isOffloadingHostKind(Action::OFK_HIP) && + Args.hasFlag(options::OPT_gpu_bundle_output, + options::OPT_no_gpu_bundle_output, true) && + !Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false) && + !llvm::any_of(OffloadActions, + [](Action *A) { return A->getType() != types::TY_Image; }); + // All kinds exit now in device-only mode except for non-RDC mode HIP. - if (offloadDeviceOnly() && - (getFinalPhase(Args) == phases::Preprocess || - !C.isOffloadingHostKind(Action::OFK_HIP) || - !Args.hasFlag(options::OPT_gpu_bundle_output, - options::OPT_no_gpu_bundle_output, true) || - Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false))) + if (offloadDeviceOnly() && !ShouldBundleHIP) return C.MakeAction<OffloadAction>(DDeps, types::TY_Nothing); if (OffloadActions.empty()) diff --git a/clang/test/Driver/hip-phases.hip b/clang/test/Driver/hip-phases.hip index ca63d4304d39..180ef43022f8 100644 --- a/clang/test/Driver/hip-phases.hip +++ b/clang/test/Driver/hip-phases.hip @@ -648,3 +648,15 @@ // LTO-NEXT: 14: offload, "host-hip (x86_64-unknown-linux-gnu)" {2}, "device-hip (x86_64-unknown-linux-gnu)" {13}, ir // LTO-NEXT: 15: backend, {14}, assembler, (host-hip) // LTO-NEXT: 16: assembler, {15}, object, (host-hip) + +// +// Test the new driver when not bundling +// +// RUN: %clang -### --target=x86_64-linux-gnu --offload-new-driver -ccc-print-phases \ +// RUN: --offload-device-only --offload-arch=gfx90a -emit-llvm -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=DEVICE-ONLY %s +// DEVICE-ONLY: 0: input, "[[INPUT:.+]]", hip, (device-hip, gfx90a) +// DEVICE-ONLY-NEXT: 1: preprocessor, {0}, hip-cpp-output, (device-hip, gfx90a) +// DEVICE-ONLY-NEXT: 2: compiler, {1}, ir, (device-hip, gfx90a) +// DEVICE-ONLY-NEXT: 3: backend, {2}, ir, (device-hip, gfx90a) +// DEVICE-ONLY-NEXT: 4: offload, "device-hip (amdgcn-amd-amdhsa:gfx90a)" {3}, none -- GitLab From da2c98b5582436d2f58c98403671cc1fd5bf5186 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme <thomas.preudhomme@arm.com> Date: Wed, 20 Mar 2024 12:18:42 +0000 Subject: [PATCH 231/307] [MLIR] Remove UtilsDialect dep on ArithUtils (#85919) This will reduce the amount of libraries pulled through the de facto dependency of TilingInterface on UtilsDialect for its IteratorType. --- mlir/include/mlir/Dialect/Utils/StaticValueUtils.h | 1 + mlir/lib/Dialect/Utils/CMakeLists.txt | 4 +++- mlir/lib/Dialect/Utils/StaticValueUtils.cpp | 12 ++++-------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/mlir/include/mlir/Dialect/Utils/StaticValueUtils.h b/mlir/include/mlir/Dialect/Utils/StaticValueUtils.h index 1dc0398494dc..20f019666a2e 100644 --- a/mlir/include/mlir/Dialect/Utils/StaticValueUtils.h +++ b/mlir/include/mlir/Dialect/Utils/StaticValueUtils.h @@ -15,6 +15,7 @@ #ifndef MLIR_DIALECT_UTILS_STATICVALUEUTILS_H #define MLIR_DIALECT_UTILS_STATICVALUEUTILS_H +#include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/OpDefinition.h" #include "mlir/Support/LLVM.h" diff --git a/mlir/lib/Dialect/Utils/CMakeLists.txt b/mlir/lib/Dialect/Utils/CMakeLists.txt index 7d40caebe1e0..a0096e5f299d 100644 --- a/mlir/lib/Dialect/Utils/CMakeLists.txt +++ b/mlir/lib/Dialect/Utils/CMakeLists.txt @@ -4,7 +4,9 @@ add_mlir_library(MLIRDialectUtils StructuredOpsUtils.cpp StaticValueUtils.cpp + DEPENDS + MLIRDialectUtilsIncGen + LINK_LIBS PUBLIC - MLIRArithUtils MLIRIR ) diff --git a/mlir/lib/Dialect/Utils/StaticValueUtils.cpp b/mlir/lib/Dialect/Utils/StaticValueUtils.cpp index 0c8a88da789e..1e8197e10944 100644 --- a/mlir/lib/Dialect/Utils/StaticValueUtils.cpp +++ b/mlir/lib/Dialect/Utils/StaticValueUtils.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "mlir/Dialect/Utils/StaticValueUtils.h" -#include "mlir/Dialect/Arith/Utils/Utils.h" #include "mlir/IR/Matchers.h" #include "mlir/Support/LLVM.h" #include "mlir/Support/MathExtras.h" @@ -18,13 +17,10 @@ namespace mlir { bool isZeroIndex(OpFoldResult v) { if (!v) return false; - if (auto attr = llvm::dyn_cast_if_present<Attribute>(v)) { - IntegerAttr intAttr = dyn_cast<IntegerAttr>(attr); - return intAttr && intAttr.getValue().isZero(); - } - if (auto cst = v.get<Value>().getDefiningOp<arith::ConstantIndexOp>()) - return cst.value() == 0; - return false; + std::optional<int64_t> constint = getConstantIntValue(v); + if (!constint) + return false; + return *constint == 0; } std::tuple<SmallVector<OpFoldResult>, SmallVector<OpFoldResult>, -- GitLab From 679e594d9d400ab688f6cc47b3ca26fe69265cae Mon Sep 17 00:00:00 2001 From: Yuta Saito <kateinoigakukun@gmail.com> Date: Wed, 20 Mar 2024 21:18:57 +0900 Subject: [PATCH 232/307] [clang] Add `__has_extension(swiftcc)` support (#85347) --- clang/docs/ReleaseNotes.rst | 7 +++++++ clang/include/clang/Basic/AttrDocs.td | 13 +++++++++---- clang/include/clang/Basic/Features.def | 5 ++++- clang/test/Sema/swift-call-conv.c | 14 +++++++++++++- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 0ce3cbe3266e..91048daf8f5b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -210,6 +210,13 @@ Attribute Changes in Clang and each must be a positive integer when provided. The parameter ``x`` is required, while ``y`` and ``z`` are optional with default value of 1. +- The ``swiftasynccc`` attribute is now considered to be a Clang extension + rather than a language standard feature. Please use + ``__has_extension(swiftasynccc)`` to check the availability of this attribute + for the target platform instead of ``__has_feature(swiftasynccc)``. Also, + added a new extension query ``__has_extension(swiftcc)`` corresponding to the + ``__attribute__((swiftcc))`` attribute. + Improvements to Clang's diagnostics ----------------------------------- - Clang now applies syntax highlighting to the code snippets it diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index d61f96ade557..9de14f608fd1 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5137,10 +5137,11 @@ that does not. A single parameter may not have multiple ABI treatment attributes. Support for this feature is target-dependent, although it should be -supported on every target that Swift supports. Query for this support -with ``__has_attribute(swiftcall)``. This implies support for the -``swift_context``, ``swift_error_result``, and ``swift_indirect_result`` -attributes. +supported on every target that Swift supports. Query for this attribute +with ``__has_attribute(swiftcall)``. Query if the target supports the +calling convention with ``__has_extension(swiftcc)``. This implies +support for the ``swift_context``, ``swift_error_result``, and +``swift_indirect_result`` attributes. }]; } @@ -5187,6 +5188,10 @@ the following: semantically be performed after a guaranteed tail call, such as the non-trivial destruction of a local variable or temporary, then the program is ill-formed. + +Query for this attribute with ``__has_attribute(swiftasynccall)``. Query if +the target supports the calling convention with +``__has_extension(swiftasynccc)``. }]; } diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index eeed5f4751f2..726ead4b5ab5 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -102,7 +102,10 @@ FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics) -FEATURE(swiftasynccc, +EXTENSION(swiftcc, + PP.getTargetInfo().checkCallingConvention(CC_Swift) == + clang::TargetInfo::CCCR_OK) +EXTENSION(swiftasynccc, PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) == clang::TargetInfo::CCCR_OK) FEATURE(pragma_stdc_cx_limited_range, true) diff --git a/clang/test/Sema/swift-call-conv.c b/clang/test/Sema/swift-call-conv.c index 755c18f5183f..2c9be8405584 100644 --- a/clang/test/Sema/swift-call-conv.c +++ b/clang/test/Sema/swift-call-conv.c @@ -1,7 +1,19 @@ // RUN: %clang_cc1 -triple aarch64-unknown-windows-msvc -fsyntax-only %s -verify // RUN: %clang_cc1 -triple thumbv7-unknown-windows-msvc -fsyntax-only %s -verify // RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fsyntax-only %s -verify +// RISC-V does not support swiftcall +// RUN: %clang_cc1 -triple riscv32-unknown-elf -fsyntax-only %s -verify +#if __has_extension(swiftcc) // expected-no-diagnostics - +#else +// expected-warning@+2 {{'__swiftcall__' calling convention is not supported for this target}} +#endif void __attribute__((__swiftcall__)) f(void) {} + +#if __has_extension(swiftasynccc) +// expected-no-diagnostics +#else +// expected-warning@+2 {{'__swiftasynccall__' calling convention is not supported for this target}} +#endif +void __attribute__((__swiftasynccall__)) g(void) {} -- GitLab From 1de7e6c8cba27296f3fc16d107822ea0ee856759 Mon Sep 17 00:00:00 2001 From: Abhin P Jose <abhinjose@live.com> Date: Wed, 20 Mar 2024 13:34:46 +0100 Subject: [PATCH 233/307] [clang] move -Wcast-function-type under -Wextra (#77178) The -Wcast-fuction-type-strict has been moved under dignstic group -Wextra. Edited the test cases for -Wcast-fuction-type-strict and -Wcast-fuction-type in Sema an SemaCXX. Added a new test case which include a functionality that was already in the -Wextra group, i.e -Wignored-qualifiers with -Wcast-fuction-type-strict. Fixes: #76872 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/include/clang/Basic/DiagnosticGroups.td | 1 + clang/test/Sema/warn-cast-function-type-strict.c | 3 ++- clang/test/Sema/warn-cast-function-type.c | 1 + clang/test/SemaCXX/warn-cast-function-type-strict.cpp | 1 + clang/test/SemaCXX/warn-cast-function-type.cpp | 1 + 6 files changed, 8 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 91048daf8f5b..a10e942615ff 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -193,6 +193,8 @@ Modified Compiler Flags ``-Wreturn-type``, and moved some of the diagnostics previously controlled by ``-Wreturn-type`` under this new flag. Fixes #GH72116. +- Added ``-Wcast-function-type`` as a warning enabled by ``-Wextra``. #GH76872 + Removed Compiler Flags ------------------------- diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index dee555f783cc..bf03d4e8f67e 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1038,6 +1038,7 @@ def Extra : DiagGroup<"extra", [ EmptyInitStatement, StringConcatation, FUseLdPath, + CastFunctionType, ]>; def Most : DiagGroup<"most", [ diff --git a/clang/test/Sema/warn-cast-function-type-strict.c b/clang/test/Sema/warn-cast-function-type-strict.c index 5233680796e9..8c88f275d2b3 100644 --- a/clang/test/Sema/warn-cast-function-type-strict.c +++ b/clang/test/Sema/warn-cast-function-type-strict.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -fsyntax-only -Wcast-function-type -verify // RUN: %clang_cc1 %s -fsyntax-only -Wcast-function-type-strict -verify - +// RUN: %clang_cc1 %s -fsyntax-only -Wextra -Wno-ignored-qualifiers -verify int t(int array[static 12]); int u(int i); @@ -39,5 +39,6 @@ void foo(void) { g = (f7 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f7 *' (aka 'int (*)(long, ...)') converts to incompatible function type}} */ h = (f8 *)t; i = (f9 *)u; + // FIXME: return type qualifier should not be included in the function type . Warning should be absent after this issue is fixed. https://github.com/llvm/llvm-project/issues/39494 . j = (f10 *)v; /* expected-warning {{cast from 'const int (*)(int)' to 'f10 *' (aka 'int (*)(int)') converts to incompatible function type}} */ } diff --git a/clang/test/Sema/warn-cast-function-type.c b/clang/test/Sema/warn-cast-function-type.c index d7ddcdb73725..09d169026b1c 100644 --- a/clang/test/Sema/warn-cast-function-type.c +++ b/clang/test/Sema/warn-cast-function-type.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -verify +// RUN: %clang_cc1 %s -fsyntax-only -Wextra -Wno-cast-function-type-strict -verify int x(long); diff --git a/clang/test/SemaCXX/warn-cast-function-type-strict.cpp b/clang/test/SemaCXX/warn-cast-function-type-strict.cpp index f7ee55f84ac2..b3164afde5a0 100644 --- a/clang/test/SemaCXX/warn-cast-function-type-strict.cpp +++ b/clang/test/SemaCXX/warn-cast-function-type-strict.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 %s -fblocks -fsyntax-only -Wcast-function-type -verify // RUN: %clang_cc1 %s -fblocks -fsyntax-only -Wcast-function-type-strict -verify +// RUN: %clang_cc1 %s -fblocks -fsyntax-only -Wextra -verify int x(long); diff --git a/clang/test/SemaCXX/warn-cast-function-type.cpp b/clang/test/SemaCXX/warn-cast-function-type.cpp index c613aaea1e33..db2ee030fcbf 100644 --- a/clang/test/SemaCXX/warn-cast-function-type.cpp +++ b/clang/test/SemaCXX/warn-cast-function-type.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -fblocks -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -verify +// RUN: %clang_cc1 %s -fblocks -fsyntax-only -Wextra -Wno-cast-function-type-strict -verify int x(long); -- GitLab From 254bfe955ac3deba08dbbe490ef3cf5004a3bd6e Mon Sep 17 00:00:00 2001 From: Jacek Caban <jacek@codeweavers.com> Date: Wed, 20 Mar 2024 13:39:23 +0100 Subject: [PATCH 234/307] [llvm-ar][Object][COFF] Add support for EC symbols to llvm-ar. (#85230) Make writeArchive IsEC argument optional and use EC symbol map when indicated by input object files. --- llvm/include/llvm/Object/ArchiveWriter.h | 2 +- llvm/lib/Object/ArchiveWriter.cpp | 65 ++++++++++++++---- llvm/test/tools/llvm-ar/ecsymbols.ll | 19 ++++++ llvm/test/tools/llvm-ar/ecsymbols.yaml | 84 ++++++++++++++++++++++++ llvm/test/tools/llvm-lib/empty.test | 27 ++++++++ 5 files changed, 185 insertions(+), 12 deletions(-) create mode 100644 llvm/test/tools/llvm-ar/ecsymbols.ll create mode 100644 llvm/test/tools/llvm-ar/ecsymbols.yaml create mode 100644 llvm/test/tools/llvm-lib/empty.test diff --git a/llvm/include/llvm/Object/ArchiveWriter.h b/llvm/include/llvm/Object/ArchiveWriter.h index 7f915929cd72..a19f8fcc79d7 100644 --- a/llvm/include/llvm/Object/ArchiveWriter.h +++ b/llvm/include/llvm/Object/ArchiveWriter.h @@ -52,7 +52,7 @@ Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr, - bool IsEC = false); + std::optional<bool> IsEC = std::nullopt); // writeArchiveToBuffer is similar to writeArchive but returns the Archive in a // buffer instead of writing it out to a file. diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp index 97d0e4f75be8..913b74c110b3 100644 --- a/llvm/lib/Object/ArchiveWriter.cpp +++ b/llvm/lib/Object/ArchiveWriter.cpp @@ -48,7 +48,7 @@ using namespace llvm; using namespace llvm::object; struct SymMap { - bool UseECMap; + bool UseECMap = false; std::map<std::string, uint16_t> Map; std::map<std::string, uint16_t> ECMap; }; @@ -678,6 +678,25 @@ static bool isECObject(object::SymbolicFile &Obj) { return false; } +static bool isAnyArm64COFF(object::SymbolicFile &Obj) { + if (Obj.isCOFF()) + return COFF::isAnyArm64(cast<COFFObjectFile>(&Obj)->getMachine()); + + if (Obj.isCOFFImportFile()) + return COFF::isAnyArm64(cast<COFFImportFile>(&Obj)->getMachine()); + + if (Obj.isIR()) { + Expected<std::string> TripleStr = + getBitcodeTargetTriple(Obj.getMemoryBufferRef()); + if (!TripleStr) + return false; + Triple T(*TripleStr); + return T.isOSWindows() && T.getArch() == Triple::aarch64; + } + + return false; +} + bool isImportDescriptor(StringRef Name) { return Name.starts_with(ImportDescriptorPrefix) || Name == StringRef{NullImportDescriptorSymbolName} || @@ -731,7 +750,8 @@ static Expected<std::vector<MemberData>> computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, object::Archive::Kind Kind, bool Thin, bool Deterministic, SymtabWritingMode NeedSymbols, SymMap *SymMap, - LLVMContext &Context, ArrayRef<NewArchiveMember> NewMembers) { + LLVMContext &Context, ArrayRef<NewArchiveMember> NewMembers, + std::optional<bool> IsEC) { static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'}; uint64_t MemHeadPadSize = 0; uint64_t Pos = @@ -807,6 +827,30 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, } } + if (SymMap) { + if (IsEC) { + SymMap->UseECMap = *IsEC; + } else { + // When IsEC is not specified by the caller, use it when we have both + // any ARM64 object (ARM64 or ARM64EC) and any EC object (ARM64EC or + // AMD64). This may be a single ARM64EC object, but may also be separate + // ARM64 and AMD64 objects. + bool HaveArm64 = false, HaveEC = false; + for (std::unique_ptr<SymbolicFile> &SymFile : SymFiles) { + if (!SymFile) + continue; + if (!HaveArm64) + HaveArm64 = isAnyArm64COFF(*SymFile); + if (!HaveEC) + HaveEC = isECObject(*SymFile); + if (HaveArm64 && HaveEC) { + SymMap->UseECMap = true; + break; + } + } + } + } + // The big archive format needs to know the offset of the previous member // header. uint64_t PrevOffset = 0; @@ -953,11 +997,10 @@ Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) { return std::string(Relative); } -static Error writeArchiveToStream(raw_ostream &Out, - ArrayRef<NewArchiveMember> NewMembers, - SymtabWritingMode WriteSymtab, - object::Archive::Kind Kind, - bool Deterministic, bool Thin, bool IsEC) { +static Error +writeArchiveToStream(raw_ostream &Out, ArrayRef<NewArchiveMember> NewMembers, + SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, + bool Deterministic, bool Thin, std::optional<bool> IsEC) { assert((!Thin || !isBSDLike(Kind)) && "Only the gnu format has a thin mode"); SmallString<0> SymNamesBuf; @@ -977,10 +1020,9 @@ static Error writeArchiveToStream(raw_ostream &Out, // reference to it, thus SymbolicFile should be destroyed first. LLVMContext Context; - SymMap.UseECMap = IsEC; Expected<std::vector<MemberData>> DataOrErr = computeMemberData( StringTable, SymNames, Kind, Thin, Deterministic, WriteSymtab, - isCOFFArchive(Kind) ? &SymMap : nullptr, Context, NewMembers); + isCOFFArchive(Kind) ? &SymMap : nullptr, Context, NewMembers, IsEC); if (Error E = DataOrErr.takeError()) return E; std::vector<MemberData> &Data = *DataOrErr; @@ -1226,7 +1268,8 @@ static Error writeArchiveToStream(raw_ostream &Out, Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, - std::unique_ptr<MemoryBuffer> OldArchiveBuf, bool IsEC) { + std::unique_ptr<MemoryBuffer> OldArchiveBuf, + std::optional<bool> IsEC) { Expected<sys::fs::TempFile> Temp = sys::fs::TempFile::create(ArcName + ".temp-archive-%%%%%%%.a"); if (!Temp) @@ -1263,7 +1306,7 @@ writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, raw_svector_ostream ArchiveStream(ArchiveBufferVector); if (Error E = writeArchiveToStream(ArchiveStream, NewMembers, WriteSymtab, - Kind, Deterministic, Thin, false)) + Kind, Deterministic, Thin, std::nullopt)) return std::move(E); return std::make_unique<SmallVectorMemoryBuffer>( diff --git a/llvm/test/tools/llvm-ar/ecsymbols.ll b/llvm/test/tools/llvm-ar/ecsymbols.ll new file mode 100644 index 000000000000..f49c991b5934 --- /dev/null +++ b/llvm/test/tools/llvm-ar/ecsymbols.ll @@ -0,0 +1,19 @@ +;; Test that ECSYMBOLS section is created when ARM64EC bitcode is used. + +; RUN: llvm-as %s -o %t.bc +; RUN: rm -f %t.a +; RUN: llvm-ar cr %t.a %t.bc +; RUN: llvm-nm --print-armap %t.a | FileCheck %s + +; CHECK-NOT: Archive map +; CHECK: Archive EC map +; CHECK-NEXT: a in ecsymbols.ll.tmp.bc +; CHECK-NEXT: b in ecsymbols.ll.tmp.bc +; CHECK-NEXT: c in ecsymbols.ll.tmp.bc +; CHECK-EMPTY: + +target triple = "arm64ec-unknown-windows-msvc" + +define void @b() { ret void } +define void @c() { ret void } +define void @a() { ret void } diff --git a/llvm/test/tools/llvm-ar/ecsymbols.yaml b/llvm/test/tools/llvm-ar/ecsymbols.yaml new file mode 100644 index 000000000000..6cfe78d160ed --- /dev/null +++ b/llvm/test/tools/llvm-ar/ecsymbols.yaml @@ -0,0 +1,84 @@ +## Test that ECSYMBOLS section is created when ARM64EC is used. + +# RUN: yaml2obj %s -o %t.arm64ec.obj -DMACHINE=IMAGE_FILE_MACHINE_ARM64EC +# RUN: yaml2obj %s -o %t.arm64.obj -DMACHINE=IMAGE_FILE_MACHINE_ARM64 +# RUN: yaml2obj %s -o %t.amd64.obj -DMACHINE=IMAGE_FILE_MACHINE_AMD64 + +## Create ARM64EC archive. +# RUN: rm -f %t*.a +# RUN: llvm-ar cr %t1.a %t.arm64ec.obj +# RUN: llvm-nm --print-armap %t1.a | FileCheck --check-prefixes=NOMAP,ECMAP %s + +## Add ARM64 object to the archive. +# RUN: llvm-ar r %t1.a %t.arm64.obj +# RUN: llvm-nm --print-armap %t1.a | FileCheck --check-prefixes=MAP,ECMAP %s + +## Create ARM64 archive. +# RUN: llvm-ar cr %t2.a %t.arm64.obj +# RUN: llvm-nm --print-armap %t2.a | FileCheck --check-prefixes=MAP,NOECMAP %s + +## Add ARM64EC object to the archive. +# RUN: llvm-ar r %t2.a %t.arm64ec.obj +# RUN: llvm-nm --print-armap %t2.a | FileCheck --check-prefixes=MAP,ECMAP %s + +## Create mixed archive with ARM64 and ARM64EC members. +# RUN: llvm-ar cr %t3.a %t.arm64ec.obj %t.arm64.obj +# RUN: llvm-nm --print-armap %t3.a | FileCheck --check-prefixes=MAP,ECMAP %s + +## Create mixed archive with ARM64 and AMD64 members. +# RUN: llvm-ar cr %t4.a %t.amd64.obj %t.arm64.obj +# RUN: llvm-nm --print-armap %t4.a | FileCheck --check-prefixes=MAP,AMDECMAP %s + +## Create an archive with no symbol table. +# RUN: llvm-ar crS %t5.a %t.amd64.obj %t.arm64.obj +# RUN: llvm-nm --print-armap %t5.a | FileCheck --check-prefixes=NOMAP,NOECMAP %s + +# MAP: Archive map +# MAP-NEXT: a in ecsymbols.yaml.tmp.arm64.obj +# MAP-NEXT: b in ecsymbols.yaml.tmp.arm64.obj +# MAP-NEXT: c in ecsymbols.yaml.tmp.arm64.obj +# MAP-EMPTY: +# NOMAP-NOT: Archive map + +# ECMAP: Archive EC map +# ECMAP-NEXT: a in ecsymbols.yaml.tmp.arm64ec.obj +# ECMAP-NEXT: b in ecsymbols.yaml.tmp.arm64ec.obj +# ECMAP-NEXT: c in ecsymbols.yaml.tmp.arm64ec.obj +# ECMAP-EMPTY: +# NOECMAP-NOT: Archive EC map + +# AMDECMAP: Archive EC map +# AMDECMAP-NEXT: a in ecsymbols.yaml.tmp.amd64.obj +# AMDECMAP-NEXT: b in ecsymbols.yaml.tmp.amd64.obj +# AMDECMAP-NEXT: c in ecsymbols.yaml.tmp.amd64.obj +# AMDECMAP-EMPTY: + +--- !COFF +header: + Machine: [[MACHINE]] + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '' +symbols: + - Name: b + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: c + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: a + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... diff --git a/llvm/test/tools/llvm-lib/empty.test b/llvm/test/tools/llvm-lib/empty.test new file mode 100644 index 000000000000..37c841f8db46 --- /dev/null +++ b/llvm/test/tools/llvm-lib/empty.test @@ -0,0 +1,27 @@ +Create import libraries with empty exports and make sure that archive symbols +are properly populated. + +RUN: split-file %s %t.dir && cd %t.dir + +RUN: llvm-lib -machine:arm64 -out:arm64.lib -def:test.def +RUN: llvm-nm --print-armap arm64.lib | FileCheck --check-prefixes=CHECK,NOECMAP %s + +RUN: llvm-lib -machine:arm64ec -out:arm64ec.lib -def:test.def +RUN: llvm-nm --print-armap arm64ec.lib | FileCheck --check-prefixes=CHECK,ECMAP %s + +CHECK: Archive map +CHECK-NEXT: __IMPORT_DESCRIPTOR_test in test.dll +CHECK-NEXT: __NULL_IMPORT_DESCRIPTOR in test.dll +CHECK-NEXT: test_NULL_THUNK_DATA in test.dll +CHECK-EMPTY: + +ECMAP: Archive EC map +ECMAP-NEXT: __IMPORT_DESCRIPTOR_test in test.dll +ECMAP-NEXT: __NULL_IMPORT_DESCRIPTOR in test.dll +ECMAP-NEXT: test_NULL_THUNK_DATA in test.dll + +NOECMAP-NOT: Archive EC map + +#--- test.def +LIBRARY test.dll +EXPORTS -- GitLab From fb5fd2d82f9befba9cf5152d1a0c5e6f91ee48f0 Mon Sep 17 00:00:00 2001 From: Michael Klemm <michael.klemm@amd.com> Date: Wed, 20 Mar 2024 13:47:26 +0100 Subject: [PATCH 235/307] [flang][OpenMP] Compile proper `omp_lib.mod` from the `openmp/src/include` sources (#80874) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR changes the build system to use use the sources for the module `omp_lib` and the `omp_lib.h` include file from the `openmp` runtime project and not from a separate copy of these files. This will greatly reduce potential for inconsistencies when adding features to the OpenMP runtime implementation. When the OpenMP subproject is not configured, this PR also disables the corresponding LIT tests with a "REQUIRES" directive at the beginning of the OpenMP test files. --------- Co-authored-by: Valentin Clement (バレンタイン クレメン) <clementval@gmail.com> --- flang/module/omp_lib.f90 | 13 - flang/module/omp_lib.h | 454 ----------------- flang/test/Driver/include-omp-header.f90 | 6 +- .../test/Lower/OpenMP/FIR/atomic-capture.f90 | 2 + flang/test/Lower/OpenMP/FIR/atomic-read.f90 | 2 + flang/test/Lower/OpenMP/FIR/atomic-update.f90 | 2 + flang/test/Lower/OpenMP/FIR/atomic-write.f90 | 2 + flang/test/Lower/OpenMP/FIR/critical.f90 | 2 + .../Lower/OpenMP/FIR/parallel-sections.f90 | 18 +- flang/test/Lower/OpenMP/FIR/parallel.f90 | 10 +- flang/test/Lower/OpenMP/FIR/sections.f90 | 6 +- flang/test/Lower/OpenMP/FIR/single.f90 | 4 +- flang/test/Lower/OpenMP/FIR/task.f90 | 6 +- flang/test/Lower/OpenMP/FIR/taskgroup.f90 | 6 +- flang/test/Lower/OpenMP/FIR/teams.f90 | 5 +- flang/test/Lower/OpenMP/atomic-capture.f90 | 2 + flang/test/Lower/OpenMP/atomic-read.f90 | 2 + flang/test/Lower/OpenMP/atomic-update.f90 | 2 + flang/test/Lower/OpenMP/atomic-write.f90 | 6 +- flang/test/Lower/OpenMP/critical.f90 | 2 + .../test/Lower/OpenMP/omp-lib-num-threads.f90 | 2 + flang/test/Lower/OpenMP/parallel-sections.f90 | 10 +- flang/test/Lower/OpenMP/parallel.f90 | 6 +- flang/test/Lower/OpenMP/sections.f90 | 6 +- flang/test/Lower/OpenMP/single.f90 | 4 +- flang/test/Lower/OpenMP/task.f90 | 6 +- flang/test/Lower/OpenMP/taskgroup.f90 | 6 +- flang/test/Lower/OpenMP/teams.f90 | 4 +- .../OpenMP/threadprivate-default-clause.f90 | 2 + .../Parser/OpenMP/allocate-tree-spec-part.f90 | 2 + flang/test/Parser/OpenMP/allocate-tree.f90 | 8 +- .../Parser/OpenMP/target_device_parse.f90 | 2 + .../Semantics/OpenMP/allocate-clause01.f90 | 2 + .../Semantics/OpenMP/allocate-directive.f90 | 2 + flang/test/Semantics/OpenMP/allocate01.f90 | 2 + flang/test/Semantics/OpenMP/allocate02.f90 | 2 + flang/test/Semantics/OpenMP/allocate03.f90 | 2 + flang/test/Semantics/OpenMP/allocate04.f90 | 2 + flang/test/Semantics/OpenMP/allocate05.f90 | 2 + flang/test/Semantics/OpenMP/allocate06.f90 | 2 + flang/test/Semantics/OpenMP/allocate07.f90 | 2 + flang/test/Semantics/OpenMP/allocate08.f90 | 2 + flang/test/Semantics/OpenMP/allocate09.f90 | 2 + flang/test/Semantics/OpenMP/allocators01.f90 | 2 + flang/test/Semantics/OpenMP/allocators02.f90 | 2 + flang/test/Semantics/OpenMP/allocators03.f90 | 2 + flang/test/Semantics/OpenMP/allocators04.f90 | 2 + flang/test/Semantics/OpenMP/allocators05.f90 | 2 + flang/test/Semantics/OpenMP/allocators06.f90 | 2 + .../Semantics/OpenMP/atomic-hint-clause.f90 | 2 + flang/test/Semantics/OpenMP/atomic01.f90 | 2 + flang/test/Semantics/OpenMP/atomic02.f90 | 2 + flang/test/Semantics/OpenMP/atomic03.f90 | 2 + flang/test/Semantics/OpenMP/atomic04.f90 | 2 + flang/test/Semantics/OpenMP/atomic05.f90 | 2 + .../Semantics/OpenMP/clause-validity01.f90 | 2 + .../Semantics/OpenMP/critical-hint-clause.f90 | 2 + .../Semantics/OpenMP/declare-target01.f90 | 2 + flang/test/Semantics/OpenMP/flush02.f90 | 2 + .../OpenMP/omp-atomic-assignment-stmt.f90 | 2 + .../Semantics/OpenMP/parallel-sections01.f90 | 2 + flang/test/Semantics/OpenMP/resolve06.f90 | 2 + flang/test/Semantics/OpenMP/sections02.f90 | 2 + .../test/Semantics/OpenMP/sync-critical02.f90 | 2 + flang/test/Semantics/OpenMP/taskgroup01.f90 | 2 + .../test/Semantics/OpenMP/threadprivate01.f90 | 2 + flang/test/lit.cfg.py | 4 + flang/test/lit.site.cfg.py.in | 1 + flang/tools/f18/CMakeLists.txt | 36 +- llvm/runtimes/CMakeLists.txt | 9 + openmp/runtime/src/CMakeLists.txt | 33 +- .../{omp_lib.f90.var => omp_lib.F90.var} | 468 ++++++++++++------ openmp/runtime/src/include/omp_lib.h.var | 22 + 73 files changed, 589 insertions(+), 662 deletions(-) delete mode 100644 flang/module/omp_lib.f90 delete mode 100644 flang/module/omp_lib.h rename openmp/runtime/src/include/{omp_lib.f90.var => omp_lib.F90.var} (62%) diff --git a/flang/module/omp_lib.f90 b/flang/module/omp_lib.f90 deleted file mode 100644 index 2ca15da68915..000000000000 --- a/flang/module/omp_lib.f90 +++ /dev/null @@ -1,13 +0,0 @@ -!===-- module/omp_lib.f90 --------------------------------------------------===! -! -! Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -! See https://llvm.org/LICENSE.txt for license information. -! SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -! -!===------------------------------------------------------------------------===! - -module omp_lib - -include "omp_lib.h" - -end module omp_lib diff --git a/flang/module/omp_lib.h b/flang/module/omp_lib.h deleted file mode 100644 index efc9ceb16968..000000000000 --- a/flang/module/omp_lib.h +++ /dev/null @@ -1,454 +0,0 @@ -!===-- module/omp_lib.h ------------------------------------------*- F90 -*-===! -! -! Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -! See https://llvm.org/LICENSE.txt for license information. -! SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -! -!===------------------------------------------------------------------------===! - -!dir$ free - - integer, parameter :: omp_integer_kind = selected_int_kind(9) ! 32-bit int - integer, parameter :: omp_logical_kind = 1 ! C_BOOL - - integer, parameter :: omp_sched_kind = omp_integer_kind - integer, parameter :: omp_proc_bind_kind = omp_integer_kind - integer, parameter :: omp_pause_resource_kind = omp_integer_kind - integer, parameter :: omp_sync_hint_kind = omp_integer_kind - integer, parameter :: omp_lock_hint_kind = omp_sync_hint_kind - integer, parameter :: omp_event_handle_kind = omp_integer_kind - integer, parameter :: omp_alloctrait_key_kind = omp_integer_kind - integer, parameter :: omp_alloctrait_val_kind = omp_integer_kind - integer, parameter :: omp_allocator_handle_kind = omp_integer_kind - integer, parameter :: omp_memspace_handle_kind = omp_integer_kind - integer, parameter :: omp_lock_kind = int_ptr_kind() - integer, parameter :: omp_nest_lock_kind = int_ptr_kind() - integer, parameter :: omp_depend_kind = omp_integer_kind - - integer(kind=omp_sched_kind), parameter :: & - omp_sched_static = 1, & - omp_sched_dynamic = 2, & - omp_sched_guided = 3, & - omp_sched_auto = 4 - - integer(kind=omp_proc_bind_kind), parameter :: & - omp_proc_bind_false = 0, & - omp_proc_bind_true = 1, & - omp_proc_bind_master = 2, & - omp_proc_bind_close = 3, & - omp_proc_bind_spread = 4 - - integer(kind=omp_pause_resource_kind), parameter :: & - omp_pause_soft = 1, & - omp_pause_hard = 2 - - integer(kind=omp_sync_hint_kind), parameter :: & - omp_sync_hint_none = 0, & - omp_sync_hint_uncontended = 1, & - omp_sync_hint_contended = 2, & - omp_sync_hint_nonspeculative = 4, & - omp_sync_hint_speculative = 8 - integer(kind=omp_lock_hint_kind), parameter :: & - omp_lock_hint_none = omp_sync_hint_none, & - omp_lock_hint_uncontended = omp_sync_hint_uncontended, & - omp_lock_hint_contended = omp_sync_hint_contended, & - omp_lock_hint_nonspeculative = omp_sync_hint_nonspeculative, & - omp_lock_hint_speculative = omp_sync_hint_speculative - - integer(kind=omp_event_handle_kind), parameter :: & - omp_allow_completion_event = 0, & - omp_task_fulfill_event = 1 - - integer(kind=omp_alloctrait_key_kind), parameter :: & - omp_atk_sync_hint = 1, & - omp_atk_alignment = 2, & - omp_atk_access = 3, & - omp_atk_pool_size = 4, & - omp_atk_fallback = 5, & - omp_atk_fb_data = 6, & - omp_atk_pinned = 7, & - omp_atk_partition = 8 - - integer(kind=omp_alloctrait_val_kind), parameter :: & - omp_atv_false = 0, & - omp_atv_true = 1, & - omp_atv_default = 2, & - omp_atv_contended = 3, & - omp_atv_uncontended = 4, & - omp_atv_sequential = 5, & - omp_atv_private = 6, & - omp_atv_all = 7, & - omp_atv_thread = 8, & - omp_atv_pteam = 9, & - omp_atv_cgroup = 10, & - omp_atv_default_mem_fb = 11, & - omp_atv_null_fb = 12, & - omp_atv_abort_fb = 13, & - omp_atv_allocator_fb = 14, & - omp_atv_environment = 15, & - omp_atv_nearest = 16, & - omp_atv_blocked = 17, & - omp_atv_interleaved = 18 - - type, bind(c) :: omp_alloctrait - integer(kind=omp_alloctrait_key_kind) :: key, value - end type omp_alloctrait - - integer(kind=omp_allocator_handle_kind), parameter :: omp_null_allocator = 0 - - integer(kind=omp_memspace_handle_kind), parameter :: & - omp_default_mem_space = 0, & - omp_large_cap_mem_space = 0, & - omp_const_mem_space = 0, & - omp_high_bw_mem_space = 0, & - omp_low_lat_mem_space = 0, & - omp_default_mem_alloc = 1, & - omp_large_cap_mem_alloc = omp_default_mem_alloc, & - omp_const_mem_alloc = 1, & - omp_high_bw_mem_alloc = 1, & - omp_low_lat_mem_alloc = 1, & - omp_thread_mem_alloc = omp_atv_thread, & - omp_pteam_mem_alloc = omp_atv_pteam, & - omp_cgroup_mem_alloc = omp_atv_cgroup - - integer(kind=omp_integer_kind), parameter :: openmp_version = 200805 - - interface - - subroutine omp_set_num_threads(nthreads) bind(c) - import - integer(kind=omp_integer_kind), value :: nthreads - end subroutine omp_set_num_threads - - function omp_get_num_threads() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_num_threads - end function omp_get_num_threads - - function omp_get_max_threads() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_max_threads - end function omp_get_max_threads - - function omp_get_thread_num() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_thread_num - end function omp_get_thread_num - - function omp_get_num_procs() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_num_procs - end function omp_get_num_procs - - function omp_in_parallel() bind(c) - import - logical(kind=omp_logical_kind) :: omp_in_parallel - end function omp_in_parallel - - subroutine omp_set_dynamic(enable) bind(c) - import - logical(kind=omp_logical_kind), value :: enable - end subroutine omp_set_dynamic - - function omp_get_dynamic() bind(c) - import - logical(kind=omp_logical_kind) :: omp_get_dynamic - end function omp_get_dynamic - - function omp_get_cancelation() bind(c) - import - logical(kind=omp_logical_kind) :: omp_get_cancelation - end function omp_get_cancelation - - subroutine omp_set_nested(enable) bind(c) - import - logical(kind=omp_logical_kind), value :: enable - end subroutine omp_set_nested - - function omp_get_nested() bind(c) - import - logical(kind=omp_logical_kind) ::omp_get_nested - end function omp_get_nested - - subroutine omp_set_schedule(kind, modifier) bind(c) - import - integer(kind=omp_integer_kind), value :: kind, modifier - end subroutine omp_set_schedule - - subroutine omp_get_schedule(kind, modifier) bind(c) - import - integer(kind=omp_integer_kind), intent(out) :: kind, modifier - end subroutine omp_get_schedule - - function omp_get_thread_limit() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_thread_limit - end function omp_get_thread_limit - - function omp_get_supported_active_levels() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_supported_active_levels - end function omp_get_supported_active_levels - - subroutine omp_set_max_active_levels(max_levels) bind(c) - import - integer(kind=omp_integer_kind), value :: max_levels - end subroutine omp_set_max_active_levels - - function omp_get_max_active_levels() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_max_active_levels - end function omp_get_max_active_levels - - function omp_get_level() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_level - end function omp_get_level - - function omp_get_ancestor_thread_num(level) bind(c) - import - integer(kind=omp_integer_kind), value :: level - integer(kind=omp_integer_kind) :: omp_get_ancestor_thread_num - end function omp_get_ancestor_thread_num - - function omp_get_team_size(level) bind(c) - import - integer(kind=omp_integer_kind), value :: level - integer(kind=omp_integer_kind) :: omp_get_team_size - end function omp_get_team_size - - function omp_get_active_level() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_active_level - end function omp_get_active_level - - function omp_in_final() bind(c) - import - logical(kind=omp_logical_kind) :: omp_in_final - end function omp_in_final - - function omp_get_proc_bind() bind(c) - import - integer(kind=omp_proc_bind_kind) :: omp_get_proc_bind - end function omp_get_proc_bind - - function omp_get_num_places() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_num_places - end function omp_get_num_places - - function omp_get_place_num_procs(place_num) bind(c) - import - integer(kind=omp_integer_kind), value :: place_num - integer(kind=omp_integer_kind) omp_get_place_num_procs - end function omp_get_place_num_procs - - subroutine omp_get_place_proc_ids(place_num, ids) bind(c) - import - integer(kind=omp_integer_kind), value :: place_num - integer(kind=omp_integer_kind), intent(out) :: ids(*) - end subroutine omp_get_place_proc_ids - - function omp_get_place_num() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_place_num - end function omp_get_place_num - - function omp_get_partition_num_places() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_partition_num_places - end function omp_get_partition_num_places - - subroutine omp_get_partition_place_nums(place_nums) bind(c) - import - integer(kind=omp_integer_kind), intent(out) :: place_nums(*) - end subroutine omp_get_partition_place_nums - - subroutine omp_set_affinity_format(format) bind(c) - import - character(len=*), intent(in) :: format - end subroutine omp_set_affinity_format - - function omp_get_affinity_format(buffer) bind(c) - import - character(len=*), intent(out) :: buffer - integer(kind=omp_integer_kind) :: omp_get_affinity_format - end function omp_get_affinity_format - - subroutine omp_display_affinity(format) bind(c) - import - character(len=*), intent(in) :: format - end subroutine omp_display_affinity - - function omp_capture_affinity(buffer, format) bind(c) - import - character(len=*), intent(out) :: buffer - character(len=*), intent(in) :: format - integer(kind=omp_integer_kind) omp_capture_affinity - end function omp_capture_affinity - - subroutine omp_set_default_device(device_num) bind(c) - import - integer(kind=omp_integer_kind), value :: device_num - end subroutine omp_set_default_device - - function omp_get_default_device() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_default_device - end function omp_get_default_device - - function omp_get_num_devices() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_num_devices - end function omp_get_num_devices - - function omp_get_device_num() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_device_num - end function omp_get_device_num - - function omp_get_num_teams() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_num_teams - end function omp_get_num_teams - - function omp_get_team_num() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_team_num - end function omp_get_team_num - - function omp_is_initial_device() bind(c) - import - integer(kind=omp_logical_kind) :: omp_is_initial_device ! TODO: should this be LOGICAL? - end function omp_is_initial_device - - function omp_get_initial_device() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_initial_device - end function omp_get_initial_device - - function omp_get_max_task_priority() bind(c) - import - integer(kind=omp_integer_kind) :: omp_get_max_task_priority - end function omp_get_max_task_priority - - function omp_pause_resource(kind, device_num) bind(c) - import - integer(kind=omp_pause_resource_kind), value :: kind - integer(kind=omp_integer_kind), value :: device_num - integer(kind=omp_integer_kind) :: omp_pause_resource - end function omp_pause_resource - - function omp_pause_resource_all(kind) bind(c) - import - integer(kind=omp_pause_resource_kind), value :: kind - integer(kind=omp_integer_kind) :: omp_pause_resource_all - end function omp_pause_resource_all - -! Lock routines - subroutine omp_init_lock(lockvar) bind(c, name="omp_init_lock_") - import - integer(kind=omp_lock_kind), intent(out) :: lockvar - end subroutine omp_init_lock - - subroutine omp_init_lock_with_hint(lockvar, hint) bind(c, name="omp_init_lock_with_hint_") - import - integer(kind=omp_lock_kind), intent(out) :: lockvar - integer(kind=omp_sync_hint_kind), value :: hint - end subroutine omp_init_lock_with_hint - - subroutine omp_destroy_lock(lockvar) bind(c, name="omp_destroy_lock_") - import - integer(kind=omp_lock_kind), intent(inout) :: lockvar - end subroutine omp_destroy_lock - - subroutine omp_set_lock(lockvar) bind(c, name="omp_set_lock_") - import - integer(kind=omp_lock_kind), intent(inout) :: lockvar - end subroutine omp_set_lock - - subroutine omp_unset_lock(lockvar) bind(c, name="omp_unset_lock_") - import - integer(kind=omp_lock_kind), intent(inout) :: lockvar - end subroutine omp_unset_lock - - function omp_test_lock(lockvar) bind(c, name="omp_test_lock_") - import - integer(kind=omp_lock_kind), intent(inout) :: lockvar - logical(kind=omp_logical_kind) :: omp_test_lock - end function omp_test_lock - - subroutine omp_init_nest_lock(lockvar) bind(c, name="omp_init_nest_lock_") - import - integer(kind=omp_nest_lock_kind), intent(out) :: lockvar - end subroutine omp_init_nest_lock - - subroutine omp_init_nest_lock_with_hint(lockvar, hint) bind(c, name="omp_init_nest_lock_with_hint_") - import - integer(kind=omp_nest_lock_kind), intent(out) :: lockvar - integer(kind=omp_sync_hint_kind), value :: hint - end subroutine omp_init_nest_lock_with_hint - - subroutine omp_destroy_nest_lock(lockvar) bind(c, name="omp_destroy_nest_lock_") - import - integer(kind=omp_nest_lock_kind), intent(inout) :: lockvar - end subroutine omp_destroy_nest_lock - - subroutine omp_set_nest_lock(lockvar) bind(c, name="omp_set_nest_lock_") - import - integer(kind=omp_nest_lock_kind), intent(inout) :: lockvar - end subroutine omp_set_nest_lock - - subroutine omp_unset_nest_lock(lockvar) bind(c, name="omp_unset_nest_lock_") - import - integer(kind=omp_nest_lock_kind), intent(inout) :: lockvar - end subroutine omp_unset_nest_lock - - function omp_test_nest_lock(lockvar) bind(c, name="omp_test_nest_lock_") - import - integer(kind=omp_integer_kind) :: omp_test_nest_lock - integer(kind=omp_nest_lock_kind), intent(inout) :: lockvar - end function omp_test_nest_lock - -! Timing routines - function omp_get_wtime() bind(c) - double precision omp_get_wtime - end function omp_get_wtime - - function omp_get_wtick() bind(c) - double precision omp_get_wtick - end function omp_get_wtick - -! Event routine - subroutine omp_fullfill_event(event) bind(c) ! TODO: is this the correct spelling? - import - integer(kind=omp_event_handle_kind) :: event - end subroutine omp_fullfill_event - -! Device Memory Routines - -! Memory Management Routines - function omp_init_allocator(memspace, ntraits, traits) bind(c) - import - integer(kind=omp_memspace_handle_kind), value :: memspace - integer, value :: ntraits - type(omp_alloctrait), intent(in) :: traits(*) - integer(kind=omp_allocator_handle_kind) :: omp_init_allocator - end function omp_init_allocator - - subroutine omp_destroy_allocator(allocator) bind(c) - import - integer(kind=omp_allocator_handle_kind), value :: allocator - end subroutine omp_destroy_allocator - - subroutine omp_set_default_allocator(allocator) bind(c) - import - integer(kind=omp_allocator_handle_kind), value :: allocator - end subroutine omp_set_default_allocator - - function omp_get_default_allocator() bind(c) - import - integer(kind=omp_allocator_handle_kind) :: omp_get_default_allocator - end function omp_get_default_allocator - - end interface diff --git a/flang/test/Driver/include-omp-header.f90 b/flang/test/Driver/include-omp-header.f90 index 4bf43bbc882b..6ddc6f3da2a4 100644 --- a/flang/test/Driver/include-omp-header.f90 +++ b/flang/test/Driver/include-omp-header.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! Verify that the omp_lib.h header is found and included correctly. This header file should be available at a path: ! * relative to the driver, that's ! * known the driver. @@ -7,11 +9,11 @@ ! This should just work ! RUN: not rm omp_lib.h -! RUN: %flang -fsyntax-only -fopenmp %s 2>&1 +! RUN: %flang -cpp -fsyntax-only -fopenmp %s 2>&1 ! Create an empty omp_lib.h header that _does not_ define omp_default_mem_alloc - this should lead to semantic errors ! RUN: touch omp_lib.h -! RUN: not %flang -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s +! RUN: not %flang -cpp -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s ! RUN: rm omp_lib.h ! CHECK: error: Must have INTEGER type, but is REAL(4) diff --git a/flang/test/Lower/OpenMP/FIR/atomic-capture.f90 b/flang/test/Lower/OpenMP/FIR/atomic-capture.f90 index 024400a9e847..9b94214b9da8 100644 --- a/flang/test/Lower/OpenMP/FIR/atomic-capture.f90 +++ b/flang/test/Lower/OpenMP/FIR/atomic-capture.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s ! This test checks the lowering of atomic capture diff --git a/flang/test/Lower/OpenMP/FIR/atomic-read.f90 b/flang/test/Lower/OpenMP/FIR/atomic-read.f90 index 66be9e713904..7698c3d7490f 100644 --- a/flang/test/Lower/OpenMP/FIR/atomic-read.f90 +++ b/flang/test/Lower/OpenMP/FIR/atomic-read.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: bbc --use-desc-for-alloc=false -fopenmp -emit-fir -hlfir=false %s -o - | FileCheck %s ! This test checks the lowering of atomic read diff --git a/flang/test/Lower/OpenMP/FIR/atomic-update.f90 b/flang/test/Lower/OpenMP/FIR/atomic-update.f90 index bd3d4ace440e..ae201807c337 100644 --- a/flang/test/Lower/OpenMP/FIR/atomic-update.f90 +++ b/flang/test/Lower/OpenMP/FIR/atomic-update.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! This test checks lowering of atomic and atomic update constructs ! RUN: bbc --use-desc-for-alloc=false -fopenmp -emit-fir -hlfir=false %s -o - | FileCheck %s ! RUN: %flang_fc1 -mllvm --use-desc-for-alloc=false -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s diff --git a/flang/test/Lower/OpenMP/FIR/atomic-write.f90 b/flang/test/Lower/OpenMP/FIR/atomic-write.f90 index 5d98176cc201..142481b7a1d2 100644 --- a/flang/test/Lower/OpenMP/FIR/atomic-write.f90 +++ b/flang/test/Lower/OpenMP/FIR/atomic-write.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: bbc --use-desc-for-alloc=false -fopenmp -emit-fir -hlfir=false %s -o - | FileCheck %s ! This test checks the lowering of atomic write diff --git a/flang/test/Lower/OpenMP/FIR/critical.f90 b/flang/test/Lower/OpenMP/FIR/critical.f90 index e88178422a83..fa33fb0fe58b 100644 --- a/flang/test/Lower/OpenMP/FIR/critical.f90 +++ b/flang/test/Lower/OpenMP/FIR/critical.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s --check-prefixes="OMPDialect" !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefix="OMPDialect" !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --fir-to-llvm-ir | tco | FileCheck %s --check-prefix="LLVMIR" diff --git a/flang/test/Lower/OpenMP/FIR/parallel-sections.f90 b/flang/test/Lower/OpenMP/FIR/parallel-sections.f90 index 78d73f038f07..0c0834cfafe9 100644 --- a/flang/test/Lower/OpenMP/FIR/parallel-sections.f90 +++ b/flang/test/Lower/OpenMP/FIR/parallel-sections.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s --check-prefixes="FIRDialect,OMPDialect" !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion-on-func-opt | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect,LLVMDialect" @@ -38,16 +40,16 @@ end subroutine omp_parallel_sections subroutine omp_parallel_sections_allocate(x, y) use omp_lib integer, intent(inout) :: x, y - !FIRDialect: %[[allocator_1:.*]] = arith.constant 1 : i32 - !FIRDialect: %[[allocator_2:.*]] = arith.constant 1 : i32 - !LLVMDialect: %[[allocator_1:.*]] = llvm.mlir.constant(1 : i32) : i32 - !LLVMDialect: %[[allocator_2:.*]] = llvm.mlir.constant(1 : i32) : i32 + !FIRDialect: %[[allocator_1:.*]] = arith.constant 4 : i64 + !FIRDialect: %[[allocator_2:.*]] = arith.constant 4 : i64 + !LLVMDialect: %[[allocator_1:.*]] = llvm.mlir.constant(4 : i64) : i64 + !LLVMDialect: %[[allocator_2:.*]] = llvm.mlir.constant(4 : i64) : i64 !OMPDialect: omp.parallel allocate( - !FIRDialect: %[[allocator_2]] : i32 -> %{{.*}} : !fir.ref<i32>) { - !LLVMDialect: %[[allocator_2]] : i32 -> %{{.*}} : !llvm.ptr) { + !FIRDialect: %[[allocator_2]] : i64 -> %{{.*}} : !fir.ref<i32>) { + !LLVMDialect: %[[allocator_2]] : i64 -> %{{.*}} : !llvm.ptr) { !OMPDialect: omp.sections allocate( - !FIRDialect: %[[allocator_1]] : i32 -> %{{.*}} : !fir.ref<i32>) { - !LLVMDialect: %[[allocator_1]] : i32 -> %{{.*}} : !llvm.ptr) { + !FIRDialect: %[[allocator_1]] : i64 -> %{{.*}} : !fir.ref<i32>) { + !LLVMDialect: %[[allocator_1]] : i64 -> %{{.*}} : !llvm.ptr) { !$omp parallel sections allocate(omp_high_bw_mem_alloc: x) !OMPDialect: omp.section { !$omp section diff --git a/flang/test/Lower/OpenMP/FIR/parallel.f90 b/flang/test/Lower/OpenMP/FIR/parallel.f90 index b68551df2341..a2ceb2d939f2 100644 --- a/flang/test/Lower/OpenMP/FIR/parallel.f90 +++ b/flang/test/Lower/OpenMP/FIR/parallel.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s --check-prefixes="FIRDialect,OMPDialect" !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="LLVMDialect,OMPDialect" @@ -153,8 +155,8 @@ subroutine parallel_allocate() use omp_lib integer :: x !OMPDialect: omp.parallel allocate( - !FIRDialect: %{{.+}} : i32 -> %{{.+}} : !fir.ref<i32> - !LLVMDialect: %{{.+}} : i32 -> %{{.+}} : !llvm.ptr + !FIRDialect: %{{.+}} : i64 -> %{{.+}} : !fir.ref<i32> + !LLVMDialect: %{{.+}} : i64 -> %{{.+}} : !llvm.ptr !OMPDialect: ) { !$omp parallel allocate(omp_high_bw_mem_alloc: x) private(x) !FIRDialect: arith.addi @@ -195,8 +197,8 @@ subroutine parallel_multiple_clauses(alpha, num_threads) !$omp end parallel !OMPDialect: omp.parallel if({{.*}} : i1) num_threads({{.*}} : i32) allocate( - !FIRDialect: %{{.+}} : i32 -> %{{.+}} : !fir.ref<i32> - !LLVMDialect: %{{.+}} : i32 -> %{{.+}} : !llvm.ptr + !FIRDialect: %{{.+}} : i64 -> %{{.+}} : !fir.ref<i32> + !LLVMDialect: %{{.+}} : i64 -> %{{.+}} : !llvm.ptr !OMPDialect: ) { !$omp parallel num_threads(num_threads) if(alpha .le. 0) allocate(omp_high_bw_mem_alloc: alpha) private(alpha) !FIRDialect: fir.call diff --git a/flang/test/Lower/OpenMP/FIR/sections.f90 b/flang/test/Lower/OpenMP/FIR/sections.f90 index 640ec34a05bc..7b313f3dc0b4 100644 --- a/flang/test/Lower/OpenMP/FIR/sections.f90 +++ b/flang/test/Lower/OpenMP/FIR/sections.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! This test checks the lowering of OpenMP sections construct with several clauses present ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s @@ -5,8 +7,8 @@ !CHECK: func @_QQmain() attributes {fir.bindc_name = "sample"} { !CHECK: %[[COUNT:.*]] = fir.address_of(@_QFEcount) : !fir.ref<i32> !CHECK: %[[ETA:.*]] = fir.alloca f32 {bindc_name = "eta", uniq_name = "_QFEeta"} -!CHECK: %[[CONST_1:.*]] = arith.constant 1 : i32 -!CHECK: omp.sections allocate(%[[CONST_1]] : i32 -> %0 : !fir.ref<i32>) { +!CHECK: %[[CONST_1:.*]] = arith.constant 4 : i64 +!CHECK: omp.sections allocate(%[[CONST_1]] : i64 -> %0 : !fir.ref<i32>) { !CHECK: omp.section { !CHECK: %[[PRIVATE_ETA:.*]] = fir.alloca f32 {bindc_name = "eta", pinned, uniq_name = "_QFEeta"} !CHECK: %[[PRIVATE_DOUBLE_COUNT:.*]] = fir.alloca i32 {bindc_name = "double_count", pinned, uniq_name = "_QFEdouble_count"} diff --git a/flang/test/Lower/OpenMP/FIR/single.f90 b/flang/test/Lower/OpenMP/FIR/single.f90 index 266f6d94c60d..65ae07c2c284 100644 --- a/flang/test/Lower/OpenMP/FIR/single.f90 +++ b/flang/test/Lower/OpenMP/FIR/single.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s !RUN: bbc -emit-fir -hlfir=false -fopenmp %s -o - | FileCheck %s @@ -55,7 +57,7 @@ subroutine single_allocate() integer :: x !CHECK: omp.parallel { !$omp parallel - !CHECK: omp.single allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) { + !CHECK: omp.single allocate(%{{.+}} : i64 -> %{{.+}} : !fir.ref<i32>) { !$omp single allocate(omp_high_bw_mem_alloc: x) private(x) !CHECK: arith.addi x = x + 12 diff --git a/flang/test/Lower/OpenMP/FIR/task.f90 b/flang/test/Lower/OpenMP/FIR/task.f90 index 4e7e54588c79..012ac757d304 100644 --- a/flang/test/Lower/OpenMP/FIR/task.f90 +++ b/flang/test/Lower/OpenMP/FIR/task.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s !CHECK-LABEL: func @_QPomp_task_simple() { @@ -63,7 +65,7 @@ end subroutine omp_task_priority subroutine task_allocate() use omp_lib integer :: x - !CHECK: omp.task allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) { + !CHECK: omp.task allocate(%{{.+}} : i64 -> %{{.+}} : !fir.ref<i32>) { !$omp task allocate(omp_high_bw_mem_alloc: x) private(x) !CHECK: arith.addi x = x + 12 @@ -217,7 +219,7 @@ subroutine task_multiple_clauses() integer :: x, y, z logical :: buzz - !CHECK: omp.task if(%{{.+}}) final(%{{.+}}) priority(%{{.+}}) allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) { + !CHECK: omp.task if(%{{.+}}) final(%{{.+}}) priority(%{{.+}}) allocate(%{{.+}} : i64 -> %{{.+}} : !fir.ref<i32>) { !$omp task if(buzz) final(buzz) priority(z) allocate(omp_high_bw_mem_alloc: x) private(x) firstprivate(y) !CHECK: %[[x_priv:.+]] = fir.alloca i32 diff --git a/flang/test/Lower/OpenMP/FIR/taskgroup.f90 b/flang/test/Lower/OpenMP/FIR/taskgroup.f90 index 55aba3ddb6c2..78b9da8e9b09 100644 --- a/flang/test/Lower/OpenMP/FIR/taskgroup.f90 +++ b/flang/test/Lower/OpenMP/FIR/taskgroup.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s !CHECK-LABEL: @_QPomp_taskgroup @@ -5,9 +7,9 @@ subroutine omp_taskgroup use omp_lib integer :: allocated_x !CHECK-DAG: %{{.*}} = fir.alloca i32 {bindc_name = "allocated_x", uniq_name = "_QFomp_taskgroupEallocated_x"} -!CHECK-DAG: %{{.*}} = arith.constant 1 : i32 +!CHECK-DAG: %{{.*}} = arith.constant 4 : i64 -!CHECK: omp.taskgroup allocate(%{{.*}} : i32 -> %0 : !fir.ref<i32>) +!CHECK: omp.taskgroup allocate(%{{.*}} : i64 -> %0 : !fir.ref<i32>) !$omp taskgroup allocate(omp_high_bw_mem_alloc: allocated_x) !$omp task !CHECK: fir.call @_QPwork() {{.*}}: () -> () diff --git a/flang/test/Lower/OpenMP/FIR/teams.f90 b/flang/test/Lower/OpenMP/FIR/teams.f90 index 51f9087acb0b..9c0593a24f2d 100644 --- a/flang/test/Lower/OpenMP/FIR/teams.f90 +++ b/flang/test/Lower/OpenMP/FIR/teams.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s ! CHECK-LABEL: func @_QPteams_simple @@ -104,8 +106,9 @@ end subroutine teams_threadlimit subroutine teams_allocate() use omp_lib integer :: x + integer :: y ! CHECK: omp.teams - ! CHECK-SAME: allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) + ! CHECK-SAME: allocate(%{{.+}} : i64 -> %{{.+}} : !fir.ref<i32>) !$omp teams allocate(omp_high_bw_mem_alloc: x) private(x) ! CHECK: arith.addi x = x + 12 diff --git a/flang/test/Lower/OpenMP/atomic-capture.f90 b/flang/test/Lower/OpenMP/atomic-capture.f90 index cde0281dbdc8..2587c24cedf3 100644 --- a/flang/test/Lower/OpenMP/atomic-capture.f90 +++ b/flang/test/Lower/OpenMP/atomic-capture.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! This test checks the lowering of atomic capture ! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s diff --git a/flang/test/Lower/OpenMP/atomic-read.f90 b/flang/test/Lower/OpenMP/atomic-read.f90 index 97a3777bd3dc..366da21f53f8 100644 --- a/flang/test/Lower/OpenMP/atomic-read.f90 +++ b/flang/test/Lower/OpenMP/atomic-read.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s ! This test checks the lowering of atomic read diff --git a/flang/test/Lower/OpenMP/atomic-update.f90 b/flang/test/Lower/OpenMP/atomic-update.f90 index 10da97c68c24..051779e40816 100644 --- a/flang/test/Lower/OpenMP/atomic-update.f90 +++ b/flang/test/Lower/OpenMP/atomic-update.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! This test checks lowering of atomic and atomic update constructs ! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s diff --git a/flang/test/Lower/OpenMP/atomic-write.f90 b/flang/test/Lower/OpenMP/atomic-write.f90 index 119f60c1a92f..85955af64bbe 100644 --- a/flang/test/Lower/OpenMP/atomic-write.f90 +++ b/flang/test/Lower/OpenMP/atomic-write.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s ! This test checks the lowering of atomic write @@ -21,8 +23,8 @@ !CHECK: %[[Z_VAL:.*]] = fir.load %[[Z_DECL]]#0 : !fir.ref<i32> !CHECK: %[[C2:.*]] = arith.constant 2 : i32 !CHECK: %[[Z_DIV_2:.*]] = arith.divsi %[[Z_VAL]], %[[C2]] : i32 -!CHECK: %172 = arith.addi %[[TEN_X]], %[[Z_DIV_2]] : i32 -!CHECK: omp.atomic.write %163#1 = %172 hint(speculative) memory_order(release) : !fir.ref<i32>, i32 +!CHECK: %[[ADD_RES:.*]] = arith.addi %[[TEN_X]], %[[Z_DIV_2]] : i32 +!CHECK: omp.atomic.write %[[Y_DECL]]#1 = %[[ADD_RES]] hint(speculative) memory_order(release) : !fir.ref<i32>, i32 program OmpAtomicWrite use omp_lib diff --git a/flang/test/Lower/OpenMP/critical.f90 b/flang/test/Lower/OpenMP/critical.f90 index 5a4d2e4815df..38e6d0eac1cb 100644 --- a/flang/test/Lower/OpenMP/critical.f90 +++ b/flang/test/Lower/OpenMP/critical.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s !CHECK: omp.critical.declare @help2 diff --git a/flang/test/Lower/OpenMP/omp-lib-num-threads.f90 b/flang/test/Lower/OpenMP/omp-lib-num-threads.f90 index e1af7d375dfa..d2b558a886eb 100644 --- a/flang/test/Lower/OpenMP/omp-lib-num-threads.f90 +++ b/flang/test/Lower/OpenMP/omp-lib-num-threads.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - 2>&1 | FileCheck %s ! RUN: bbc -fopenmp -emit-hlfir -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-fir -fopenmp %s -o - 2>&1 | FileCheck %s diff --git a/flang/test/Lower/OpenMP/parallel-sections.f90 b/flang/test/Lower/OpenMP/parallel-sections.f90 index 77139e40ed8c..2f78dd4562b0 100644 --- a/flang/test/Lower/OpenMP/parallel-sections.f90 +++ b/flang/test/Lower/OpenMP/parallel-sections.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s !=============================================================================== @@ -37,12 +39,12 @@ end subroutine omp_parallel_sections subroutine omp_parallel_sections_allocate(x, y) use omp_lib integer, intent(inout) :: x, y - !CHECK: %[[allocator_1:.*]] = arith.constant 1 : i32 - !CHECK: %[[allocator_2:.*]] = arith.constant 1 : i32 + !CHECK: %[[allocator_1:.*]] = arith.constant 4 : i64 + !CHECK: %[[allocator_2:.*]] = arith.constant 4 : i64 !CHECK: omp.parallel allocate( - !CHECK: %[[allocator_2]] : i32 -> %{{.*}} : !fir.ref<i32>) { + !CHECK: %[[allocator_2]] : i64 -> %{{.*}} : !fir.ref<i32>) { !CHECK: omp.sections allocate( - !CHECK: %[[allocator_1]] : i32 -> %{{.*}} : !fir.ref<i32>) { + !CHECK: %[[allocator_1]] : i64 -> %{{.*}} : !fir.ref<i32>) { !$omp parallel sections allocate(omp_high_bw_mem_alloc: x) !CHECK: omp.section { !$omp section diff --git a/flang/test/Lower/OpenMP/parallel.f90 b/flang/test/Lower/OpenMP/parallel.f90 index 0e43244994cf..6c062b706ed4 100644 --- a/flang/test/Lower/OpenMP/parallel.f90 +++ b/flang/test/Lower/OpenMP/parallel.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s !CHECK-LABEL: func @_QPparallel_simple @@ -152,7 +154,7 @@ subroutine parallel_allocate() use omp_lib integer :: x !CHECK: omp.parallel allocate( - !CHECK: %{{.+}} : i32 -> %{{.+}} : !fir.ref<i32> + !CHECK: %{{.+}} : i64 -> %{{.+}} : !fir.ref<i32> !CHECK: ) { !$omp parallel allocate(omp_high_bw_mem_alloc: x) private(x) !CHECK: arith.addi @@ -193,7 +195,7 @@ subroutine parallel_multiple_clauses(alpha, num_threads) !$omp end parallel !CHECK: omp.parallel if({{.*}} : i1) num_threads({{.*}} : i32) allocate( - !CHECK: %{{.+}} : i32 -> %{{.+}} : !fir.ref<i32> + !CHECK: %{{.+}} : i64 -> %{{.+}} : !fir.ref<i32> !CHECK: ) { !$omp parallel num_threads(num_threads) if(alpha .le. 0) allocate(omp_high_bw_mem_alloc: alpha) private(alpha) !CHECK: fir.call diff --git a/flang/test/Lower/OpenMP/sections.f90 b/flang/test/Lower/OpenMP/sections.f90 index 6bad688058d2..018848e63573 100644 --- a/flang/test/Lower/OpenMP/sections.f90 +++ b/flang/test/Lower/OpenMP/sections.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! This test checks the lowering of OpenMP sections construct with several clauses present ! RUN: %flang_fc1 -flang-experimental-hlfir -emit-hlfir -fopenmp %s -o - | FileCheck %s @@ -7,8 +9,8 @@ !CHECK: %[[COUNT:.*]] = fir.address_of(@_QFEcount) : !fir.ref<i32> !CHECK: %[[COUNT_DECL:.*]]:2 = hlfir.declare %[[COUNT]] {uniq_name = "_QFEcount"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) !CHECK: %[[ETA:.*]] = fir.alloca f32 {bindc_name = "eta", uniq_name = "_QFEeta"} -!CHECK: %[[CONST_1:.*]] = arith.constant 1 : i32 -!CHECK: omp.sections allocate(%[[CONST_1]] : i32 -> %[[COUNT_DECL]]#1 : !fir.ref<i32>) { +!CHECK: %[[CONST_1:.*]] = arith.constant 4 : i64 +!CHECK: omp.sections allocate(%[[CONST_1]] : i64 -> %[[COUNT_DECL]]#1 : !fir.ref<i32>) { !CHECK: omp.section { !CHECK: %[[PRIVATE_ETA:.*]] = fir.alloca f32 {bindc_name = "eta", pinned, uniq_name = "_QFEeta"} !CHECK: %[[PRIVATE_ETA_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_ETA]] {uniq_name = "_QFEeta"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) diff --git a/flang/test/Lower/OpenMP/single.f90 b/flang/test/Lower/OpenMP/single.f90 index ffc41af84e3c..10d537a0e18b 100644 --- a/flang/test/Lower/OpenMP/single.f90 +++ b/flang/test/Lower/OpenMP/single.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s !RUN: bbc -emit-hlfir -fopenmp %s -o - | FileCheck %s @@ -57,7 +59,7 @@ subroutine single_allocate() integer :: x !CHECK: omp.parallel { !$omp parallel - !CHECK: omp.single allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) { + !CHECK: omp.single allocate(%{{.+}} : i64 -> %{{.+}} : !fir.ref<i32>) { !$omp single allocate(omp_high_bw_mem_alloc: x) private(x) !CHECK: arith.addi x = x + 12 diff --git a/flang/test/Lower/OpenMP/task.f90 b/flang/test/Lower/OpenMP/task.f90 index 7d7a79af3185..f3718b8829cc 100644 --- a/flang/test/Lower/OpenMP/task.f90 +++ b/flang/test/Lower/OpenMP/task.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s !CHECK-LABEL: func @_QPomp_task_simple() { @@ -63,7 +65,7 @@ end subroutine omp_task_priority subroutine task_allocate() use omp_lib integer :: x - !CHECK: omp.task allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) { + !CHECK: omp.task allocate(%{{.+}} : i64 -> %{{.+}} : !fir.ref<i32>) { !$omp task allocate(omp_high_bw_mem_alloc: x) private(x) !CHECK: arith.addi x = x + 12 @@ -225,7 +227,7 @@ subroutine task_multiple_clauses() integer :: x, y, z logical :: buzz - !CHECK: omp.task if(%{{.+}}) final(%{{.+}}) priority(%{{.+}}) allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) { + !CHECK: omp.task if(%{{.+}}) final(%{{.+}}) priority(%{{.+}}) allocate(%{{.+}} : i64 -> %{{.+}} : !fir.ref<i32>) { !$omp task if(buzz) final(buzz) priority(z) allocate(omp_high_bw_mem_alloc: x) private(x) firstprivate(y) !CHECK: %[[X_PRIV_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "x", pinned, uniq_name = "_QFtask_multiple_clausesEx"} diff --git a/flang/test/Lower/OpenMP/taskgroup.f90 b/flang/test/Lower/OpenMP/taskgroup.f90 index 85dc253b59d6..76458f1f1127 100644 --- a/flang/test/Lower/OpenMP/taskgroup.f90 +++ b/flang/test/Lower/OpenMP/taskgroup.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + !RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s !CHECK-LABEL: @_QPomp_taskgroup @@ -6,9 +8,9 @@ use omp_lib integer :: allocated_x !CHECK: %[[ALLOC_X_REF:.*]] = fir.alloca i32 {bindc_name = "allocated_x", uniq_name = "_QFomp_taskgroupEallocated_x"} !CHECK-NEXT: %[[ALLOC_X_DECL:.*]]:2 = hlfir.declare %[[ALLOC_X_REF]] {uniq_name = "_QFomp_taskgroupEallocated_x"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) -!CHECK: %[[C1:.*]] = arith.constant 1 : i32 +!CHECK: %[[C4:.*]] = arith.constant 4 : i64 -!CHECK: omp.taskgroup allocate(%[[C1]] : i32 -> %[[ALLOC_X_DECL]]#1 : !fir.ref<i32>) +!CHECK: omp.taskgroup allocate(%[[C4]] : i64 -> %[[ALLOC_X_DECL]]#1 : !fir.ref<i32>) !$omp taskgroup allocate(omp_high_bw_mem_alloc: allocated_x) !$omp task !CHECK: fir.call @_QPwork() {{.*}}: () -> () diff --git a/flang/test/Lower/OpenMP/teams.f90 b/flang/test/Lower/OpenMP/teams.f90 index 2620d7752a4e..f122a578a6e1 100644 --- a/flang/test/Lower/OpenMP/teams.f90 +++ b/flang/test/Lower/OpenMP/teams.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s ! CHECK-LABEL: func @_QPteams_simple @@ -105,7 +107,7 @@ subroutine teams_allocate() use omp_lib integer :: x ! CHECK: omp.teams - ! CHECK-SAME: allocate(%{{.+}} : i32 -> %{{.+}} : !fir.ref<i32>) + ! CHECK-SAME: allocate(%{{.+}} : i64 -> %{{.+}} : !fir.ref<i32>) !$omp teams allocate(omp_high_bw_mem_alloc: x) private(x) ! CHECK: arith.addi x = x + 12 diff --git a/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 b/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 index be07aeca2d5c..10beaf6fefde 100644 --- a/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 +++ b/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! Simple test for lowering of OpenMP Threadprivate Directive with HLFIR. !RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s diff --git a/flang/test/Parser/OpenMP/allocate-tree-spec-part.f90 b/flang/test/Parser/OpenMP/allocate-tree-spec-part.f90 index 45a693d2cb04..ab56b98b5783 100644 --- a/flang/test/Parser/OpenMP/allocate-tree-spec-part.f90 +++ b/flang/test/Parser/OpenMP/allocate-tree-spec-part.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %flang_fc1 -fopenmp -fdebug-dump-parse-tree %s | FileCheck %s ! Ensures associated declarative OMP allocations in the specification ! part are kept there diff --git a/flang/test/Parser/OpenMP/allocate-tree.f90 b/flang/test/Parser/OpenMP/allocate-tree.f90 index f04e431e74ae..02393a536cf4 100644 --- a/flang/test/Parser/OpenMP/allocate-tree.f90 +++ b/flang/test/Parser/OpenMP/allocate-tree.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %flang_fc1 -fopenmp -fdebug-dump-parse-tree %s | FileCheck %s ! RUN: %flang_fc1 -fopenmp -fdebug-unparse %s | FileCheck %s --check-prefix="UNPARSE" ! Ensures associated declarative OMP allocations are nested in their @@ -36,8 +38,8 @@ end program allocate_tree !CHECK-NEXT: | | | | | Designator -> DataRef -> Name = !CHECK-NEXT: | | | AllocateStmt -!UNPARSE: !$OMP ALLOCATE (w) ALLOCATOR(1_4) -!UNPARSE-NEXT: !$OMP ALLOCATE (xarray) ALLOCATOR(1_4) -!UNPARSE-NEXT: !$OMP ALLOCATE (zarray) ALLOCATOR(1_4) +!UNPARSE: !$OMP ALLOCATE (w) ALLOCATOR(3_8) +!UNPARSE-NEXT: !$OMP ALLOCATE (xarray) ALLOCATOR(2_8) +!UNPARSE-NEXT: !$OMP ALLOCATE (zarray) ALLOCATOR(1_8) !UNPARSE-NEXT: !$OMP ALLOCATE !UNPARSE-NEXT: ALLOCATE(w, xarray(4_4), zarray(t,z)) diff --git a/flang/test/Parser/OpenMP/target_device_parse.f90 b/flang/test/Parser/OpenMP/target_device_parse.f90 index 1867c2f2a86c..dace34b6ec32 100644 --- a/flang/test/Parser/OpenMP/target_device_parse.f90 +++ b/flang/test/Parser/OpenMP/target_device_parse.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck --ignore-case %s ! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s ! Checks the parsing of Openmp 5.0 Target Device constructs diff --git a/flang/test/Semantics/OpenMP/allocate-clause01.f90 b/flang/test/Semantics/OpenMP/allocate-clause01.f90 index 7e2f64397f73..e059a4a61a90 100644 --- a/flang/test/Semantics/OpenMP/allocate-clause01.f90 +++ b/flang/test/Semantics/OpenMP/allocate-clause01.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.2 ! The allocate clause's allocator modifier must be of type allocator_handle diff --git a/flang/test/Semantics/OpenMP/allocate-directive.f90 b/flang/test/Semantics/OpenMP/allocate-directive.f90 index 254e5b617a7a..1db13df41938 100644 --- a/flang/test/Semantics/OpenMP/allocate-directive.f90 +++ b/flang/test/Semantics/OpenMP/allocate-directive.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! Check OpenMP Allocate directive use omp_lib diff --git a/flang/test/Semantics/OpenMP/allocate01.f90 b/flang/test/Semantics/OpenMP/allocate01.f90 index 4b290a5c2c74..a91076c80b1f 100644 --- a/flang/test/Semantics/OpenMP/allocate01.f90 +++ b/flang/test/Semantics/OpenMP/allocate01.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.0 ! 2.11.3 allocate Directive diff --git a/flang/test/Semantics/OpenMP/allocate02.f90 b/flang/test/Semantics/OpenMP/allocate02.f90 index d7da9ef57527..dc4194aca7f1 100644 --- a/flang/test/Semantics/OpenMP/allocate02.f90 +++ b/flang/test/Semantics/OpenMP/allocate02.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.0 ! 2.11.3 allocate Directive diff --git a/flang/test/Semantics/OpenMP/allocate03.f90 b/flang/test/Semantics/OpenMP/allocate03.f90 index 320a9c9ea412..30a015f26c31 100644 --- a/flang/test/Semantics/OpenMP/allocate03.f90 +++ b/flang/test/Semantics/OpenMP/allocate03.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.0 ! 2.11.3 allocate Directive diff --git a/flang/test/Semantics/OpenMP/allocate04.f90 b/flang/test/Semantics/OpenMP/allocate04.f90 index 405781be4c2d..b8a870941161 100644 --- a/flang/test/Semantics/OpenMP/allocate04.f90 +++ b/flang/test/Semantics/OpenMP/allocate04.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.0 ! 2.11.3 allocate Directive diff --git a/flang/test/Semantics/OpenMP/allocate05.f90 b/flang/test/Semantics/OpenMP/allocate05.f90 index 04bcf9119e0f..92eeaf4222ac 100644 --- a/flang/test/Semantics/OpenMP/allocate05.f90 +++ b/flang/test/Semantics/OpenMP/allocate05.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.0 ! 2.11.3 allocate Directive diff --git a/flang/test/Semantics/OpenMP/allocate06.f90 b/flang/test/Semantics/OpenMP/allocate06.f90 index 68a7e8857eb8..c4474560bea3 100644 --- a/flang/test/Semantics/OpenMP/allocate06.f90 +++ b/flang/test/Semantics/OpenMP/allocate06.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.0 ! 2.11.3 allocate Directive diff --git a/flang/test/Semantics/OpenMP/allocate07.f90 b/flang/test/Semantics/OpenMP/allocate07.f90 index c01b35ab2740..3211c0bf28b9 100644 --- a/flang/test/Semantics/OpenMP/allocate07.f90 +++ b/flang/test/Semantics/OpenMP/allocate07.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.0 ! 2.11.3 allocate Directive diff --git a/flang/test/Semantics/OpenMP/allocate08.f90 b/flang/test/Semantics/OpenMP/allocate08.f90 index 65029d1ce0e5..152ad07544ea 100644 --- a/flang/test/Semantics/OpenMP/allocate08.f90 +++ b/flang/test/Semantics/OpenMP/allocate08.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.0 ! 2.11.3 allocate Directive diff --git a/flang/test/Semantics/OpenMP/allocate09.f90 b/flang/test/Semantics/OpenMP/allocate09.f90 index 26d6ff98c4a3..639d23cd6d30 100644 --- a/flang/test/Semantics/OpenMP/allocate09.f90 +++ b/flang/test/Semantics/OpenMP/allocate09.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.0 ! 2.11.3 allocate Directive diff --git a/flang/test/Semantics/OpenMP/allocators01.f90 b/flang/test/Semantics/OpenMP/allocators01.f90 index d674438b2ab2..02d686b49716 100644 --- a/flang/test/Semantics/OpenMP/allocators01.f90 +++ b/flang/test/Semantics/OpenMP/allocators01.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.2 ! 6.7 allocators construct diff --git a/flang/test/Semantics/OpenMP/allocators02.f90 b/flang/test/Semantics/OpenMP/allocators02.f90 index 32e7bc18ad99..9d8644bc30c6 100644 --- a/flang/test/Semantics/OpenMP/allocators02.f90 +++ b/flang/test/Semantics/OpenMP/allocators02.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.2 ! 6.7 allocators construct diff --git a/flang/test/Semantics/OpenMP/allocators03.f90 b/flang/test/Semantics/OpenMP/allocators03.f90 index 533434c2ace0..85ab91fde5e0 100644 --- a/flang/test/Semantics/OpenMP/allocators03.f90 +++ b/flang/test/Semantics/OpenMP/allocators03.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.2 ! 6.7 allocators construct diff --git a/flang/test/Semantics/OpenMP/allocators04.f90 b/flang/test/Semantics/OpenMP/allocators04.f90 index d4467a2052a7..0c6e994e137a 100644 --- a/flang/test/Semantics/OpenMP/allocators04.f90 +++ b/flang/test/Semantics/OpenMP/allocators04.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.2 ! Inherited from 2.11.3 allocate Directive diff --git a/flang/test/Semantics/OpenMP/allocators05.f90 b/flang/test/Semantics/OpenMP/allocators05.f90 index 684eef695049..07f1357b75b5 100644 --- a/flang/test/Semantics/OpenMP/allocators05.f90 +++ b/flang/test/Semantics/OpenMP/allocators05.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.2 ! Inherited from 2.11.3 allocate directive diff --git a/flang/test/Semantics/OpenMP/allocators06.f90 b/flang/test/Semantics/OpenMP/allocators06.f90 index 17e168d4cfe0..d3773c05a485 100644 --- a/flang/test/Semantics/OpenMP/allocators06.f90 +++ b/flang/test/Semantics/OpenMP/allocators06.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.2 ! Inherited from 2.11.3 allocate directive diff --git a/flang/test/Semantics/OpenMP/atomic-hint-clause.f90 b/flang/test/Semantics/OpenMP/atomic-hint-clause.f90 index 5341fb2e7d28..3cbde3ab586c 100644 --- a/flang/test/Semantics/OpenMP/atomic-hint-clause.f90 +++ b/flang/test/Semantics/OpenMP/atomic-hint-clause.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! Semantic checks on hint clauses, as they appear on atomic constructs diff --git a/flang/test/Semantics/OpenMP/atomic01.f90 b/flang/test/Semantics/OpenMP/atomic01.f90 index 5469f82a0083..868c7623928a 100644 --- a/flang/test/Semantics/OpenMP/atomic01.f90 +++ b/flang/test/Semantics/OpenMP/atomic01.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! Semantic checks for OpenMP 5.0 standard 2.17.7 atomic Construct. diff --git a/flang/test/Semantics/OpenMP/atomic02.f90 b/flang/test/Semantics/OpenMP/atomic02.f90 index c11622c87cbd..db67fa63dcdf 100644 --- a/flang/test/Semantics/OpenMP/atomic02.f90 +++ b/flang/test/Semantics/OpenMP/atomic02.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Atomic construct diff --git a/flang/test/Semantics/OpenMP/atomic03.f90 b/flang/test/Semantics/OpenMP/atomic03.f90 index 5fc642088ca5..9bcbace10fb6 100644 --- a/flang/test/Semantics/OpenMP/atomic03.f90 +++ b/flang/test/Semantics/OpenMP/atomic03.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Atomic construct diff --git a/flang/test/Semantics/OpenMP/atomic04.f90 b/flang/test/Semantics/OpenMP/atomic04.f90 index ddf6b8bc2f5f..c0419a69d2dd 100644 --- a/flang/test/Semantics/OpenMP/atomic04.f90 +++ b/flang/test/Semantics/OpenMP/atomic04.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Atomic construct diff --git a/flang/test/Semantics/OpenMP/atomic05.f90 b/flang/test/Semantics/OpenMP/atomic05.f90 index b3ff6e9b910f..7b970dba8e49 100644 --- a/flang/test/Semantics/OpenMP/atomic05.f90 +++ b/flang/test/Semantics/OpenMP/atomic05.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang -fopenmp ! This tests the various semantics related to the clauses of various OpenMP atomic constructs diff --git a/flang/test/Semantics/OpenMP/clause-validity01.f90 b/flang/test/Semantics/OpenMP/clause-validity01.f90 index d9573a81821f..977a52986461 100644 --- a/flang/test/Semantics/OpenMP/clause-validity01.f90 +++ b/flang/test/Semantics/OpenMP/clause-validity01.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp use omp_lib ! Check OpenMP clause validity for the following directives: diff --git a/flang/test/Semantics/OpenMP/critical-hint-clause.f90 b/flang/test/Semantics/OpenMP/critical-hint-clause.f90 index 33088c6caf35..f35eea149135 100644 --- a/flang/test/Semantics/OpenMP/critical-hint-clause.f90 +++ b/flang/test/Semantics/OpenMP/critical-hint-clause.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! Semantic checks on hint clauses, as they appear on critical construct diff --git a/flang/test/Semantics/OpenMP/declare-target01.f90 b/flang/test/Semantics/OpenMP/declare-target01.f90 index 3168781ba383..549f708b08f9 100644 --- a/flang/test/Semantics/OpenMP/declare-target01.f90 +++ b/flang/test/Semantics/OpenMP/declare-target01.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.1 ! Check OpenMP construct validity for the following directives: diff --git a/flang/test/Semantics/OpenMP/flush02.f90 b/flang/test/Semantics/OpenMP/flush02.f90 index 7700954b1906..dbb57ac81450 100644 --- a/flang/test/Semantics/OpenMP/flush02.f90 +++ b/flang/test/Semantics/OpenMP/flush02.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! Check OpenMP 5.0 - 2.17.8 flush Construct diff --git a/flang/test/Semantics/OpenMP/omp-atomic-assignment-stmt.f90 b/flang/test/Semantics/OpenMP/omp-atomic-assignment-stmt.f90 index 7e2d508839ff..d9ced2cd7950 100644 --- a/flang/test/Semantics/OpenMP/omp-atomic-assignment-stmt.f90 +++ b/flang/test/Semantics/OpenMP/omp-atomic-assignment-stmt.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! Semantic checks for various assignments related to atomic constructs diff --git a/flang/test/Semantics/OpenMP/parallel-sections01.f90 b/flang/test/Semantics/OpenMP/parallel-sections01.f90 index c5bfbdfcb7b2..2bf58ea2cb29 100644 --- a/flang/test/Semantics/OpenMP/parallel-sections01.f90 +++ b/flang/test/Semantics/OpenMP/parallel-sections01.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang -fopenmp ! OpenMP version 5.0.0 ! 2.13.3 parallel sections Construct diff --git a/flang/test/Semantics/OpenMP/resolve06.f90 b/flang/test/Semantics/OpenMP/resolve06.f90 index 1afc7408c0bc..f97290500559 100644 --- a/flang/test/Semantics/OpenMP/resolve06.f90 +++ b/flang/test/Semantics/OpenMP/resolve06.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp use omp_lib !2.11.4 Allocate Clause diff --git a/flang/test/Semantics/OpenMP/sections02.f90 b/flang/test/Semantics/OpenMP/sections02.f90 index bcdeb05e5a17..b96455a960ef 100644 --- a/flang/test/Semantics/OpenMP/sections02.f90 +++ b/flang/test/Semantics/OpenMP/sections02.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang -fopenmp ! OpenMP version 5.0.0 ! 2.8.1 sections construct diff --git a/flang/test/Semantics/OpenMP/sync-critical02.f90 b/flang/test/Semantics/OpenMP/sync-critical02.f90 index dac031f4f8fc..fdd95fa76ad7 100644 --- a/flang/test/Semantics/OpenMP/sync-critical02.f90 +++ b/flang/test/Semantics/OpenMP/sync-critical02.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang -fopenmp ! OpenMP Version 5.0 diff --git a/flang/test/Semantics/OpenMP/taskgroup01.f90 b/flang/test/Semantics/OpenMP/taskgroup01.f90 index a2494129b580..e3185552a44b 100644 --- a/flang/test/Semantics/OpenMP/taskgroup01.f90 +++ b/flang/test/Semantics/OpenMP/taskgroup01.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang -fopenmp use omp_lib diff --git a/flang/test/Semantics/OpenMP/threadprivate01.f90 b/flang/test/Semantics/OpenMP/threadprivate01.f90 index 309d209a4567..5ba5f400eb20 100644 --- a/flang/test/Semantics/OpenMP/threadprivate01.f90 +++ b/flang/test/Semantics/OpenMP/threadprivate01.f90 @@ -1,3 +1,5 @@ +! REQUIRES: openmp_runtime + ! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp ! OpenMP Version 5.1 ! Check OpenMP construct validity for the following directives: diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py index 65467f2d23f4..5eeada0e9ee3 100644 --- a/flang/test/lit.cfg.py +++ b/flang/test/lit.cfg.py @@ -200,6 +200,10 @@ result = lit_config.params.get("LIBPGMATH") if result: config.environment["LIBPGMATH"] = True +# Determine if OpenMP runtime was built (enable OpenMP tests via REQUIRES in test file) +if config.have_openmp_rtl: + config.available_features.add("openmp_runtime") + # Add features and substitutions to test F128 math support. # %f128-lib substitution may be used to generate check prefixes # for LIT tests checking for F128 library support. diff --git a/flang/test/lit.site.cfg.py.in b/flang/test/lit.site.cfg.py.in index e66f1af79452..b9b7a7c5fd63 100644 --- a/flang/test/lit.site.cfg.py.in +++ b/flang/test/lit.site.cfg.py.in @@ -25,6 +25,7 @@ config.cc = "@CMAKE_C_COMPILER@" config.osx_sysroot = path(r"@CMAKE_OSX_SYSROOT@") config.targets_to_build = "@TARGETS_TO_BUILD@" config.default_sysroot = "@DEFAULT_SYSROOT@" +config.have_openmp_rtl = ("@LLVM_TOOL_OPENMP_BUILD@" == "TRUE") config.flang_runtime_f128_math_lib = "@FLANG_RUNTIME_F128_MATH_LIB@" import lit.llvm diff --git a/flang/tools/f18/CMakeLists.txt b/flang/tools/f18/CMakeLists.txt index a24958316831..3a31f4df1607 100644 --- a/flang/tools/f18/CMakeLists.txt +++ b/flang/tools/f18/CMakeLists.txt @@ -17,7 +17,6 @@ set(MODULES "ieee_features" "iso_c_binding" "iso_fortran_env" - "omp_lib" "__fortran_builtins" "__fortran_type_info" ) @@ -59,6 +58,7 @@ if (NOT CMAKE_CROSSCOMPILING) endif() endif() + # TODO: We may need to flag this with conditional, in case Flang is built w/o OpenMP support add_custom_command(OUTPUT ${base}.mod COMMAND ${CMAKE_COMMAND} -E make_directory ${FLANG_INTRINSIC_MODULES_DIR} COMMAND flang-new -cpp -fsyntax-only ${opts} -module-dir ${FLANG_INTRINSIC_MODULES_DIR} @@ -71,6 +71,30 @@ if (NOT CMAKE_CROSSCOMPILING) list(APPEND MODULE_FILES ${base}.mod ${base}.f18.mod) install(FILES ${base}.mod ${base}.f18.mod DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang") endforeach() + + # Special case for omp_lib.mod, because its source comes from openmp/runtime/src/include. + # It also produces two module files: omp_lib.mod and omp_lib_kinds.mod. Compile these + # files only if OpenMP support has been configured. + if (LLVM_TOOL_OPENMP_BUILD) + message(STATUS "OpenMP runtime support enabled via LLVM_ENABLED_PROJECTS, building omp_lib.mod") + set(base ${FLANG_INTRINSIC_MODULES_DIR}/omp_lib) + add_custom_command(OUTPUT ${base}.mod ${base}_kinds.mod + COMMAND ${CMAKE_COMMAND} -E make_directory ${FLANG_INTRINSIC_MODULES_DIR} + COMMAND flang-new -cpp -fsyntax-only ${opts} -module-dir ${FLANG_INTRINSIC_MODULES_DIR} + ${CMAKE_BINARY_DIR}/projects/openmp/runtime/src/omp_lib.F90 + DEPENDS flang-new ${FLANG_INTRINSIC_MODULES_DIR}/iso_c_binding.mod ${CMAKE_BINARY_DIR}/projects/openmp/runtime/src/omp_lib.F90 ${depends} + ) + add_custom_command(OUTPUT ${base}.f18.mod + DEPENDS ${base}.mod + COMMAND ${CMAKE_COMMAND} -E copy ${base}.mod ${base}.f18.mod) + add_custom_command(OUTPUT ${base}_kinds.f18.mod + DEPENDS ${base}.mod + COMMAND ${CMAKE_COMMAND} -E copy ${base}_kinds.mod ${base}_kinds.f18.mod) + list(APPEND MODULE_FILES ${base}.mod ${base}.f18.mod ${base}_kinds.mod ${base}_kinds.f18.mod) + install(FILES ${base}.mod ${base}.f18.mod ${base}_kinds.mod ${base}_kinds.f18.mod DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang") + else() + message(STATUS "Not building omp_lib.mod, no OpenMP runtime in LLVM_ENABLED_PROJECTS") + endif() endif() add_custom_target(module_files ALL DEPENDS ${MODULE_FILES}) @@ -87,5 +111,11 @@ if (NOT WIN32) endif() # TODO Move this to a more suitable location -file(COPY ${FLANG_SOURCE_DIR}/module/omp_lib.h DESTINATION "${CMAKE_BINARY_DIR}/include/flang/OpenMP/" FILE_PERMISSIONS OWNER_READ OWNER_WRITE) -install(FILES ${CMAKE_BINARY_DIR}/include/flang/OpenMP/omp_lib.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang/OpenMP") +# Copy the generated omp_lib.h header file, if OpenMP support has been configured. +if (LLVM_TOOL_OPENMP_BUILD) + message(STATUS "OpenMP runtime support enabled via LLVM_ENABLED_PROJECTS, building omp_lib.h") + file(COPY ${CMAKE_BINARY_DIR}/projects/openmp/runtime/src/omp_lib.h DESTINATION "${CMAKE_BINARY_DIR}/include/flang/OpenMP/" FILE_PERMISSIONS OWNER_READ OWNER_WRITE) + install(FILES ${CMAKE_BINARY_DIR}/include/flang/OpenMP/omp_lib.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang/OpenMP") +else() + message(STATUS "Not copying omp_lib.h, no OpenMP runtime in LLVM_ENABLED_PROJECTS") +endif() diff --git a/llvm/runtimes/CMakeLists.txt b/llvm/runtimes/CMakeLists.txt index 54ec8bd28d4c..623c43d564cc 100644 --- a/llvm/runtimes/CMakeLists.txt +++ b/llvm/runtimes/CMakeLists.txt @@ -425,6 +425,15 @@ if(runtimes) # together in a single CMake invocation. set(extra_deps "") if("openmp" IN_LIST LLVM_ENABLE_RUNTIMES) + if (${LLVM_TOOL_FLANG_BUILD}) + message(STATUS "Configuring build of omp_lib.mod and omp_lib_kinds.mod via flang-new") + set(LIBOMP_FORTRAN_MODULES_COMPILER "${CMAKE_BINARY_DIR}/bin/flang-new") + set(LIBOMP_MODULES_INSTALL_PATH "${CMAKE_INSTALL_INCLUDEDIR}/flang") + # TODO: This is a workaround until flang becomes a first-class project + # in llvm/CMakeList.txt. Until then, this line ensures that flang-new is + # built before "openmp" is built as a runtime project. + list(APPEND extra_deps "flang-new") + endif() foreach(dep opt llvm-link llvm-extract clang clang-offload-packager) if(TARGET ${dep} AND OPENMP_ENABLE_LIBOMPTARGET) list(APPEND extra_deps ${dep}) diff --git a/openmp/runtime/src/CMakeLists.txt b/openmp/runtime/src/CMakeLists.txt index ff129feb5b6f..f05bcabb4417 100644 --- a/openmp/runtime/src/CMakeLists.txt +++ b/openmp/runtime/src/CMakeLists.txt @@ -316,9 +316,25 @@ endif() # Building the Fortran module files # One compilation step creates both omp_lib.mod and omp_lib_kinds.mod -if(${LIBOMP_FORTRAN_MODULES}) - configure_file(${LIBOMP_INC_DIR}/omp_lib.h.var omp_lib.h @ONLY) - configure_file(${LIBOMP_INC_DIR}/omp_lib.f90.var omp_lib.f90 @ONLY) +configure_file(${LIBOMP_INC_DIR}/omp_lib.h.var omp_lib.h @ONLY) +configure_file(${LIBOMP_INC_DIR}/omp_lib.F90.var omp_lib.F90 @ONLY) + +set(BUILD_FORTRAN_MODULES False) +if (NOT ${LIBOMP_FORTRAN_MODULES_COMPILER} STREQUAL "") + # If libomp is built as an LLVM runtime and the flang compiler is available, + # compile the Fortran module files. + message(STATUS "configuring openmp to build Fortran module files using ${LIBOMP_FORTRAN_MODULES_COMPILER}") + set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.F90) + add_custom_target(libomp-mod ALL DEPENDS omp_lib.mod omp_lib_kinds.mod) + add_custom_command( + OUTPUT omp_lib.mod omp_lib_kinds.mod + COMMAND ${LIBOMP_FORTRAN_MODULES_COMPILER} -cpp -fsyntax-only ${LIBOMP_FORTRAN_SOURCE_FILE} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_FORTRAN_SOURCE_FILE} + ${CMAKE_CURRENT_BINARY_DIR}/omp_lib.h + ) + set(BUILD_FORTRAN_MODULES True) +elseif(${LIBOMP_FORTRAN_MODULES}) + # The following requests explicit building of the Fortran module files # Workaround for gfortran to build modules with the # omp_sched_monotonic integer parameter if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") @@ -327,7 +343,7 @@ if(${LIBOMP_FORTRAN_MODULES}) add_custom_target(libomp-mod ALL DEPENDS omp_lib.mod omp_lib_kinds.mod) libomp_get_fflags(LIBOMP_CONFIGURED_FFLAGS) if(CMAKE_Fortran_COMPILER_SUPPORTS_F90) - set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.f90) + set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.F90) else() message(FATAL_ERROR "Fortran module build requires Fortran 90 compiler") endif() @@ -339,6 +355,7 @@ if(${LIBOMP_FORTRAN_MODULES}) ${CMAKE_CURRENT_BINARY_DIR}/omp_lib.h ) set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES omp_lib${CMAKE_C_OUTPUT_EXTENSION}) + set(BUILD_FORTRAN_MODULES True) endif() # Move files to exports/ directory if requested @@ -412,11 +429,15 @@ if(${LIBOMP_OMPT_SUPPORT}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/omp-tools.h DESTINATION ${LIBOMP_HEADERS_INSTALL_PATH} RENAME ompt.h) set(LIBOMP_OMP_TOOLS_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) endif() -if(${LIBOMP_FORTRAN_MODULES}) +if(${BUILD_FORTRAN_MODULES}) + set (destination ${LIBOMP_HEADERS_INSTALL_PATH}) + if (NOT ${LIBOMP_MODULES_INSTALL_PATH} STREQUAL "") + set (destination ${LIBOMP_MODULES_INSTALL_PATH}) + endif() install(FILES ${CMAKE_CURRENT_BINARY_DIR}/omp_lib.h ${CMAKE_CURRENT_BINARY_DIR}/omp_lib.mod ${CMAKE_CURRENT_BINARY_DIR}/omp_lib_kinds.mod - DESTINATION ${LIBOMP_HEADERS_INSTALL_PATH} + DESTINATION ${destination} ) endif() diff --git a/openmp/runtime/src/include/omp_lib.f90.var b/openmp/runtime/src/include/omp_lib.F90.var similarity index 62% rename from openmp/runtime/src/include/omp_lib.f90.var rename to openmp/runtime/src/include/omp_lib.F90.var index 1ca542db3767..63a3c93b8d92 100644 --- a/openmp/runtime/src/include/omp_lib.f90.var +++ b/openmp/runtime/src/include/omp_lib.F90.var @@ -14,37 +14,42 @@ use, intrinsic :: iso_c_binding - integer, parameter :: omp_integer_kind = c_int - integer, parameter :: omp_logical_kind = 4 - integer, parameter :: omp_real_kind = c_float - integer, parameter :: kmp_double_kind = c_double - integer, parameter :: omp_lock_kind = c_intptr_t - integer, parameter :: omp_nest_lock_kind = c_intptr_t - integer, parameter :: omp_sched_kind = omp_integer_kind - integer, parameter :: omp_proc_bind_kind = omp_integer_kind - integer, parameter :: kmp_pointer_kind = c_intptr_t - integer, parameter :: kmp_size_t_kind = c_size_t - integer, parameter :: kmp_affinity_mask_kind = c_intptr_t - integer, parameter :: kmp_cancel_kind = omp_integer_kind - integer, parameter :: omp_sync_hint_kind = omp_integer_kind - integer, parameter :: omp_lock_hint_kind = omp_sync_hint_kind - integer, parameter :: omp_control_tool_kind = omp_integer_kind - integer, parameter :: omp_control_tool_result_kind = omp_integer_kind - integer, parameter :: omp_allocator_handle_kind = c_intptr_t - integer, parameter :: omp_memspace_handle_kind = c_intptr_t - integer, parameter :: omp_alloctrait_key_kind = omp_integer_kind - integer, parameter :: omp_alloctrait_val_kind = c_intptr_t - integer, parameter :: omp_interop_kind = c_intptr_t - integer, parameter :: omp_interop_fr_kind = omp_integer_kind + ! Set PRIVATE by default to explicitly only export what is meant + ! to be exported by this MODULE. + private + + integer, parameter, public :: omp_integer_kind = c_int + integer, parameter, public :: omp_logical_kind = 4 + integer, parameter, public :: omp_real_kind = c_float + integer, parameter, public :: kmp_double_kind = c_double + integer, parameter, public :: omp_lock_kind = c_intptr_t + integer, parameter, public :: omp_nest_lock_kind = c_intptr_t + integer, parameter, public :: omp_sched_kind = omp_integer_kind + integer, parameter, public :: omp_proc_bind_kind = omp_integer_kind + integer, parameter, public :: kmp_pointer_kind = c_intptr_t + integer, parameter, public :: kmp_size_t_kind = c_size_t + integer, parameter, public :: kmp_affinity_mask_kind = c_intptr_t + integer, parameter, public :: kmp_cancel_kind = omp_integer_kind + integer, parameter, public :: omp_sync_hint_kind = omp_integer_kind + integer, parameter, public :: omp_lock_hint_kind = omp_sync_hint_kind + integer, parameter, public :: omp_control_tool_kind = omp_integer_kind + integer, parameter, public :: omp_control_tool_result_kind = omp_integer_kind + integer, parameter, public :: omp_allocator_handle_kind = c_intptr_t + integer, parameter, public :: omp_memspace_handle_kind = c_intptr_t + integer, parameter, public :: omp_alloctrait_key_kind = omp_integer_kind + integer, parameter, public :: omp_alloctrait_val_kind = c_intptr_t + integer, parameter, public :: omp_interop_kind = c_intptr_t + integer, parameter, public :: omp_interop_fr_kind = omp_integer_kind type omp_alloctrait integer(kind=omp_alloctrait_key_kind) key integer(kind=omp_alloctrait_val_kind) value end type omp_alloctrait + public :: omp_alloctrait - integer, parameter :: omp_pause_resource_kind = omp_integer_kind - integer, parameter :: omp_depend_kind = c_intptr_t - integer, parameter :: omp_event_handle_kind = c_intptr_t + integer, parameter, public :: omp_pause_resource_kind = omp_integer_kind + integer, parameter, public :: omp_depend_kind = c_intptr_t + integer, parameter, public :: omp_event_handle_kind = c_intptr_t end module omp_lib_kinds @@ -52,119 +57,151 @@ use omp_lib_kinds - integer (kind=omp_integer_kind), parameter :: openmp_version = @LIBOMP_OMP_YEAR_MONTH@ - integer (kind=omp_integer_kind), parameter :: kmp_version_major = @LIBOMP_VERSION_MAJOR@ - integer (kind=omp_integer_kind), parameter :: kmp_version_minor = @LIBOMP_VERSION_MINOR@ - integer (kind=omp_integer_kind), parameter :: kmp_version_build = @LIBOMP_VERSION_BUILD@ + ! Set PRIVATE by default to explicitly only export what is meant + ! to be exported by this MODULE. + private + + ! Re-export definitions in omp_lib_kinds + public :: omp_integer_kind + public :: omp_logical_kind + public :: omp_real_kind + public :: kmp_double_kind + public :: omp_lock_kind + public :: omp_nest_lock_kind + public :: omp_sched_kind + public :: omp_proc_bind_kind + public :: kmp_pointer_kind + public :: kmp_size_t_kind + public :: kmp_affinity_mask_kind + public :: kmp_cancel_kind + public :: omp_sync_hint_kind + public :: omp_lock_hint_kind + public :: omp_control_tool_kind + public :: omp_control_tool_result_kind + public :: omp_allocator_handle_kind + public :: omp_memspace_handle_kind + public :: omp_alloctrait_key_kind + public :: omp_alloctrait_val_kind + public :: omp_interop_kind + public :: omp_interop_fr_kind + public :: omp_alloctrait + public :: omp_pause_resource_kind + public :: omp_depend_kind + public :: omp_event_handle_kind + + integer (kind=omp_integer_kind), parameter, public :: openmp_version = @LIBOMP_OMP_YEAR_MONTH@ + integer (kind=omp_integer_kind), parameter, public :: kmp_version_major = @LIBOMP_VERSION_MAJOR@ + integer (kind=omp_integer_kind), parameter, public :: kmp_version_minor = @LIBOMP_VERSION_MINOR@ + integer (kind=omp_integer_kind), parameter, public :: kmp_version_build = @LIBOMP_VERSION_BUILD@ character(*) kmp_build_date parameter( kmp_build_date = '@LIBOMP_BUILD_DATE@' ) - integer(kind=omp_sched_kind), parameter :: omp_sched_static = 1 - integer(kind=omp_sched_kind), parameter :: omp_sched_dynamic = 2 - integer(kind=omp_sched_kind), parameter :: omp_sched_guided = 3 - integer(kind=omp_sched_kind), parameter :: omp_sched_auto = 4 - integer(kind=omp_sched_kind), parameter :: omp_sched_monotonic = int(Z'80000000', kind=omp_sched_kind) - - integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_false = 0 - integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_true = 1 - integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_master = 2 - integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_close = 3 - integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_spread = 4 - - integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_parallel = 1 - integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_loop = 2 - integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_sections = 3 - integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_taskgroup = 4 - - integer (kind=omp_sync_hint_kind), parameter :: omp_sync_hint_none = 0 - integer (kind=omp_sync_hint_kind), parameter :: omp_sync_hint_uncontended = 1 - integer (kind=omp_sync_hint_kind), parameter :: omp_sync_hint_contended = 2 - integer (kind=omp_sync_hint_kind), parameter :: omp_sync_hint_nonspeculative = 4 - integer (kind=omp_sync_hint_kind), parameter :: omp_sync_hint_speculative = 8 - integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_none = omp_sync_hint_none - integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_uncontended = omp_sync_hint_uncontended - integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_contended = omp_sync_hint_contended - integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_nonspeculative = omp_sync_hint_nonspeculative - integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_speculative = omp_sync_hint_speculative - integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 65536 - integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 131072 - integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 262144 - - integer (kind=omp_control_tool_kind), parameter :: omp_control_tool_start = 1 - integer (kind=omp_control_tool_kind), parameter :: omp_control_tool_pause = 2 - integer (kind=omp_control_tool_kind), parameter :: omp_control_tool_flush = 3 - integer (kind=omp_control_tool_kind), parameter :: omp_control_tool_end = 4 - - integer (kind=omp_control_tool_result_kind), parameter :: omp_control_tool_notool = -2 - integer (kind=omp_control_tool_result_kind), parameter :: omp_control_tool_nocallback = -1 - integer (kind=omp_control_tool_result_kind), parameter :: omp_control_tool_success = 0 - integer (kind=omp_control_tool_result_kind), parameter :: omp_control_tool_ignored = 1 - - integer (kind=omp_alloctrait_key_kind), parameter :: omp_atk_sync_hint = 1 - integer (kind=omp_alloctrait_key_kind), parameter :: omp_atk_alignment = 2 - integer (kind=omp_alloctrait_key_kind), parameter :: omp_atk_access = 3 - integer (kind=omp_alloctrait_key_kind), parameter :: omp_atk_pool_size = 4 - integer (kind=omp_alloctrait_key_kind), parameter :: omp_atk_fallback = 5 - integer (kind=omp_alloctrait_key_kind), parameter :: omp_atk_fb_data = 6 - integer (kind=omp_alloctrait_key_kind), parameter :: omp_atk_pinned = 7 - integer (kind=omp_alloctrait_key_kind), parameter :: omp_atk_partition = 8 - - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_default = -1 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_false = 0 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_true = 1 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_contended = 3 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_uncontended = 4 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_serialized = 5 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_sequential = omp_atv_serialized - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_private = 6 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_all = 7 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_thread = 8 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_pteam = 9 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_cgroup = 10 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_default_mem_fb = 11 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_null_fb = 12 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_abort_fb = 13 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_allocator_fb = 14 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_environment = 15 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_nearest = 16 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_blocked = 17 - integer (kind=omp_alloctrait_val_kind), parameter :: omp_atv_interleaved = 18 - - integer (kind=omp_allocator_handle_kind), parameter :: omp_null_allocator = 0 - integer (kind=omp_allocator_handle_kind), parameter :: omp_default_mem_alloc = 1 - integer (kind=omp_allocator_handle_kind), parameter :: omp_large_cap_mem_alloc = 2 - integer (kind=omp_allocator_handle_kind), parameter :: omp_const_mem_alloc = 3 - integer (kind=omp_allocator_handle_kind), parameter :: omp_high_bw_mem_alloc = 4 - integer (kind=omp_allocator_handle_kind), parameter :: omp_low_lat_mem_alloc = 5 - integer (kind=omp_allocator_handle_kind), parameter :: omp_cgroup_mem_alloc = 6 - integer (kind=omp_allocator_handle_kind), parameter :: omp_pteam_mem_alloc = 7 - integer (kind=omp_allocator_handle_kind), parameter :: omp_thread_mem_alloc = 8 - integer (kind=omp_allocator_handle_kind), parameter :: llvm_omp_target_host_mem_alloc = 100 - integer (kind=omp_allocator_handle_kind), parameter :: llvm_omp_target_shared_mem_alloc = 101 - integer (kind=omp_allocator_handle_kind), parameter :: llvm_omp_target_device_mem_alloc = 102 - - integer (kind=omp_memspace_handle_kind), parameter :: omp_default_mem_space = 0 - integer (kind=omp_memspace_handle_kind), parameter :: omp_large_cap_mem_space = 1 - integer (kind=omp_memspace_handle_kind), parameter :: omp_const_mem_space = 2 - integer (kind=omp_memspace_handle_kind), parameter :: omp_high_bw_mem_space = 3 - integer (kind=omp_memspace_handle_kind), parameter :: omp_low_lat_mem_space = 4 - integer (kind=omp_memspace_handle_kind), parameter :: llvm_omp_target_host_mem_space = 100 - integer (kind=omp_memspace_handle_kind), parameter :: llvm_omp_target_shared_mem_space = 101 - integer (kind=omp_memspace_handle_kind), parameter :: llvm_omp_target_device_mem_space = 102 - - integer (kind=omp_pause_resource_kind), parameter :: omp_pause_resume = 0 - integer (kind=omp_pause_resource_kind), parameter :: omp_pause_soft = 1 - integer (kind=omp_pause_resource_kind), parameter :: omp_pause_hard = 2 - - integer (kind=omp_interop_fr_kind), parameter :: omp_ifr_cuda = 1 - integer (kind=omp_interop_fr_kind), parameter :: omp_ifr_cuda_driver = 2 - integer (kind=omp_interop_fr_kind), parameter :: omp_ifr_opencl = 3 - integer (kind=omp_interop_fr_kind), parameter :: omp_ifr_sycl = 4 - integer (kind=omp_interop_fr_kind), parameter :: omp_ifr_hip = 5 - integer (kind=omp_interop_fr_kind), parameter :: omp_ifr_level_zero = 6 - integer (kind=omp_interop_fr_kind), parameter :: omp_ifr_last = 7 - - integer (kind=omp_interop_kind), parameter :: omp_interop_none = 0 + integer(kind=omp_sched_kind), parameter, public :: omp_sched_static = 1 + integer(kind=omp_sched_kind), parameter, public :: omp_sched_dynamic = 2 + integer(kind=omp_sched_kind), parameter, public :: omp_sched_guided = 3 + integer(kind=omp_sched_kind), parameter, public :: omp_sched_auto = 4 + integer(kind=omp_sched_kind), parameter, public :: omp_sched_monotonic = int(Z'80000000', kind=omp_sched_kind) + + integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_false = 0 + integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_true = 1 + integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_master = 2 + integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_close = 3 + integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_spread = 4 + + integer (kind=kmp_cancel_kind), parameter, public :: kmp_cancel_parallel = 1 + integer (kind=kmp_cancel_kind), parameter, public :: kmp_cancel_loop = 2 + integer (kind=kmp_cancel_kind), parameter, public :: kmp_cancel_sections = 3 + integer (kind=kmp_cancel_kind), parameter, public :: kmp_cancel_taskgroup = 4 + + integer (kind=omp_sync_hint_kind), parameter, public :: omp_sync_hint_none = 0 + integer (kind=omp_sync_hint_kind), parameter, public :: omp_sync_hint_uncontended = 1 + integer (kind=omp_sync_hint_kind), parameter, public :: omp_sync_hint_contended = 2 + integer (kind=omp_sync_hint_kind), parameter, public :: omp_sync_hint_nonspeculative = 4 + integer (kind=omp_sync_hint_kind), parameter, public :: omp_sync_hint_speculative = 8 + integer (kind=omp_lock_hint_kind), parameter, public :: omp_lock_hint_none = omp_sync_hint_none + integer (kind=omp_lock_hint_kind), parameter, public :: omp_lock_hint_uncontended = omp_sync_hint_uncontended + integer (kind=omp_lock_hint_kind), parameter, public :: omp_lock_hint_contended = omp_sync_hint_contended + integer (kind=omp_lock_hint_kind), parameter, public :: omp_lock_hint_nonspeculative = omp_sync_hint_nonspeculative + integer (kind=omp_lock_hint_kind), parameter, public :: omp_lock_hint_speculative = omp_sync_hint_speculative + integer (kind=omp_lock_hint_kind), parameter, public :: kmp_lock_hint_hle = 65536 + integer (kind=omp_lock_hint_kind), parameter, public :: kmp_lock_hint_rtm = 131072 + integer (kind=omp_lock_hint_kind), parameter, public :: kmp_lock_hint_adaptive = 262144 + + integer (kind=omp_control_tool_kind), parameter, public :: omp_control_tool_start = 1 + integer (kind=omp_control_tool_kind), parameter, public :: omp_control_tool_pause = 2 + integer (kind=omp_control_tool_kind), parameter, public :: omp_control_tool_flush = 3 + integer (kind=omp_control_tool_kind), parameter, public :: omp_control_tool_end = 4 + + integer (kind=omp_control_tool_result_kind), parameter, public :: omp_control_tool_notool = -2 + integer (kind=omp_control_tool_result_kind), parameter, public :: omp_control_tool_nocallback = -1 + integer (kind=omp_control_tool_result_kind), parameter, public :: omp_control_tool_success = 0 + integer (kind=omp_control_tool_result_kind), parameter, public :: omp_control_tool_ignored = 1 + + integer (kind=omp_alloctrait_key_kind), parameter, public :: omp_atk_sync_hint = 1 + integer (kind=omp_alloctrait_key_kind), parameter, public :: omp_atk_alignment = 2 + integer (kind=omp_alloctrait_key_kind), parameter, public :: omp_atk_access = 3 + integer (kind=omp_alloctrait_key_kind), parameter, public :: omp_atk_pool_size = 4 + integer (kind=omp_alloctrait_key_kind), parameter, public :: omp_atk_fallback = 5 + integer (kind=omp_alloctrait_key_kind), parameter, public :: omp_atk_fb_data = 6 + integer (kind=omp_alloctrait_key_kind), parameter, public :: omp_atk_pinned = 7 + integer (kind=omp_alloctrait_key_kind), parameter, public :: omp_atk_partition = 8 + + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_default = -1 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_false = 0 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_true = 1 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_contended = 3 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_uncontended = 4 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_serialized = 5 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_sequential = omp_atv_serialized + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_private = 6 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_all = 7 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_thread = 8 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_pteam = 9 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_cgroup = 10 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_default_mem_fb = 11 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_null_fb = 12 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_abort_fb = 13 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_allocator_fb = 14 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_environment = 15 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_nearest = 16 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_blocked = 17 + integer (kind=omp_alloctrait_val_kind), parameter, public :: omp_atv_interleaved = 18 + + integer (kind=omp_allocator_handle_kind), parameter, public :: omp_null_allocator = 0 + integer (kind=omp_allocator_handle_kind), parameter, public :: omp_default_mem_alloc = 1 + integer (kind=omp_allocator_handle_kind), parameter, public :: omp_large_cap_mem_alloc = 2 + integer (kind=omp_allocator_handle_kind), parameter, public :: omp_const_mem_alloc = 3 + integer (kind=omp_allocator_handle_kind), parameter, public :: omp_high_bw_mem_alloc = 4 + integer (kind=omp_allocator_handle_kind), parameter, public :: omp_low_lat_mem_alloc = 5 + integer (kind=omp_allocator_handle_kind), parameter, public :: omp_cgroup_mem_alloc = 6 + integer (kind=omp_allocator_handle_kind), parameter, public :: omp_pteam_mem_alloc = 7 + integer (kind=omp_allocator_handle_kind), parameter, public :: omp_thread_mem_alloc = 8 + integer (kind=omp_allocator_handle_kind), parameter, public :: llvm_omp_target_host_mem_alloc = 100 + integer (kind=omp_allocator_handle_kind), parameter, public :: llvm_omp_target_shared_mem_alloc = 101 + integer (kind=omp_allocator_handle_kind), parameter, public :: llvm_omp_target_device_mem_alloc = 102 + + integer (kind=omp_memspace_handle_kind), parameter, public :: omp_default_mem_space = 0 + integer (kind=omp_memspace_handle_kind), parameter, public :: omp_large_cap_mem_space = 1 + integer (kind=omp_memspace_handle_kind), parameter, public :: omp_const_mem_space = 2 + integer (kind=omp_memspace_handle_kind), parameter, public :: omp_high_bw_mem_space = 3 + integer (kind=omp_memspace_handle_kind), parameter, public :: omp_low_lat_mem_space = 4 + integer (kind=omp_memspace_handle_kind), parameter, public :: llvm_omp_target_host_mem_space = 100 + integer (kind=omp_memspace_handle_kind), parameter, public :: llvm_omp_target_shared_mem_space = 101 + integer (kind=omp_memspace_handle_kind), parameter, public :: llvm_omp_target_device_mem_space = 102 + + integer (kind=omp_pause_resource_kind), parameter, public :: omp_pause_resume = 0 + integer (kind=omp_pause_resource_kind), parameter, public :: omp_pause_soft = 1 + integer (kind=omp_pause_resource_kind), parameter, public :: omp_pause_hard = 2 + + integer (kind=omp_interop_fr_kind), parameter, public :: omp_ifr_cuda = 1 + integer (kind=omp_interop_fr_kind), parameter, public :: omp_ifr_cuda_driver = 2 + integer (kind=omp_interop_fr_kind), parameter, public :: omp_ifr_opencl = 3 + integer (kind=omp_interop_fr_kind), parameter, public :: omp_ifr_sycl = 4 + integer (kind=omp_interop_fr_kind), parameter, public :: omp_ifr_hip = 5 + integer (kind=omp_interop_fr_kind), parameter, public :: omp_ifr_level_zero = 6 + integer (kind=omp_interop_fr_kind), parameter, public :: omp_ifr_last = 7 + + integer (kind=omp_interop_kind), parameter, public :: omp_interop_none = 0 interface @@ -392,82 +429,102 @@ end subroutine omp_fulfill_event subroutine omp_init_lock(svar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_init_lock !DIR$ ENDIF +#endif use omp_lib_kinds integer (kind=omp_lock_kind) svar end subroutine omp_init_lock subroutine omp_destroy_lock(svar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_destroy_lock !DIR$ ENDIF +#endif use omp_lib_kinds integer (kind=omp_lock_kind) svar end subroutine omp_destroy_lock subroutine omp_set_lock(svar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_set_lock !DIR$ ENDIF +#endif use omp_lib_kinds integer (kind=omp_lock_kind) svar end subroutine omp_set_lock subroutine omp_unset_lock(svar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_unset_lock !DIR$ ENDIF +#endif use omp_lib_kinds integer (kind=omp_lock_kind) svar end subroutine omp_unset_lock function omp_test_lock(svar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_test_lock !DIR$ ENDIF +#endif use omp_lib_kinds logical (kind=omp_logical_kind) omp_test_lock integer (kind=omp_lock_kind) svar end function omp_test_lock subroutine omp_init_nest_lock(nvar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_init_nest_lock !DIR$ ENDIF +#endif use omp_lib_kinds integer (kind=omp_nest_lock_kind) nvar end subroutine omp_init_nest_lock subroutine omp_destroy_nest_lock(nvar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_destroy_nest_lock !DIR$ ENDIF +#endif use omp_lib_kinds integer (kind=omp_nest_lock_kind) nvar end subroutine omp_destroy_nest_lock subroutine omp_set_nest_lock(nvar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_set_nest_lock !DIR$ ENDIF +#endif use omp_lib_kinds integer (kind=omp_nest_lock_kind) nvar end subroutine omp_set_nest_lock subroutine omp_unset_nest_lock(nvar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_unset_nest_lock !DIR$ ENDIF +#endif use omp_lib_kinds integer (kind=omp_nest_lock_kind) nvar end subroutine omp_unset_nest_lock function omp_test_nest_lock(nvar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_test_nest_lock !DIR$ ENDIF +#endif use omp_lib_kinds integer (kind=omp_integer_kind) omp_test_nest_lock integer (kind=omp_nest_lock_kind) nvar @@ -568,20 +625,20 @@ end subroutine omp_display_env function omp_target_alloc(size, device_num) bind(c) - use omp_lib_kinds + use, intrinsic :: iso_c_binding, only: c_ptr, c_size_t, c_int type(c_ptr) omp_target_alloc integer(c_size_t), value :: size integer(c_int), value :: device_num end function omp_target_alloc subroutine omp_target_free(device_ptr, device_num) bind(c) - use omp_lib_kinds + use, intrinsic :: iso_c_binding, only: c_ptr, c_int type(c_ptr), value :: device_ptr integer(c_int), value :: device_num end subroutine omp_target_free function omp_target_is_present(ptr, device_num) bind(c) - use omp_lib_kinds + use, intrinsic :: iso_c_binding, only: c_ptr, c_int integer(c_int) omp_target_is_present type(c_ptr), value :: ptr integer(c_int), value :: device_num @@ -589,7 +646,7 @@ function omp_target_memcpy(dst, src, length, dst_offset, src_offset, & dst_device_num, src_device_num) bind(c) - use omp_lib_kinds + use, intrinsic :: iso_c_binding, only: c_ptr, c_size_t, c_int integer(c_int) omp_target_memcpy type(c_ptr), value :: dst, src integer(c_size_t), value :: length, dst_offset, src_offset @@ -599,7 +656,7 @@ function omp_target_memcpy_rect(dst, src, element_size, num_dims, & volume, dst_offsets, src_offsets, dst_dimensions, & src_dimensions, dst_device_num, src_device_num) bind(c) - use omp_lib_kinds + use, intrinsic :: iso_c_binding, only: c_ptr, c_size_t, c_int integer(c_int) omp_target_memcpy_rect type(c_ptr), value :: dst, src integer(c_size_t), value :: element_size @@ -612,6 +669,7 @@ src_offset, dst_device_num, src_device_num, depobj_count, & depobj_list) bind(c) use omp_lib_kinds + use, intrinsic :: iso_c_binding, only: c_ptr, c_size_t, c_int integer(c_int) omp_target_memcpy_async type(c_ptr), value :: dst, src integer(c_size_t), value :: length, dst_offset, src_offset @@ -625,6 +683,7 @@ src_dimensions, dst_device_num, src_device_num, depobj_count, & depobj_list) bind(c) use omp_lib_kinds + use, intrinsic :: iso_c_binding, only: c_ptr, c_size_t, c_int integer(c_int) omp_target_memcpy_rect_async type(c_ptr), value :: dst, src integer(c_size_t), value :: element_size @@ -646,8 +705,8 @@ function omp_target_memset_async(ptr, val, count, device_num, & depobj_count, depobj_list) bind(c) - use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_size_t use omp_lib_kinds + use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_size_t type(c_ptr) :: omp_target_memset_async type(c_ptr), value :: ptr integer(c_int), value :: val @@ -659,7 +718,7 @@ function omp_target_associate_ptr(host_ptr, device_ptr, size, & device_offset, device_num) bind(c) - use omp_lib_kinds + use, intrinsic :: iso_c_binding, only: c_ptr, c_size_t, c_int integer(c_int) omp_target_associate_ptr type(c_ptr), value :: host_ptr, device_ptr integer(c_size_t), value :: size, device_offset @@ -667,21 +726,20 @@ end function omp_target_associate_ptr function omp_get_mapped_ptr(ptr, device_num) bind(c) - use omp_lib_kinds + use, intrinsic :: iso_c_binding, only: c_ptr, c_int type(c_ptr) omp_get_mapped_ptr type(c_ptr), value :: ptr integer(c_int), value :: device_num end function omp_get_mapped_ptr function omp_target_disassociate_ptr(ptr, device_num) bind(c) - use omp_lib_kinds + use, intrinsic :: iso_c_binding, only: c_ptr, c_int integer(c_int) omp_target_disassociate_ptr type(c_ptr), value :: ptr integer(c_int), value :: device_num end function omp_target_disassociate_ptr function omp_target_is_accessible(ptr, size, device_num) bind(c) - use omp_lib_kinds use, intrinsic :: iso_c_binding, only : c_ptr, c_size_t, c_int integer(c_int) omp_target_is_accessible type(c_ptr), value :: ptr @@ -900,4 +958,124 @@ end interface + ! make the above routine definitions public + public :: omp_set_num_threads + public :: omp_set_dynamic + public :: omp_set_nested + public :: omp_get_num_threads + public :: omp_get_max_threads + public :: omp_get_thread_num + public :: omp_get_num_procs + public :: omp_in_parallel + public :: omp_in_final + public :: omp_get_dynamic + public :: omp_get_nested + public :: omp_get_thread_limit + public :: omp_set_max_active_levels + public :: omp_get_max_active_levels + public :: omp_get_level + public :: omp_get_active_level + public :: omp_get_ancestor_thread_num + public :: omp_get_team_size + public :: omp_set_schedule + public :: omp_get_schedule + public :: omp_get_proc_bind + public :: omp_get_num_places + public :: omp_get_place_num_procs + public :: omp_get_place_proc_ids + public :: omp_get_place_num + public :: omp_get_partition_num_places + public :: omp_get_partition_place_nums + public :: omp_get_wtime + public :: omp_get_wtick + public :: omp_get_default_device + public :: omp_set_default_device + public :: omp_get_num_devices + public :: omp_get_num_teams + public :: omp_get_team_num + public :: omp_get_cancellation + public :: omp_is_initial_device + public :: omp_get_initial_device + public :: omp_get_device_num + public :: omp_pause_resource + public :: omp_pause_resource_all + public :: omp_get_supported_active_levels + public :: omp_fulfill_event + public :: omp_init_lock + public :: omp_destroy_lock + public :: omp_set_lock + public :: omp_unset_lock + public :: omp_test_lock + public :: omp_init_nest_lock + public :: omp_destroy_nest_lock + public :: omp_set_nest_lock + public :: omp_unset_nest_lock + public :: omp_test_nest_lock + public :: omp_get_max_task_priority + public :: omp_init_lock_with_hint + public :: omp_init_nest_lock_with_hint + public :: omp_control_tool + public :: omp_init_allocator + public :: omp_destroy_allocator + public :: omp_set_default_allocator + public :: omp_get_default_allocator + public :: omp_set_affinity_format + public :: omp_get_affinity_format + public :: omp_display_affinity + public :: omp_capture_affinity + public :: omp_set_num_teams + public :: omp_get_max_teams + public :: omp_set_teams_thread_limit + public :: omp_get_teams_thread_limit + public :: omp_display_env + public :: omp_target_alloc + public :: omp_target_free + public :: omp_target_is_present + public :: omp_target_memcpy + public :: omp_target_memcpy_rect + public :: omp_target_memcpy_async + public :: omp_target_memcpy_rect_async + public :: omp_target_memset + public :: omp_target_memset_async + public :: omp_target_associate_ptr + public :: omp_get_mapped_ptr + public :: omp_target_disassociate_ptr + public :: omp_target_is_accessible + public :: omp_alloc + public :: omp_aligned_alloc + public :: omp_calloc + public :: omp_aligned_calloc + public :: omp_realloc + public :: omp_free + public :: omp_in_explicit_task + public :: kmp_set_stacksize + public :: kmp_set_stacksize_s + public :: kmp_set_blocktime + public :: kmp_set_library_serial + public :: kmp_set_library_turnaround + public :: kmp_set_library_throughput + public :: kmp_set_library + public :: kmp_set_defaults + public :: kmp_get_stacksize + public :: kmp_get_stacksize_s + public :: kmp_get_blocktime + public :: kmp_get_library + public :: kmp_set_disp_num_buffers + public :: kmp_set_affinity + public :: kmp_get_affinity + public :: kmp_get_affinity_max_proc + public :: kmp_create_affinity_mask + public :: kmp_destroy_affinity_mask + public :: kmp_set_affinity_mask_proc + public :: kmp_unset_affinity_mask_proc + public :: kmp_get_affinity_mask_proc + public :: kmp_malloc + public :: kmp_aligned_malloc + public :: kmp_calloc + public :: kmp_realloc + public :: kmp_free + public :: kmp_set_warnings_on + public :: kmp_set_warnings_off + public :: kmp_get_cancellation_status + end module omp_lib diff --git a/openmp/runtime/src/include/omp_lib.h.var b/openmp/runtime/src/include/omp_lib.h.var index 617f2321676d..a709a2f298f8 100644 --- a/openmp/runtime/src/include/omp_lib.h.var +++ b/openmp/runtime/src/include/omp_lib.h.var @@ -486,82 +486,102 @@ end subroutine omp_fulfill_event subroutine omp_init_lock(svar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_init_lock !DIR$ ENDIF +#endif import integer (kind=omp_lock_kind) svar end subroutine omp_init_lock subroutine omp_destroy_lock(svar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_destroy_lock !DIR$ ENDIF +#endif import integer (kind=omp_lock_kind) svar end subroutine omp_destroy_lock subroutine omp_set_lock(svar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_set_lock !DIR$ ENDIF +#endif import integer (kind=omp_lock_kind) svar end subroutine omp_set_lock subroutine omp_unset_lock(svar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_unset_lock !DIR$ ENDIF +#endif import integer (kind=omp_lock_kind) svar end subroutine omp_unset_lock function omp_test_lock(svar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_test_lock !DIR$ ENDIF +#endif import logical (kind=omp_logical_kind) omp_test_lock integer (kind=omp_lock_kind) svar end function omp_test_lock subroutine omp_init_nest_lock(nvar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_init_nest_lock !DIR$ ENDIF +#endif import integer (kind=omp_nest_lock_kind) nvar end subroutine omp_init_nest_lock subroutine omp_destroy_nest_lock(nvar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_destroy_nest_lock !DIR$ ENDIF +#endif import integer (kind=omp_nest_lock_kind) nvar end subroutine omp_destroy_nest_lock subroutine omp_set_nest_lock(nvar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_set_nest_lock !DIR$ ENDIF +#endif import integer (kind=omp_nest_lock_kind) nvar end subroutine omp_set_nest_lock subroutine omp_unset_nest_lock(nvar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_unset_nest_lock !DIR$ ENDIF +#endif import integer (kind=omp_nest_lock_kind) nvar end subroutine omp_unset_nest_lock function omp_test_nest_lock(nvar) bind(c) +#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_test_nest_lock !DIR$ ENDIF +#endif import integer (kind=omp_integer_kind) omp_test_nest_lock integer (kind=omp_nest_lock_kind) nvar @@ -990,6 +1010,7 @@ end subroutine kmp_set_warnings_off end interface +#ifdef __INTEL_COMPILER !DIR$ IF DEFINED (__INTEL_OFFLOAD) !DIR$ IF(__INTEL_COMPILER.LT.1900) @@ -1158,3 +1179,4 @@ !$omp declare target(omp_init_nest_lock_with_hint ) !DIR$ ENDIF !DIR$ ENDIF +#endif -- GitLab From 81d9ed605b126d163f2f1cc226c639f1dfdc5224 Mon Sep 17 00:00:00 2001 From: Alexey Bataev <a.bataev@outlook.com> Date: Thu, 14 Mar 2024 16:16:18 -0400 Subject: [PATCH 236/307] [SLP]Do extra analysis int minbitwidth if some checks return false. The instruction itself can be considered good for minbitwidth casting, even if one of the operand checks returns false. Reviewers: RKSimon Reviewed By: RKSimon Pull Request: https://github.com/llvm/llvm-project/pull/84363 --- .../Transforms/Vectorize/SLPVectorizer.cpp | 108 ++++++++++-------- .../SLPVectorizer/AArch64/horizontal.ll | 20 ++-- .../X86/minbitwidth-node-but-not-operands.ll | 61 ++++++++++ 3 files changed, 133 insertions(+), 56 deletions(-) create mode 100644 llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-node-but-not-operands.ll diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index e3711fe63efe..b0cb3cd47dd7 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -12225,7 +12225,8 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { return E->VectorizedValue; } if (True->getType() != VecTy || False->getType() != VecTy) { - assert((getOperandEntry(E, 1)->State == TreeEntry::NeedToGather || + assert((It != MinBWs.end() || + getOperandEntry(E, 1)->State == TreeEntry::NeedToGather || getOperandEntry(E, 2)->State == TreeEntry::NeedToGather || MinBWs.contains(getOperandEntry(E, 1)) || MinBWs.contains(getOperandEntry(E, 2))) && @@ -12297,7 +12298,8 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { return E->VectorizedValue; } if (LHS->getType() != VecTy || RHS->getType() != VecTy) { - assert((getOperandEntry(E, 0)->State == TreeEntry::NeedToGather || + assert((It != MinBWs.end() || + getOperandEntry(E, 0)->State == TreeEntry::NeedToGather || getOperandEntry(E, 1)->State == TreeEntry::NeedToGather || MinBWs.contains(getOperandEntry(E, 0)) || MinBWs.contains(getOperandEntry(E, 1))) && @@ -12543,7 +12545,8 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { ((Instruction::isBinaryOp(E->getOpcode()) && (LHS->getType() != VecTy || RHS->getType() != VecTy)) || (isa<CmpInst>(VL0) && LHS->getType() != RHS->getType()))) { - assert((getOperandEntry(E, 0)->State == TreeEntry::NeedToGather || + assert((It != MinBWs.end() || + getOperandEntry(E, 0)->State == TreeEntry::NeedToGather || getOperandEntry(E, 1)->State == TreeEntry::NeedToGather || MinBWs.contains(getOperandEntry(E, 0)) || MinBWs.contains(getOperandEntry(E, 1))) && @@ -12559,9 +12562,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) { else CastTy = LHS->getType(); } - if (LHS->getType() != VecTy) + if (LHS->getType() != CastTy) LHS = Builder.CreateIntCast(LHS, CastTy, GetOperandSignedness(0)); - if (RHS->getType() != VecTy) + if (RHS->getType() != CastTy) RHS = Builder.CreateIntCast(RHS, CastTy, GetOperandSignedness(1)); } @@ -13988,15 +13991,6 @@ bool BoUpSLP::collectValuesToDemote( // If the value is not a vectorized instruction in the expression and not used // by the insertelement instruction and not used in multiple vector nodes, it // cannot be demoted. - // TODO: improve handling of gathered values and others. - auto *I = dyn_cast<Instruction>(V); - const TreeEntry *ITE = I ? getTreeEntry(I) : nullptr; - if (!ITE || !Visited.insert(I).second || MultiNodeScalars.contains(I) || - all_of(I->users(), [&](User *U) { - return isa<InsertElementInst>(U) && !getTreeEntry(U); - })) - return false; - auto IsPotentiallyTruncated = [&](Value *V, unsigned &BitWidth) -> bool { if (MultiNodeScalars.contains(V)) return false; @@ -14011,8 +14005,44 @@ bool BoUpSLP::collectValuesToDemote( BitWidth = std::max(BitWidth, BitWidth1); return BitWidth > 0 && OrigBitWidth >= (BitWidth * 2); }; + auto FinalAnalysis = [&](const TreeEntry *ITE = nullptr) { + if (!IsProfitableToDemote) + return false; + return (ITE && ITE->UserTreeIndices.size() > 1) || + IsPotentiallyTruncated(V, BitWidth); + }; + // TODO: improve handling of gathered values and others. + auto *I = dyn_cast<Instruction>(V); + const TreeEntry *ITE = I ? getTreeEntry(I) : nullptr; + if (!ITE || !Visited.insert(I).second || MultiNodeScalars.contains(I) || + all_of(I->users(), [&](User *U) { + return isa<InsertElementInst>(U) && !getTreeEntry(U); + })) + return FinalAnalysis(); + unsigned Start = 0; unsigned End = I->getNumOperands(); + + auto ProcessOperands = [&](ArrayRef<Value *> Operands, bool &NeedToExit) { + NeedToExit = false; + unsigned InitLevel = MaxDepthLevel; + for (Value *IncValue : Operands) { + unsigned Level = InitLevel; + if (!collectValuesToDemote(IncValue, IsProfitableToDemoteRoot, BitWidth, + ToDemote, DemotedConsts, Visited, Level, + IsProfitableToDemote, IsTruncRoot)) { + if (!IsProfitableToDemote) + return false; + NeedToExit = true; + if (!FinalAnalysis(ITE)) + return false; + continue; + } + MaxDepthLevel = std::max(MaxDepthLevel, Level); + } + return true; + }; + bool NeedToExit = false; switch (I->getOpcode()) { // We can always demote truncations and extensions. Since truncations can @@ -14038,35 +14068,21 @@ bool BoUpSLP::collectValuesToDemote( case Instruction::And: case Instruction::Or: case Instruction::Xor: { - unsigned Level1 = MaxDepthLevel, Level2 = MaxDepthLevel; - if ((ITE->UserTreeIndices.size() > 1 && - !IsPotentiallyTruncated(I, BitWidth)) || - !collectValuesToDemote(I->getOperand(0), IsProfitableToDemoteRoot, - BitWidth, ToDemote, DemotedConsts, Visited, - Level1, IsProfitableToDemote, IsTruncRoot) || - !collectValuesToDemote(I->getOperand(1), IsProfitableToDemoteRoot, - BitWidth, ToDemote, DemotedConsts, Visited, - Level2, IsProfitableToDemote, IsTruncRoot)) + if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) + return false; + if (!ProcessOperands({I->getOperand(0), I->getOperand(1)}, NeedToExit)) return false; - MaxDepthLevel = std::max(Level1, Level2); break; } // We can demote selects if we can demote their true and false values. case Instruction::Select: { + if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) + return false; Start = 1; - unsigned Level1 = MaxDepthLevel, Level2 = MaxDepthLevel; - SelectInst *SI = cast<SelectInst>(I); - if ((ITE->UserTreeIndices.size() > 1 && - !IsPotentiallyTruncated(I, BitWidth)) || - !collectValuesToDemote(SI->getTrueValue(), IsProfitableToDemoteRoot, - BitWidth, ToDemote, DemotedConsts, Visited, - Level1, IsProfitableToDemote, IsTruncRoot) || - !collectValuesToDemote(SI->getFalseValue(), IsProfitableToDemoteRoot, - BitWidth, ToDemote, DemotedConsts, Visited, - Level2, IsProfitableToDemote, IsTruncRoot)) + auto *SI = cast<SelectInst>(I); + if (!ProcessOperands({SI->getTrueValue(), SI->getFalseValue()}, NeedToExit)) return false; - MaxDepthLevel = std::max(Level1, Level2); break; } @@ -14076,23 +14092,20 @@ bool BoUpSLP::collectValuesToDemote( PHINode *PN = cast<PHINode>(I); if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) return false; - unsigned InitLevel = MaxDepthLevel; - for (Value *IncValue : PN->incoming_values()) { - unsigned Level = InitLevel; - if (!collectValuesToDemote(IncValue, IsProfitableToDemoteRoot, BitWidth, - ToDemote, DemotedConsts, Visited, Level, - IsProfitableToDemote, IsTruncRoot)) - return false; - MaxDepthLevel = std::max(MaxDepthLevel, Level); - } + SmallVector<Value *> Ops(PN->incoming_values().begin(), + PN->incoming_values().end()); + if (!ProcessOperands(Ops, NeedToExit)) + return false; break; } // Otherwise, conservatively give up. default: MaxDepthLevel = 1; - return IsProfitableToDemote && IsPotentiallyTruncated(I, BitWidth); + return FinalAnalysis(); } + if (NeedToExit) + return true; ++MaxDepthLevel; // Gather demoted constant operands. @@ -14131,6 +14144,7 @@ void BoUpSLP::computeMinimumValueSizes() { // The first value node for store/insertelement is sext/zext/trunc? Skip it, // resize to the final type. + bool IsTruncRoot = false; bool IsProfitableToDemoteRoot = !IsStoreOrInsertElt; if (NodeIdx != 0 && VectorizableTree[NodeIdx]->State == TreeEntry::Vectorize && @@ -14138,8 +14152,9 @@ void BoUpSLP::computeMinimumValueSizes() { VectorizableTree[NodeIdx]->getOpcode() == Instruction::SExt || VectorizableTree[NodeIdx]->getOpcode() == Instruction::Trunc)) { assert(IsStoreOrInsertElt && "Expected store/insertelement seeded graph."); - ++NodeIdx; + IsTruncRoot = VectorizableTree[NodeIdx]->getOpcode() == Instruction::Trunc; IsProfitableToDemoteRoot = true; + ++NodeIdx; } // Analyzed in reduction already and not profitable - exit. @@ -14271,7 +14286,6 @@ void BoUpSLP::computeMinimumValueSizes() { ReductionBitWidth = bit_ceil(ReductionBitWidth); } bool IsTopRoot = NodeIdx == 0; - bool IsTruncRoot = false; while (NodeIdx < VectorizableTree.size() && VectorizableTree[NodeIdx]->State == TreeEntry::Vectorize && VectorizableTree[NodeIdx]->getOpcode() == Instruction::Trunc) { diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll index 1986b51ec948..7c5f9847db1f 100644 --- a/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll +++ b/llvm/test/Transforms/SLPVectorizer/AArch64/horizontal.ll @@ -228,7 +228,7 @@ for.end: ; preds = %for.end.loopexit, % ; YAML-NEXT: Function: test_unrolled_select ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'Vectorized horizontal reduction with cost ' -; YAML-NEXT: - Cost: '-36' +; YAML-NEXT: - Cost: '-41' ; YAML-NEXT: - String: ' and with tree size ' ; YAML-NEXT: - TreeSize: '10' @@ -246,15 +246,17 @@ define i32 @test_unrolled_select(ptr noalias nocapture readonly %blk1, ptr noali ; CHECK-NEXT: [[P2_045:%.*]] = phi ptr [ [[BLK2:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR88:%.*]], [[IF_END_86]] ] ; CHECK-NEXT: [[P1_044:%.*]] = phi ptr [ [[BLK1:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR:%.*]], [[IF_END_86]] ] ; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[P1_044]], align 1 -; CHECK-NEXT: [[TMP1:%.*]] = zext <8 x i8> [[TMP0]] to <8 x i32> +; CHECK-NEXT: [[TMP1:%.*]] = zext <8 x i8> [[TMP0]] to <8 x i16> ; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i8>, ptr [[P2_045]], align 1 -; CHECK-NEXT: [[TMP3:%.*]] = zext <8 x i8> [[TMP2]] to <8 x i32> -; CHECK-NEXT: [[TMP4:%.*]] = sub nsw <8 x i32> [[TMP1]], [[TMP3]] -; CHECK-NEXT: [[TMP5:%.*]] = icmp slt <8 x i32> [[TMP4]], zeroinitializer -; CHECK-NEXT: [[TMP6:%.*]] = sub nsw <8 x i32> zeroinitializer, [[TMP4]] -; CHECK-NEXT: [[TMP7:%.*]] = select <8 x i1> [[TMP5]], <8 x i32> [[TMP6]], <8 x i32> [[TMP4]] -; CHECK-NEXT: [[TMP8:%.*]] = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[TMP7]]) -; CHECK-NEXT: [[OP_RDX]] = add i32 [[TMP8]], [[S_047]] +; CHECK-NEXT: [[TMP3:%.*]] = zext <8 x i8> [[TMP2]] to <8 x i16> +; CHECK-NEXT: [[TMP4:%.*]] = sub <8 x i16> [[TMP1]], [[TMP3]] +; CHECK-NEXT: [[TMP5:%.*]] = sext <8 x i16> [[TMP4]] to <8 x i32> +; CHECK-NEXT: [[TMP6:%.*]] = icmp slt <8 x i32> [[TMP5]], zeroinitializer +; CHECK-NEXT: [[TMP7:%.*]] = sub <8 x i16> zeroinitializer, [[TMP4]] +; CHECK-NEXT: [[TMP8:%.*]] = select <8 x i1> [[TMP6]], <8 x i16> [[TMP7]], <8 x i16> [[TMP4]] +; CHECK-NEXT: [[TMP9:%.*]] = sext <8 x i16> [[TMP8]] to <8 x i32> +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> [[TMP9]]) +; CHECK-NEXT: [[OP_RDX]] = add i32 [[TMP10]], [[S_047]] ; CHECK-NEXT: [[CMP83:%.*]] = icmp slt i32 [[OP_RDX]], [[LIM:%.*]] ; CHECK-NEXT: br i1 [[CMP83]], label [[IF_END_86]], label [[FOR_END_LOOPEXIT:%.*]] ; CHECK: if.end.86: diff --git a/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-node-but-not-operands.ll b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-node-but-not-operands.ll new file mode 100644 index 000000000000..fcccaf202a91 --- /dev/null +++ b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-node-but-not-operands.ll @@ -0,0 +1,61 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 +; RUN: opt --passes=slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s + +define void @test() { +; CHECK-LABEL: define void @test() { +; CHECK-NEXT: entry: +; CHECK-NEXT: store <8 x i16> zeroinitializer, ptr null, align 2 +; CHECK-NEXT: ret void +; +entry: + %arrayidx8 = getelementptr i8, ptr null, i64 2 + %shr10 = ashr i32 0, 0 + %shr19 = lshr i32 0, 0 + %sub20 = or i32 %shr19, %shr10 + %xor21 = xor i32 %sub20, 0 + %conv22 = trunc i32 %xor21 to i16 + store i16 %conv22, ptr %arrayidx8, align 2 + %arrayidx28 = getelementptr i8, ptr null, i64 4 + %shr34 = lshr i32 0, 0 + %sub35 = or i32 %shr34, %shr10 + %xor36 = xor i32 %sub35, 0 + %conv37 = trunc i32 %xor36 to i16 + store i16 %conv37, ptr %arrayidx28, align 2 + %arrayidx43 = getelementptr i8, ptr null, i64 6 + %shr49 = lshr i32 0, 0 + %sub50 = or i32 %shr49, %shr10 + %xor51 = xor i32 %sub50, 0 + %conv52 = trunc i32 %xor51 to i16 + store i16 %conv52, ptr %arrayidx43, align 2 + %arrayidx.1 = getelementptr i8, ptr null, i64 8 + %shr.1 = lshr i32 0, 0 + %xor2.1 = xor i32 %shr.1, %shr10 + %sub3.1 = or i32 %xor2.1, 0 + %conv4.1 = trunc i32 %sub3.1 to i16 + store i16 %conv4.1, ptr %arrayidx.1, align 2 + %arrayidx8.1 = getelementptr i8, ptr null, i64 10 + %shr10.1 = ashr i32 0, 0 + %shr19.1 = lshr i32 0, 0 + %sub20.1 = or i32 %shr19.1, %shr10.1 + %xor21.1 = xor i32 %sub20.1, 0 + %conv22.1 = trunc i32 %xor21.1 to i16 + store i16 %conv22.1, ptr %arrayidx8.1, align 2 + %arrayidx28.1 = getelementptr i8, ptr null, i64 12 + %shr34.1 = lshr i32 0, 0 + %sub35.1 = or i32 %shr34.1, %shr10.1 + %xor36.1 = xor i32 %sub35.1, 0 + %conv37.1 = trunc i32 %xor36.1 to i16 + store i16 %conv37.1, ptr %arrayidx28.1, align 2 + %arrayidx43.1 = getelementptr i8, ptr null, i64 14 + %shr49.1 = lshr i32 0, 0 + %sub50.1 = or i32 %shr49.1, %shr10.1 + %xor51.1 = xor i32 %sub50.1, 0 + %conv52.1 = trunc i32 %xor51.1 to i16 + store i16 %conv52.1, ptr %arrayidx43.1, align 2 + %shr.2 = lshr i32 0, 0 + %xor2.2 = xor i32 %shr.2, %shr10.1 + %sub3.2 = or i32 %xor2.2, 0 + %conv4.2 = trunc i32 %sub3.2 to i16 + store i16 %conv4.2, ptr null, align 2 + ret void +} -- GitLab From 6c1d4454ad00414cf20f9a69e04856de99f6bf1d Mon Sep 17 00:00:00 2001 From: Alexey Bataev <a.bataev@outlook.com> Date: Wed, 20 Mar 2024 09:07:26 -0400 Subject: [PATCH 237/307] [SLP]Improve minbitwidth analysis for shifts. Adds improved bitwidth analysis for shl/ashr/lshr instructions. The analysis is based on similar version in InstCombiner. Reviewers: RKSimon Reviewed By: RKSimon Pull Request: https://github.com/llvm/llvm-project/pull/84356 --- .../Transforms/Vectorize/SLPVectorizer.cpp | 97 ++++++++++++++++++- .../X86/reorder-possible-strided-node.ll | 6 +- .../X86/reorder_diamond_match.ll | 25 ++--- 3 files changed, 109 insertions(+), 19 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index b0cb3cd47dd7..5d59f35f3081 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -13995,9 +13995,11 @@ bool BoUpSLP::collectValuesToDemote( if (MultiNodeScalars.contains(V)) return false; uint32_t OrigBitWidth = DL->getTypeSizeInBits(V->getType()); - APInt Mask = APInt::getBitsSetFrom(OrigBitWidth, BitWidth); - if (MaskedValueIsZero(V, Mask, SimplifyQuery(*DL))) - return true; + if (OrigBitWidth < BitWidth) { + APInt Mask = APInt::getBitsSetFrom(OrigBitWidth, BitWidth); + if (MaskedValueIsZero(V, Mask, SimplifyQuery(*DL))) + return true; + } auto NumSignBits = ComputeNumSignBits(V, *DL, 0, AC, nullptr, DT); unsigned BitWidth1 = OrigBitWidth - NumSignBits; if (!isKnownNonNegative(V, SimplifyQuery(*DL))) @@ -14042,6 +14044,30 @@ bool BoUpSLP::collectValuesToDemote( } return true; }; + auto AttemptCheckBitwidth = + [&](function_ref<bool(unsigned, unsigned)> Checker, bool &NeedToExit) { + // Try all bitwidth < OrigBitWidth. + NeedToExit = false; + uint32_t OrigBitWidth = DL->getTypeSizeInBits(I->getType()); + unsigned BestFailBitwidth = 0; + for (; BitWidth < OrigBitWidth; BitWidth *= 2) { + if (Checker(BitWidth, OrigBitWidth)) + return true; + if (BestFailBitwidth == 0 && FinalAnalysis()) + BestFailBitwidth = BitWidth; + } + if (BitWidth >= OrigBitWidth) { + if (BestFailBitwidth == 0) { + BitWidth = OrigBitWidth; + return false; + } + MaxDepthLevel = 1; + BitWidth = BestFailBitwidth; + NeedToExit = true; + return true; + } + return false; + }; bool NeedToExit = false; switch (I->getOpcode()) { @@ -14074,6 +14100,71 @@ bool BoUpSLP::collectValuesToDemote( return false; break; } + case Instruction::Shl: { + // Several vectorized uses? Check if we can truncate it, otherwise - exit. + if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) + return false; + // If we are truncating the result of this SHL, and if it's a shift of an + // inrange amount, we can always perform a SHL in a smaller type. + if (!AttemptCheckBitwidth( + [&](unsigned BitWidth, unsigned) { + KnownBits AmtKnownBits = computeKnownBits(I->getOperand(1), *DL); + return AmtKnownBits.getMaxValue().ult(BitWidth); + }, + NeedToExit)) + return false; + if (NeedToExit) + return true; + if (!ProcessOperands({I->getOperand(0), I->getOperand(1)}, NeedToExit)) + return false; + break; + } + case Instruction::LShr: { + // Several vectorized uses? Check if we can truncate it, otherwise - exit. + if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) + return false; + // If this is a truncate of a logical shr, we can truncate it to a smaller + // lshr iff we know that the bits we would otherwise be shifting in are + // already zeros. + if (!AttemptCheckBitwidth( + [&](unsigned BitWidth, unsigned OrigBitWidth) { + KnownBits AmtKnownBits = computeKnownBits(I->getOperand(1), *DL); + APInt ShiftedBits = APInt::getBitsSetFrom(OrigBitWidth, BitWidth); + return AmtKnownBits.getMaxValue().ult(BitWidth) && + MaskedValueIsZero(I->getOperand(0), ShiftedBits, + SimplifyQuery(*DL)); + }, + NeedToExit)) + return false; + if (NeedToExit) + return true; + if (!ProcessOperands({I->getOperand(0), I->getOperand(1)}, NeedToExit)) + return false; + break; + } + case Instruction::AShr: { + // Several vectorized uses? Check if we can truncate it, otherwise - exit. + if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) + return false; + // If this is a truncate of an arithmetic shr, we can truncate it to a + // smaller ashr iff we know that all the bits from the sign bit of the + // original type and the sign bit of the truncate type are similar. + if (!AttemptCheckBitwidth( + [&](unsigned BitWidth, unsigned OrigBitWidth) { + KnownBits AmtKnownBits = computeKnownBits(I->getOperand(1), *DL); + unsigned ShiftedBits = OrigBitWidth - BitWidth; + return AmtKnownBits.getMaxValue().ult(BitWidth) && + ShiftedBits < ComputeNumSignBits(I->getOperand(0), *DL, 0, + AC, nullptr, DT); + }, + NeedToExit)) + return false; + if (NeedToExit) + return true; + if (!ProcessOperands({I->getOperand(0), I->getOperand(1)}, NeedToExit)) + return false; + break; + } // We can demote selects if we can demote their true and false values. case Instruction::Select: { diff --git a/llvm/test/Transforms/SLPVectorizer/X86/reorder-possible-strided-node.ll b/llvm/test/Transforms/SLPVectorizer/X86/reorder-possible-strided-node.ll index f6db831ed97b..4a23abf182e8 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/reorder-possible-strided-node.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/reorder-possible-strided-node.ll @@ -10,10 +10,8 @@ define void @test() { ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[ARRAYIDX22]], align 4 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0> ; CHECK-NEXT: [[TMP3:%.*]] = mul <4 x i32> [[TMP2]], [[TMP0]] -; CHECK-NEXT: [[TMP4:%.*]] = sext <4 x i32> [[TMP3]] to <4 x i64> -; CHECK-NEXT: [[TMP5:%.*]] = ashr <4 x i64> [[TMP4]], zeroinitializer -; CHECK-NEXT: [[TMP6:%.*]] = trunc <4 x i64> [[TMP5]] to <4 x i32> -; CHECK-NEXT: store <4 x i32> [[TMP6]], ptr getelementptr inbounds ([4 x i32], ptr null, i64 8, i64 0), align 16 +; CHECK-NEXT: [[TMP4:%.*]] = ashr <4 x i32> [[TMP3]], zeroinitializer +; CHECK-NEXT: store <4 x i32> [[TMP4]], ptr getelementptr inbounds ([4 x i32], ptr null, i64 8, i64 0), align 16 ; CHECK-NEXT: ret void ; entry: diff --git a/llvm/test/Transforms/SLPVectorizer/X86/reorder_diamond_match.ll b/llvm/test/Transforms/SLPVectorizer/X86/reorder_diamond_match.ll index 86b1e1a801e3..dce85b4b2a19 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/reorder_diamond_match.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/reorder_diamond_match.ll @@ -5,18 +5,19 @@ define void @test() { ; CHECK-LABEL: @test( ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr undef, i64 4 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [4 x [4 x i32]], ptr undef, i64 0, i64 1, i64 0 -; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i8>, ptr [[TMP1]], align 1 -; CHECK-NEXT: [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32> -; CHECK-NEXT: [[TMP6:%.*]] = sub nsw <4 x i32> zeroinitializer, [[TMP5]] -; CHECK-NEXT: [[TMP7:%.*]] = shl nsw <4 x i32> [[TMP6]], zeroinitializer -; CHECK-NEXT: [[TMP8:%.*]] = add nsw <4 x i32> [[TMP7]], zeroinitializer -; CHECK-NEXT: [[TMP9:%.*]] = shufflevector <4 x i32> [[TMP8]], <4 x i32> poison, <4 x i32> <i32 1, i32 0, i32 3, i32 2> -; CHECK-NEXT: [[TMP10:%.*]] = add nsw <4 x i32> [[TMP8]], [[TMP9]] -; CHECK-NEXT: [[TMP11:%.*]] = sub nsw <4 x i32> [[TMP8]], [[TMP9]] -; CHECK-NEXT: [[TMP12:%.*]] = shufflevector <4 x i32> [[TMP10]], <4 x i32> [[TMP11]], <4 x i32> <i32 1, i32 4, i32 3, i32 6> -; CHECK-NEXT: [[TMP13:%.*]] = add nsw <4 x i32> zeroinitializer, [[TMP12]] -; CHECK-NEXT: [[TMP14:%.*]] = sub nsw <4 x i32> zeroinitializer, [[TMP12]] -; CHECK-NEXT: [[TMP15:%.*]] = shufflevector <4 x i32> [[TMP13]], <4 x i32> [[TMP14]], <4 x i32> <i32 0, i32 1, i32 6, i32 7> +; CHECK-NEXT: [[TMP3:%.*]] = load <4 x i8>, ptr [[TMP1]], align 1 +; CHECK-NEXT: [[TMP4:%.*]] = zext <4 x i8> [[TMP3]] to <4 x i16> +; CHECK-NEXT: [[TMP5:%.*]] = sub <4 x i16> zeroinitializer, [[TMP4]] +; CHECK-NEXT: [[TMP6:%.*]] = shl <4 x i16> [[TMP5]], zeroinitializer +; CHECK-NEXT: [[TMP7:%.*]] = add <4 x i16> [[TMP6]], zeroinitializer +; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <4 x i16> [[TMP7]], <4 x i16> poison, <4 x i32> <i32 1, i32 0, i32 3, i32 2> +; CHECK-NEXT: [[TMP9:%.*]] = add nsw <4 x i16> [[TMP7]], [[TMP8]] +; CHECK-NEXT: [[TMP10:%.*]] = sub nsw <4 x i16> [[TMP7]], [[TMP8]] +; CHECK-NEXT: [[TMP11:%.*]] = shufflevector <4 x i16> [[TMP9]], <4 x i16> [[TMP10]], <4 x i32> <i32 1, i32 4, i32 3, i32 6> +; CHECK-NEXT: [[TMP12:%.*]] = add nsw <4 x i16> zeroinitializer, [[TMP11]] +; CHECK-NEXT: [[TMP13:%.*]] = sub nsw <4 x i16> zeroinitializer, [[TMP11]] +; CHECK-NEXT: [[TMP14:%.*]] = shufflevector <4 x i16> [[TMP12]], <4 x i16> [[TMP13]], <4 x i32> <i32 0, i32 1, i32 6, i32 7> +; CHECK-NEXT: [[TMP15:%.*]] = sext <4 x i16> [[TMP14]] to <4 x i32> ; CHECK-NEXT: store <4 x i32> [[TMP15]], ptr [[TMP2]], align 16 ; CHECK-NEXT: ret void ; -- GitLab From bdc77d1ecc9219dfc641aaaa4fb088233e9a32d1 Mon Sep 17 00:00:00 2001 From: Stephen Tozer <stephen.tozer@sony.com> Date: Wed, 20 Mar 2024 13:11:28 +0000 Subject: [PATCH 238/307] [RemoveDIs][NFC] Rename DPLabel->DbgLabelRecord (#85918) This patch renames DPLabel to DbgLabelRecord, in accordance with the ongoing DbgRecord rename. This rename was fairly trivial, since DPLabel isn't as widely used as DPValue and has no real conflicts in either its full or abbreviated name. As usual, the entire replacement was done automatically, with `s/DPLabel/DbgLabelRecord/` and `s/DPL/DLR/`. --- llvm/docs/RemoveDIsDebugInfo.md | 6 ++-- .../include/llvm/IR/DebugProgramInstruction.h | 22 +++++++------ llvm/lib/AsmParser/LLParser.cpp | 2 +- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 5 +-- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 6 ++-- llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 6 ++-- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 10 +++--- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 10 +++--- .../SelectionDAG/SelectionDAGBuilder.cpp | 15 ++++----- llvm/lib/IR/AsmWriter.cpp | 20 ++++++------ llvm/lib/IR/AutoUpgrade.cpp | 2 +- llvm/lib/IR/BasicBlock.cpp | 3 +- llvm/lib/IR/DIBuilder.cpp | 8 ++--- llvm/lib/IR/DebugProgramInstruction.cpp | 31 ++++++++++--------- llvm/lib/IR/Verifier.cpp | 24 +++++++------- .../Scalar/SpeculativeExecution.cpp | 2 +- llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 2 +- llvm/lib/Transforms/Utils/CodeExtractor.cpp | 4 +-- llvm/lib/Transforms/Utils/ValueMapper.cpp | 4 +-- llvm/unittests/IR/IRBuilderTest.cpp | 4 +-- 20 files changed, 97 insertions(+), 89 deletions(-) diff --git a/llvm/docs/RemoveDIsDebugInfo.md b/llvm/docs/RemoveDIsDebugInfo.md index 2cb17e2b5e44..f8405767a579 100644 --- a/llvm/docs/RemoveDIsDebugInfo.md +++ b/llvm/docs/RemoveDIsDebugInfo.md @@ -65,9 +65,9 @@ We're using a dedicated C++ class called `DbgRecord` to store debug info, with a https://llvm.org/docs/doxygen/classllvm_1_1DbgRecord.html https://llvm.org/docs/doxygen/classllvm_1_1DbgVariableRecord.html - https://llvm.org/docs/doxygen/classllvm_1_1DPLabel.html + https://llvm.org/docs/doxygen/classllvm_1_1DbgLabelRecord.html -This allows you to treat a `DbgVariableRecord` as if it's a `dbg.value`/`dbg.declare`/`dbg.assign` intrinsic most of the time, for example in generic (auto-param) lambdas, and the same for `DPLabel` and `dbg.label`s. +This allows you to treat a `DbgVariableRecord` as if it's a `dbg.value`/`dbg.declare`/`dbg.assign` intrinsic most of the time, for example in generic (auto-param) lambdas, and the same for `DbgLabelRecord` and `dbg.label`s. ## How do these `DbgRecords` fit into the instruction stream? @@ -97,7 +97,7 @@ Each instruction has a pointer to a `DPMarker` (which will become optional), tha Not shown are the links from DbgRecord to other parts of the `Value`/`Metadata` hierachy: `DbgRecord` subclasses have tracking pointers to the DIMetadata that they use, and `DbgVariableRecord` has references to `Value`s that are stored in a `DebugValueUser` base class. This refers to a `ValueAsMetadata` object referring to `Value`s, via the `TrackingMetadata` facility. -The various kinds of debug intrinsic (value, declare, assign, label) are all stored in `DbgRecord` subclasses, with a "RecordKind" field distinguishing `DPLabel`s from `DbgVariableRecord`s, and a `LocationType` field in the `DbgVariableRecord` class further disambiguating the various debug variable intrinsics it can represent. +The various kinds of debug intrinsic (value, declare, assign, label) are all stored in `DbgRecord` subclasses, with a "RecordKind" field distinguishing `DbgLabelRecord`s from `DbgVariableRecord`s, and a `LocationType` field in the `DbgVariableRecord` class further disambiguating the various debug variable intrinsics it can represent. ## Finding debug info records diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h index db41e9acc7be..8bd6331a9a3e 100644 --- a/llvm/include/llvm/IR/DebugProgramInstruction.h +++ b/llvm/include/llvm/IR/DebugProgramInstruction.h @@ -222,23 +222,25 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DbgRecord &R) { /// llvm.dbg.label intrinsic. /// FIXME: Rename DbgLabelRecord when DbgVariableRecord is renamed to /// DbgVariableRecord. -class DPLabel : public DbgRecord { +class DbgLabelRecord : public DbgRecord { DbgRecordParamRef<DILabel> Label; /// This constructor intentionally left private, so that it is only called via - /// "createUnresolvedDPLabel", which clearly expresses that it is for parsing - /// only. - DPLabel(MDNode *Label, MDNode *DL); + /// "createUnresolvedDbgLabelRecord", which clearly expresses that it is for + /// parsing only. + DbgLabelRecord(MDNode *Label, MDNode *DL); public: - DPLabel(DILabel *Label, DebugLoc DL); + DbgLabelRecord(DILabel *Label, DebugLoc DL); - /// For use during parsing; creates a DPLabel from as-of-yet unresolved - /// MDNodes. Trying to access the resulting DPLabel's fields before they are - /// resolved, or if they resolve to the wrong type, will result in a crash. - static DPLabel *createUnresolvedDPLabel(MDNode *Label, MDNode *DL); + /// For use during parsing; creates a DbgLabelRecord from as-of-yet unresolved + /// MDNodes. Trying to access the resulting DbgLabelRecord's fields before + /// they are resolved, or if they resolve to the wrong type, will result in a + /// crash. + static DbgLabelRecord *createUnresolvedDbgLabelRecord(MDNode *Label, + MDNode *DL); - DPLabel *clone() const; + DbgLabelRecord *clone() const; void print(raw_ostream &O, bool IsForDebug = false) const; void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const; DbgLabelInst *createDebugIntrinsic(Module *M, diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 8738cb47dd9c..f0be021668af 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -6607,7 +6607,7 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) { return true; if (parseToken(lltok::rparen, "Expected ')' here")) return true; - DR = DPLabel::createUnresolvedDPLabel(Label, DbgLoc); + DR = DbgLabelRecord::createUnresolvedDbgLabelRecord(Label, DbgLoc); return false; } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index fa7038acc524..3fc8141381c6 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -6426,14 +6426,15 @@ Error BitcodeReader::parseFunctionBody(Function *F) { break; } case bitc::FUNC_CODE_DEBUG_RECORD_LABEL: { - // DPLabels are placed after the Instructions that they are attached to. + // DbgLabelRecords are placed after the Instructions that they are + // attached to. Instruction *Inst = getLastInstruction(); if (!Inst) return error("Invalid dbg record: missing instruction"); DILocation *DIL = cast<DILocation>(getFnMetadataByID(Record[0])); DILabel *Label = cast<DILabel>(getFnMetadataByID(Record[1])); Inst->getParent()->insertDbgRecordBefore( - new DPLabel(Label, DebugLoc(DIL)), Inst->getIterator()); + new DbgLabelRecord(Label, DebugLoc(DIL)), Inst->getIterator()); continue; // This isn't an instruction. } case bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index a1ee02918dfa..5addf0ac33c4 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -3570,9 +3570,9 @@ void ModuleBitcodeWriter::writeFunction( // instruction. Write it after the instruction so that it's easy to // re-attach to the instruction reading the records in. for (DbgRecord &DR : I.DbgMarker->getDbgRecordRange()) { - if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) { - Vals.push_back(VE.getMetadataID(&*DPL->getDebugLoc())); - Vals.push_back(VE.getMetadataID(DPL->getLabel())); + if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) { + Vals.push_back(VE.getMetadataID(&*DLR->getDebugLoc())); + Vals.push_back(VE.getMetadataID(DLR->getLabel())); Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_RECORD_LABEL, Vals); Vals.clear(); continue; diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 3209dca253fe..e6787e245a49 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -441,9 +441,9 @@ ValueEnumerator::ValueEnumerator(const Module &M, }; for (DbgRecord &DR : I.getDbgRecordRange()) { - if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) { - EnumerateMetadata(&F, DPL->getLabel()); - EnumerateMetadata(&F, &*DPL->getDebugLoc()); + if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) { + EnumerateMetadata(&F, DLR->getLabel()); + EnumerateMetadata(&F, &*DLR->getDebugLoc()); continue; } // Enumerate non-local location metadata. diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index c18574071bfb..757af3b1c4fe 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -3376,13 +3376,13 @@ void IRTranslator::translateDbgDeclareRecord(Value *Address, bool HasArgList, void IRTranslator::translateDbgInfo(const Instruction &Inst, MachineIRBuilder &MIRBuilder) { for (DbgRecord &DR : Inst.getDbgRecordRange()) { - if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) { - MIRBuilder.setDebugLoc(DPL->getDebugLoc()); - assert(DPL->getLabel() && "Missing label"); - assert(DPL->getLabel()->isValidLocationForIntrinsic( + if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) { + MIRBuilder.setDebugLoc(DLR->getDebugLoc()); + assert(DLR->getLabel() && "Missing label"); + assert(DLR->getLabel()->isValidLocationForIntrinsic( MIRBuilder.getDebugLoc()) && "Expected inlined-at fields to agree"); - MIRBuilder.buildDbgLabel(DPL->getLabel()); + MIRBuilder.buildDbgLabel(DLR->getLabel()); continue; } DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR); diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 8b834862fb4d..27b8472ddb73 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1192,16 +1192,16 @@ void FastISel::handleDbgInfo(const Instruction *II) { flushLocalValueMap(); recomputeInsertPt(); - if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) { - assert(DPL->getLabel() && "Missing label"); + if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) { + assert(DLR->getLabel() && "Missing label"); if (!FuncInfo.MF->getMMI().hasDebugInfo()) { - LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DPL << "\n"); + LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DLR << "\n"); continue; } - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DPL->getDebugLoc(), + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DLR->getDebugLoc(), TII.get(TargetOpcode::DBG_LABEL)) - .addMetadata(DPL->getLabel()); + .addMetadata(DLR->getLabel()); continue; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index dd19ee16d1d6..2d63774c75e3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1248,18 +1248,19 @@ void SelectionDAGBuilder::visitDbgInfo(const Instruction &I) { // We must skip DbgVariableRecords if they've already been processed above as // we have just emitted the debug values resulting from assignment tracking // analysis, making any existing DbgVariableRecords redundant (and probably - // less correct). We still need to process DPLabels. This does sink DPLabels - // to the bottom of the group of debug records. That sholdn't be important - // as it does so deterministcally and ordering between DPLabels and - // DbgVariableRecords is immaterial (other than for MIR/IR printing). + // less correct). We still need to process DbgLabelRecords. This does sink + // DbgLabelRecords to the bottom of the group of debug records. That sholdn't + // be important as it does so deterministcally and ordering between + // DbgLabelRecords and DbgVariableRecords is immaterial (other than for MIR/IR + // printing). bool SkipDbgVariableRecords = DAG.getFunctionVarLocs(); // Is there is any debug-info attached to this instruction, in the form of // DbgRecord non-instruction debug-info records. for (DbgRecord &DR : I.getDbgRecordRange()) { - if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) { - assert(DPL->getLabel() && "Missing label"); + if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) { + assert(DLR->getLabel() && "Missing label"); SDDbgLabel *SDV = - DAG.getDbgLabel(DPL->getLabel(), DPL->getDebugLoc(), SDNodeOrder); + DAG.getDbgLabel(DLR->getLabel(), DLR->getDebugLoc(), SDNodeOrder); DAG.AddDbgLabel(SDV); continue; } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 5caed518e265..8ce6fabb30f2 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1152,8 +1152,8 @@ void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) { if (auto *Empty = dyn_cast<MDNode>(DVR->getRawAddress())) CreateMetadataSlot(Empty); } - } else if (const DPLabel *DPL = dyn_cast<const DPLabel>(&DR)) { - CreateMetadataSlot(DPL->getRawLabel()); + } else if (const DbgLabelRecord *DLR = dyn_cast<const DbgLabelRecord>(&DR)) { + CreateMetadataSlot(DLR->getRawLabel()); } else { llvm_unreachable("unsupported DbgRecord kind"); } @@ -2719,7 +2719,7 @@ public: void printInstruction(const Instruction &I); void printDPMarker(const DPMarker &DPI); void printDbgVariableRecord(const DbgVariableRecord &DVR); - void printDPLabel(const DPLabel &DPL); + void printDbgLabelRecord(const DbgLabelRecord &DLR); void printDbgRecord(const DbgRecord &DR); void printDbgRecordLine(const DbgRecord &DR); @@ -4621,8 +4621,8 @@ void AssemblyWriter::printDPMarker(const DPMarker &Marker) { void AssemblyWriter::printDbgRecord(const DbgRecord &DR) { if (auto *DVR = dyn_cast<DbgVariableRecord>(&DR)) printDbgVariableRecord(*DVR); - else if (auto *DPL = dyn_cast<DPLabel>(&DR)) - printDPLabel(*DPL); + else if (auto *DLR = dyn_cast<DbgLabelRecord>(&DR)) + printDbgLabelRecord(*DLR); else llvm_unreachable("Unexpected DbgRecord kind"); } @@ -4672,7 +4672,7 @@ void AssemblyWriter::printDbgRecordLine(const DbgRecord &DR) { Out << '\n'; } -void AssemblyWriter::printDPLabel(const DPLabel &Label) { +void AssemblyWriter::printDbgLabelRecord(const DbgLabelRecord &Label) { auto WriterCtx = getContext(); Out << "#dbg_label("; WriteAsOperandInternal(Out, Label.getRawLabel(), WriterCtx, true); @@ -4934,7 +4934,7 @@ void DPMarker::print(raw_ostream &ROS, ModuleSlotTracker &MST, W.printDPMarker(*this); } -void DPLabel::print(raw_ostream &ROS, bool IsForDebug) const { +void DbgLabelRecord::print(raw_ostream &ROS, bool IsForDebug) const { ModuleSlotTracker MST(getModuleFromDPI(this), true); print(ROS, MST, IsForDebug); @@ -4957,8 +4957,8 @@ void DbgVariableRecord::print(raw_ostream &ROS, ModuleSlotTracker &MST, W.printDbgVariableRecord(*this); } -void DPLabel::print(raw_ostream &ROS, ModuleSlotTracker &MST, - bool IsForDebug) const { +void DbgLabelRecord::print(raw_ostream &ROS, ModuleSlotTracker &MST, + bool IsForDebug) const { formatted_raw_ostream OS(ROS); SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr)); SlotTracker &SlotTable = @@ -4970,7 +4970,7 @@ void DPLabel::print(raw_ostream &ROS, ModuleSlotTracker &MST, incorporateFunction(Marker->getParent() ? Marker->getParent()->getParent() : nullptr); AssemblyWriter W(OS, SlotTable, getModuleFromDPI(this), nullptr, IsForDebug); - W.printDPLabel(*this); + W.printDbgLabelRecord(*this); } void Value::print(raw_ostream &ROS, bool IsForDebug) const { diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 7d954f9d09ad..a44f6af4162f 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -2358,7 +2358,7 @@ static MDType *unwrapMAVOp(CallBase *CI, unsigned Op) { static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) { DbgRecord *DR = nullptr; if (Name == "label") { - DR = new DPLabel(unwrapMAVOp<DILabel>(CI, 0), CI->getDebugLoc()); + DR = new DbgLabelRecord(unwrapMAVOp<DILabel>(CI, 0), CI->getDebugLoc()); } else if (Name == "assign") { DR = new DbgVariableRecord( unwrapMAVOp<Metadata>(CI, 0), unwrapMAVOp<DILocalVariable>(CI, 1), diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp index 2dff6e4d6d9c..2fa9b3330d18 100644 --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -83,7 +83,8 @@ void BasicBlock::convertToNewDbgValues() { } if (DbgLabelInst *DLI = dyn_cast<DbgLabelInst>(&I)) { - DbgVarRecs.push_back(new DPLabel(DLI->getLabel(), DLI->getDebugLoc())); + DbgVarRecs.push_back( + new DbgLabelRecord(DLI->getLabel(), DLI->getDebugLoc())); DLI->eraseFromParent(); continue; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index f10b5acb980d..f86e557b8def 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -1155,12 +1155,12 @@ DbgInstPtr DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL, trackIfUnresolved(LabelInfo); if (M.IsNewDbgInfoFormat) { - DPLabel *DPL = new DPLabel(LabelInfo, DL); + DbgLabelRecord *DLR = new DbgLabelRecord(LabelInfo, DL); if (InsertBB && InsertBefore) - InsertBB->insertDbgRecordBefore(DPL, InsertBefore->getIterator()); + InsertBB->insertDbgRecordBefore(DLR, InsertBefore->getIterator()); else if (InsertBB) - InsertBB->insertDbgRecordBefore(DPL, InsertBB->end()); - return DPL; + InsertBB->insertDbgRecordBefore(DLR, InsertBB->end()); + return DLR; } if (!LabelFn) diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp index 1fb435f46a5f..1c0be6f598cc 100644 --- a/llvm/lib/IR/DebugProgramInstruction.cpp +++ b/llvm/lib/IR/DebugProgramInstruction.cpp @@ -82,7 +82,7 @@ void DbgRecord::deleteRecord() { delete cast<DbgVariableRecord>(this); return; case LabelKind: - delete cast<DPLabel>(this); + delete cast<DbgLabelRecord>(this); return; } llvm_unreachable("unsupported DbgRecord kind"); @@ -94,7 +94,7 @@ void DbgRecord::print(raw_ostream &O, bool IsForDebug) const { cast<DbgVariableRecord>(this)->print(O, IsForDebug); return; case LabelKind: - cast<DPLabel>(this)->print(O, IsForDebug); + cast<DbgLabelRecord>(this)->print(O, IsForDebug); return; }; llvm_unreachable("unsupported DbgRecord kind"); @@ -107,7 +107,7 @@ void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST, cast<DbgVariableRecord>(this)->print(O, MST, IsForDebug); return; case LabelKind: - cast<DPLabel>(this)->print(O, MST, IsForDebug); + cast<DbgLabelRecord>(this)->print(O, MST, IsForDebug); return; }; llvm_unreachable("unsupported DbgRecord kind"); @@ -121,7 +121,8 @@ bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const { return cast<DbgVariableRecord>(this)->isIdenticalToWhenDefined( *cast<DbgVariableRecord>(&R)); case LabelKind: - return cast<DPLabel>(this)->getLabel() == cast<DPLabel>(R).getLabel(); + return cast<DbgLabelRecord>(this)->getLabel() == + cast<DbgLabelRecord>(R).getLabel(); }; llvm_unreachable("unsupported DbgRecord kind"); } @@ -136,24 +137,25 @@ DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const { case ValueKind: return cast<DbgVariableRecord>(this)->createDebugIntrinsic(M, InsertBefore); case LabelKind: - return cast<DPLabel>(this)->createDebugIntrinsic(M, InsertBefore); + return cast<DbgLabelRecord>(this)->createDebugIntrinsic(M, InsertBefore); }; llvm_unreachable("unsupported DbgRecord kind"); } -DPLabel::DPLabel(MDNode *Label, MDNode *DL) +DbgLabelRecord::DbgLabelRecord(MDNode *Label, MDNode *DL) : DbgRecord(LabelKind, DebugLoc(DL)), Label(Label) { assert(Label && "Unexpected nullptr"); assert((isa<DILabel>(Label) || Label->isTemporary()) && "Label type must be or resolve to a DILabel"); } -DPLabel::DPLabel(DILabel *Label, DebugLoc DL) +DbgLabelRecord::DbgLabelRecord(DILabel *Label, DebugLoc DL) : DbgRecord(LabelKind, DL), Label(Label) { assert(Label && "Unexpected nullptr"); } -DPLabel *DPLabel::createUnresolvedDPLabel(MDNode *Label, MDNode *DL) { - return new DPLabel(Label, DL); +DbgLabelRecord *DbgLabelRecord::createUnresolvedDbgLabelRecord(MDNode *Label, + MDNode *DL) { + return new DbgLabelRecord(Label, DL); } DbgVariableRecord::DbgVariableRecord(DbgVariableRecord::LocationType Type, @@ -380,7 +382,7 @@ DbgRecord *DbgRecord::clone() const { case ValueKind: return cast<DbgVariableRecord>(this)->clone(); case LabelKind: - return cast<DPLabel>(this)->clone(); + return cast<DbgLabelRecord>(this)->clone(); }; llvm_unreachable("unsupported DbgRecord kind"); } @@ -389,8 +391,8 @@ DbgVariableRecord *DbgVariableRecord::clone() const { return new DbgVariableRecord(*this); } -DPLabel *DPLabel::clone() const { - return new DPLabel(getLabel(), getDebugLoc()); +DbgLabelRecord *DbgLabelRecord::clone() const { + return new DbgLabelRecord(getLabel(), getDebugLoc()); } DbgVariableIntrinsic * @@ -450,8 +452,9 @@ DbgVariableRecord::createDebugIntrinsic(Module *M, return DVI; } -DbgLabelInst *DPLabel::createDebugIntrinsic(Module *M, - Instruction *InsertBefore) const { +DbgLabelInst * +DbgLabelRecord::createDebugIntrinsic(Module *M, + Instruction *InsertBefore) const { auto *LabelFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_label); Value *Args[] = { MetadataAsValue::get(getDebugLoc()->getContext(), getLabel())}; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 1e16e8648462..a99b307a3536 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -544,7 +544,7 @@ private: void visitTemplateParams(const MDNode &N, const Metadata &RawParams); - void visit(DPLabel &DPL); + void visit(DbgLabelRecord &DLR); void visit(DbgVariableRecord &DVR); // InstVisitor overrides... using InstVisitor<Verifier>::visit; @@ -696,8 +696,8 @@ void Verifier::visitDbgRecords(Instruction &I) { // intrinsic behaviour. verifyFragmentExpression(*DVR); verifyNotEntryValue(*DVR); - } else if (auto *DPL = dyn_cast<DPLabel>(&DR)) { - visit(*DPL); + } else if (auto *DLR = dyn_cast<DbgLabelRecord>(&DR)) { + visit(*DLR); } } } @@ -6244,22 +6244,22 @@ static DISubprogram *getSubprogram(Metadata *LocalScope) { return nullptr; } -void Verifier::visit(DPLabel &DPL) { - CheckDI(isa<DILabel>(DPL.getRawLabel()), - "invalid #dbg_label intrinsic variable", &DPL, DPL.getRawLabel()); +void Verifier::visit(DbgLabelRecord &DLR) { + CheckDI(isa<DILabel>(DLR.getRawLabel()), + "invalid #dbg_label intrinsic variable", &DLR, DLR.getRawLabel()); // Ignore broken !dbg attachments; they're checked elsewhere. - if (MDNode *N = DPL.getDebugLoc().getAsMDNode()) + if (MDNode *N = DLR.getDebugLoc().getAsMDNode()) if (!isa<DILocation>(N)) return; - BasicBlock *BB = DPL.getParent(); + BasicBlock *BB = DLR.getParent(); Function *F = BB ? BB->getParent() : nullptr; // The scopes for variables and !dbg attachments must agree. - DILabel *Label = DPL.getLabel(); - DILocation *Loc = DPL.getDebugLoc(); - CheckDI(Loc, "#dbg_label record requires a !dbg attachment", &DPL, BB, F); + DILabel *Label = DLR.getLabel(); + DILocation *Loc = DLR.getDebugLoc(); + CheckDI(Loc, "#dbg_label record requires a !dbg attachment", &DLR, BB, F); DISubprogram *LabelSP = getSubprogram(Label->getRawScope()); DISubprogram *LocSP = getSubprogram(Loc->getRawScope()); @@ -6268,7 +6268,7 @@ void Verifier::visit(DPLabel &DPL) { CheckDI(LabelSP == LocSP, "mismatched subprogram between #dbg_label label and !dbg attachment", - &DPL, BB, F, Label, Label->getScope()->getSubprogram(), Loc, + &DLR, BB, F, Label, Label->getScope()->getSubprogram(), Loc, Loc->getScope()->getSubprogram()); } diff --git a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp index 400b56894174..5efc340da60b 100644 --- a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp +++ b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp @@ -292,7 +292,7 @@ bool SpeculativeExecutionPass::considerHoistingFromTo( InstructionCost TotalSpeculationCost = 0; unsigned NotHoistedInstCount = 0; for (const auto &I : FromBlock) { - // Make note of any DbgVariableRecords that need hoisting. DPLabels + // Make note of any DbgVariableRecords that need hoisting. DbgLabelRecords // get left behind just like llvm.dbg.labels. for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { if (HasNoUnhoistedInstr(DVR.location_ops())) diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index bf1de05a647d..915cd81661f0 100644 --- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -388,7 +388,7 @@ DbgVariableRecordsRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { SmallDenseSet<DebugVariable> VariableSet; for (auto &I : reverse(*BB)) { for (DbgRecord &DR : reverse(I.getDbgRecordRange())) { - if (isa<DPLabel>(DR)) { + if (isa<DbgLabelRecord>(DR)) { // Emulate existing behaviour (see comment below for dbg.declares). // FIXME: Don't do this. VariableSet.clear(); diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index 122b7a9747b6..3191751d92e1 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -1619,8 +1619,8 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc, auto UpdateDbgRecordsOnInst = [&](Instruction &I) -> void { for (DbgRecord &DR : I.getDbgRecordRange()) { - if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) { - UpdateDbgLabel(DPL); + if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) { + UpdateDbgLabel(DLR); continue; } diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 8c24599c8ce3..6ebdd85d37b4 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -538,8 +538,8 @@ Value *Mapper::mapValue(const Value *V) { } void Mapper::remapDbgRecord(DbgRecord &DR) { - if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) { - DPL->setLabel(cast<DILabel>(mapMetadata(DPL->getLabel()))); + if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) { + DLR->setLabel(cast<DILabel>(mapMetadata(DLR->getLabel()))); return; } diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp index ec3059821230..2001df090aed 100644 --- a/llvm/unittests/IR/IRBuilderTest.cpp +++ b/llvm/unittests/IR/IRBuilderTest.cpp @@ -922,7 +922,7 @@ TEST_F(IRBuilderTest, DIBuilder) { DILabel *Label = DIB.createLabel(BarScope, "badger", File, 1, /*AlwaysPreserve*/ false); - { /* dbg.label | DPLabel */ + { /* dbg.label | DbgLabelRecord */ // Insert before I and check order. ExpectOrder(DIB.insertLabel(Label, LabelLoc, I), I->getIterator()); @@ -931,7 +931,7 @@ TEST_F(IRBuilderTest, DIBuilder) { // inserted into the block untill another instruction is added. DbgInstPtr LabelRecord = DIB.insertLabel(Label, LabelLoc, BB); // Specifically do not insert a terminator, to check this works. `I` - // should have absorbed the DPLabel in the new debug info mode. + // should have absorbed the DbgLabelRecord in the new debug info mode. I = Builder.CreateAlloca(Builder.getInt32Ty()); ExpectOrder(LabelRecord, I->getIterator()); } -- GitLab From 2ac85d8d200a9e1e0ced501c2d2f04404c400bd9 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <llvm-dev@redking.me.uk> Date: Wed, 20 Mar 2024 11:56:02 +0000 Subject: [PATCH 239/307] [VectorCombine] foldBitcastShuf - add support for binary shuffles Generalise fold to "bitcast (shuf V0, V1, MaskC) --> shuf (bitcast V0), (bitcast V1), MaskC'". Further prep work for #67803 --- .../Transforms/Vectorize/VectorCombine.cpp | 21 ++++++----- .../Transforms/PhaseOrdering/X86/pr67803.ll | 35 +++++++++++++++++-- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp index 0b16a8b76769..23494314f132 100644 --- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp +++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp @@ -684,10 +684,10 @@ bool VectorCombine::foldInsExtFNeg(Instruction &I) { /// destination type followed by shuffle. This can enable further transforms by /// moving bitcasts or shuffles together. bool VectorCombine::foldBitcastShuffle(Instruction &I) { - Value *V0; + Value *V0, *V1; ArrayRef<int> Mask; if (!match(&I, m_BitCast(m_OneUse( - m_Shuffle(m_Value(V0), m_Undef(), m_Mask(Mask)))))) + m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(Mask)))))) return false; // 1) Do not fold bitcast shuffle for scalable type. First, shuffle cost for @@ -728,17 +728,21 @@ bool VectorCombine::foldBitcastShuffle(Instruction &I) { FixedVectorType::get(DestTy->getScalarType(), NumSrcElts); auto *OldShuffleTy = FixedVectorType::get(SrcTy->getScalarType(), Mask.size()); + bool IsUnary = isa<UndefValue>(V1); + unsigned NumOps = IsUnary ? 1 : 2; // The new shuffle must not cost more than the old shuffle. TargetTransformInfo::TargetCostKind CK = TargetTransformInfo::TCK_RecipThroughput; TargetTransformInfo::ShuffleKind SK = - TargetTransformInfo::SK_PermuteSingleSrc; + IsUnary ? TargetTransformInfo::SK_PermuteSingleSrc + : TargetTransformInfo::SK_PermuteTwoSrc; InstructionCost DestCost = TTI.getShuffleCost(SK, NewShuffleTy, NewMask, CK) + - TTI.getCastInstrCost(Instruction::BitCast, NewShuffleTy, SrcTy, - TargetTransformInfo::CastContextHint::None, CK); + (NumOps * TTI.getCastInstrCost(Instruction::BitCast, NewShuffleTy, SrcTy, + TargetTransformInfo::CastContextHint::None, + CK)); InstructionCost SrcCost = TTI.getShuffleCost(SK, SrcTy, Mask, CK) + TTI.getCastInstrCost(Instruction::BitCast, DestTy, OldShuffleTy, @@ -746,10 +750,11 @@ bool VectorCombine::foldBitcastShuffle(Instruction &I) { if (DestCost > SrcCost || !DestCost.isValid()) return false; - // bitcast (shuf V0, MaskC) --> shuf (bitcast V0), MaskC' + // bitcast (shuf V0, V1, MaskC) --> shuf (bitcast V0), (bitcast V1), MaskC' ++NumShufOfBitcast; - Value *CastV = Builder.CreateBitCast(V0, NewShuffleTy); - Value *Shuf = Builder.CreateShuffleVector(CastV, NewMask); + Value *CastV0 = Builder.CreateBitCast(V0, NewShuffleTy); + Value *CastV1 = Builder.CreateBitCast(V1, NewShuffleTy); + Value *Shuf = Builder.CreateShuffleVector(CastV0, CastV1, NewMask); replaceValue(I, *Shuf); return true; } diff --git a/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll b/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll index 211c90b5604e..e61b254b7a5f 100644 --- a/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll +++ b/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s -; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s -; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s +; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=CHECK +; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=CHECK +; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=AVX512 define <4 x i64> @PR67803(<4 x i64> %x, <4 x i64> %y, <4 x i64> %a, <4 x i64> %b) { ; CHECK-LABEL: @PR67803( @@ -35,6 +35,35 @@ define <4 x i64> @PR67803(<4 x i64> %x, <4 x i64> %y, <4 x i64> %a, <4 x i64> %b ; CHECK-NEXT: [[SHUFFLE_I23:%.*]] = shufflevector <2 x i64> [[TMP12]], <2 x i64> [[TMP20]], <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; CHECK-NEXT: ret <4 x i64> [[SHUFFLE_I23]] ; +; AVX512-LABEL: @PR67803( +; AVX512-NEXT: entry: +; AVX512-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[X:%.*]] to <8 x i32> +; AVX512-NEXT: [[TMP1:%.*]] = bitcast <4 x i64> [[Y:%.*]] to <8 x i32> +; AVX512-NEXT: [[TMP2:%.*]] = icmp sgt <8 x i32> [[TMP0]], [[TMP1]] +; AVX512-NEXT: [[CMP_I21:%.*]] = shufflevector <8 x i1> [[TMP2]], <8 x i1> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3> +; AVX512-NEXT: [[SEXT_I22:%.*]] = sext <4 x i1> [[CMP_I21]] to <4 x i32> +; AVX512-NEXT: [[CMP_I:%.*]] = shufflevector <8 x i1> [[TMP2]], <8 x i1> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7> +; AVX512-NEXT: [[SEXT_I:%.*]] = sext <4 x i1> [[CMP_I]] to <4 x i32> +; AVX512-NEXT: [[TMP3:%.*]] = shufflevector <4 x i32> [[SEXT_I22]], <4 x i32> [[SEXT_I]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> +; AVX512-NEXT: [[TMP4:%.*]] = bitcast <4 x i64> [[A:%.*]] to <32 x i8> +; AVX512-NEXT: [[TMP5:%.*]] = shufflevector <32 x i8> [[TMP4]], <32 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> +; AVX512-NEXT: [[TMP6:%.*]] = bitcast <4 x i64> [[B:%.*]] to <32 x i8> +; AVX512-NEXT: [[TMP7:%.*]] = shufflevector <32 x i8> [[TMP6]], <32 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> +; AVX512-NEXT: [[TMP8:%.*]] = bitcast <8 x i32> [[TMP3]] to <32 x i8> +; AVX512-NEXT: [[TMP9:%.*]] = shufflevector <32 x i8> [[TMP8]], <32 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> +; AVX512-NEXT: [[TMP10:%.*]] = tail call <16 x i8> @llvm.x86.sse41.pblendvb(<16 x i8> [[TMP5]], <16 x i8> [[TMP7]], <16 x i8> [[TMP9]]) +; AVX512-NEXT: [[TMP11:%.*]] = bitcast <16 x i8> [[TMP10]] to <2 x i64> +; AVX512-NEXT: [[TMP12:%.*]] = bitcast <4 x i64> [[A]] to <32 x i8> +; AVX512-NEXT: [[TMP13:%.*]] = shufflevector <32 x i8> [[TMP12]], <32 x i8> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31> +; AVX512-NEXT: [[TMP14:%.*]] = bitcast <4 x i64> [[B]] to <32 x i8> +; AVX512-NEXT: [[TMP15:%.*]] = shufflevector <32 x i8> [[TMP14]], <32 x i8> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31> +; AVX512-NEXT: [[TMP16:%.*]] = bitcast <8 x i32> [[TMP3]] to <32 x i8> +; AVX512-NEXT: [[TMP17:%.*]] = shufflevector <32 x i8> [[TMP16]], <32 x i8> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31> +; AVX512-NEXT: [[TMP18:%.*]] = tail call <16 x i8> @llvm.x86.sse41.pblendvb(<16 x i8> [[TMP13]], <16 x i8> [[TMP15]], <16 x i8> [[TMP17]]) +; AVX512-NEXT: [[TMP19:%.*]] = bitcast <16 x i8> [[TMP18]] to <2 x i64> +; AVX512-NEXT: [[SHUFFLE_I23:%.*]] = shufflevector <2 x i64> [[TMP11]], <2 x i64> [[TMP19]], <4 x i32> <i32 0, i32 1, i32 2, i32 3> +; AVX512-NEXT: ret <4 x i64> [[SHUFFLE_I23]] +; entry: %0 = bitcast <4 x i64> %x to <8 x i32> %extract = shufflevector <8 x i32> %0, <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3> -- GitLab From 3eb806373e3164b242db65f8c900e4adb5a2eddf Mon Sep 17 00:00:00 2001 From: Nikita Popov <npopov@redhat.com> Date: Wed, 20 Mar 2024 14:19:41 +0100 Subject: [PATCH 240/307] [CodeGen] Fix test on 32-bit targets (NFC) The range here will be different for 32-bit targets. Use a wildcard, just like all te other target-sensitive parts in this test. --- clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp index 4f96a3ae6707..ae0c3a26c597 100644 --- a/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp +++ b/clang/test/CodeGenCXX/copy-constructor-synthesis-2.cpp @@ -24,4 +24,4 @@ struct A { virtual void a(); }; A x(A& y) { return y; } // CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(ptr {{.*}}%this, ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %0) unnamed_addr -// CHECK: store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2) +// CHECK: store ptr getelementptr inbounds inrange(-{{[0-9]+}}, {{[0-9]+}}) ({ [3 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2) -- GitLab From 98c6bc531d091215896087b94e4e047c67f892c2 Mon Sep 17 00:00:00 2001 From: Christian Ulmann <christianulmann@gmail.com> Date: Wed, 20 Mar 2024 14:21:53 +0100 Subject: [PATCH 241/307] [MLIR][SROA][Mem2Reg] Add data layout to interface methods (#85644) This commit expends the Mem2Reg and SROA interface methods with passed in handles to a `DataLayout` structure. This is done to avoid superfluous retreiving of data layouts during each conversion of intrinsics. This change, additionally, enables subsequent changes to make the LLVM dialect implementation of these interfaces type agnostic. --- .../mlir/Interfaces/MemorySlotInterfaces.td | 43 ++--- mlir/include/mlir/Transforms/Mem2Reg.h | 2 +- mlir/include/mlir/Transforms/SROA.h | 3 +- mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp | 153 +++++++++++------- .../Dialect/MemRef/IR/MemRefMemorySlot.cpp | 18 ++- mlir/lib/Transforms/Mem2Reg.cpp | 24 ++- mlir/lib/Transforms/SROA.cpp | 30 ++-- 7 files changed, 165 insertions(+), 108 deletions(-) diff --git a/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td b/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td index 9ffa709cc5bf..e10e2d4e104c 100644 --- a/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td +++ b/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td @@ -83,11 +83,10 @@ def PromotableAllocationOpInterface def PromotableMemOpInterface : OpInterface<"PromotableMemOpInterface"> { let description = [{ Describes an operation that can load from memory slots and/or store - to memory slots. Loads and stores must be of whole values of the same - type as the slot itself. + to memory slots. - For a memory operation on a slot to be valid, it must operate on the slot - pointer *only as a pointer to an element of the type of the slot*. + For a memory operation on a slot to be valid, it must strictly operate + within the bounds of the slot. If the same operation does both loads and stores on the same slot, the load must semantically happen first. @@ -142,7 +141,8 @@ def PromotableMemOpInterface : OpInterface<"PromotableMemOpInterface"> { }], "bool", "canUsesBeRemoved", (ins "const ::mlir::MemorySlot &":$slot, "const ::llvm::SmallPtrSetImpl<::mlir::OpOperand *> &":$blockingUses, - "::llvm::SmallVectorImpl<::mlir::OpOperand *> &":$newBlockingUses) + "::llvm::SmallVectorImpl<::mlir::OpOperand *> &":$newBlockingUses, + "const ::mlir::DataLayout &":$datalayout) >, InterfaceMethod<[{ Transforms IR to ensure that the current operation does not use the @@ -197,7 +197,8 @@ def PromotableOpInterface : OpInterface<"PromotableOpInterface"> { No IR mutation is allowed in this method. }], "bool", "canUsesBeRemoved", (ins "const ::llvm::SmallPtrSetImpl<::mlir::OpOperand *> &":$blockingUses, - "::llvm::SmallVectorImpl<::mlir::OpOperand *> &":$newBlockingUses) + "::llvm::SmallVectorImpl<::mlir::OpOperand *> &":$newBlockingUses, + "const ::mlir::DataLayout &":$datalayout) >, InterfaceMethod<[{ Transforms IR to ensure that the current operation does not use the @@ -285,29 +286,28 @@ def DestructurableAllocationOpInterface def SafeMemorySlotAccessOpInterface : OpInterface<"SafeMemorySlotAccessOpInterface"> { let description = [{ - Describes operations using memory slots in a type-safe manner. + Describes operations using memory slots in a safe manner. }]; let cppNamespace = "::mlir"; let methods = [ InterfaceMethod<[{ Returns whether all accesses in this operation to the provided slot are - done in a type-safe manner. To be type-safe, the access must only load - the value in this type as the type of the slot, and without assuming any - context around the slot. For example, a type-safe load must not load - outside the bounds of the slot. + done in a safe manner. To be safe, the access most only access the slot + inside the bounds that its type implies. - If the type-safety of the accesses depends on the type-safety of the - accesses to further memory slots, the result of this method will be - conditioned to the type-safety of the accesses to the slots added by - this method to `mustBeSafelyUsed`. + If the safety of the accesses depends on the safety of the accesses to + further memory slots, the result of this method will be conditioned to + the safety of the accesses to the slots added by this method to + `mustBeSafelyUsed`. No IR mutation is allowed in this method. }], "::mlir::LogicalResult", "ensureOnlySafeAccesses", (ins "const ::mlir::MemorySlot &":$slot, - "::mlir::SmallVectorImpl<::mlir::MemorySlot> &":$mustBeSafelyUsed) + "::mlir::SmallVectorImpl<::mlir::MemorySlot> &":$mustBeSafelyUsed, + "const ::mlir::DataLayout &":$dataLayout) > ]; } @@ -323,13 +323,12 @@ def DestructurableAccessorOpInterface InterfaceMethod<[{ For a given destructurable memory slot, returns whether this operation can rewire its uses of the slot to use the slots generated after - destructuring. This may involve creating new operations, and usually - amounts to checking if the pointer types match. + destructuring. This may involve creating new operations. This method must also register the indices it will access within the `usedIndices` set. If the accessor generates new slots mapping to subelements, they must be registered in `mustBeSafelyUsed` to ensure - they are used in a locally type-safe manner. + they are used in a safe manner. No IR mutation is allowed in this method. }], @@ -337,7 +336,8 @@ def DestructurableAccessorOpInterface "canRewire", (ins "const ::mlir::DestructurableMemorySlot &":$slot, "::llvm::SmallPtrSetImpl<::mlir::Attribute> &":$usedIndices, - "::mlir::SmallVectorImpl<::mlir::MemorySlot> &":$mustBeSafelyUsed) + "::mlir::SmallVectorImpl<::mlir::MemorySlot> &":$mustBeSafelyUsed, + "const ::mlir::DataLayout &":$dataLayout) >, InterfaceMethod<[{ Rewires the use of a slot to the generated subslots, without deleting @@ -351,7 +351,8 @@ def DestructurableAccessorOpInterface "rewire", (ins "const ::mlir::DestructurableMemorySlot &":$slot, "::llvm::DenseMap<::mlir::Attribute, ::mlir::MemorySlot> &":$subslots, - "::mlir::RewriterBase &":$rewriter) + "::mlir::RewriterBase &":$rewriter, + "const ::mlir::DataLayout &":$dataLayout) > ]; } diff --git a/mlir/include/mlir/Transforms/Mem2Reg.h b/mlir/include/mlir/Transforms/Mem2Reg.h index d145f7ed4375..ed10644e26a5 100644 --- a/mlir/include/mlir/Transforms/Mem2Reg.h +++ b/mlir/include/mlir/Transforms/Mem2Reg.h @@ -27,7 +27,7 @@ struct Mem2RegStatistics { /// at least one memory slot was promoted. LogicalResult tryToPromoteMemorySlots(ArrayRef<PromotableAllocationOpInterface> allocators, - RewriterBase &rewriter, + RewriterBase &rewriter, const DataLayout &dataLayout, Mem2RegStatistics statistics = {}); } // namespace mlir diff --git a/mlir/include/mlir/Transforms/SROA.h b/mlir/include/mlir/Transforms/SROA.h index 1af1fe930723..d09a7989edea 100644 --- a/mlir/include/mlir/Transforms/SROA.h +++ b/mlir/include/mlir/Transforms/SROA.h @@ -31,7 +31,8 @@ struct SROAStatistics { /// failure if no slot was destructured. LogicalResult tryToDestructureMemorySlots( ArrayRef<DestructurableAllocationOpInterface> allocators, - RewriterBase &rewriter, SROAStatistics statistics = {}); + RewriterBase &rewriter, const DataLayout &dataLayout, + SROAStatistics statistics = {}); } // namespace mlir diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp index 81766b307d3d..00b4559658fd 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp @@ -132,7 +132,8 @@ Value LLVM::StoreOp::getStored(const MemorySlot &slot, RewriterBase &rewriter) { bool LLVM::LoadOp::canUsesBeRemoved( const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { if (blockingUses.size() != 1) return false; Value blockingUse = (*blockingUses.begin())->get(); @@ -155,7 +156,8 @@ DeletionKind LLVM::LoadOp::removeBlockingUses( bool LLVM::StoreOp::canUsesBeRemoved( const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { if (blockingUses.size() != 1) return false; Value blockingUse = (*blockingUses.begin())->get(); @@ -181,12 +183,14 @@ DeletionKind LLVM::StoreOp::removeBlockingUses( } LogicalResult LLVM::LoadOp::ensureOnlySafeAccesses( - const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { + const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { return success(getAddr() != slot.ptr || getType() == slot.elemType); } LogicalResult LLVM::StoreOp::ensureOnlySafeAccesses( - const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { + const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { return success(getAddr() != slot.ptr || getValue().getType() == slot.elemType); } @@ -206,7 +210,8 @@ static bool forwardToUsers(Operation *op, bool LLVM::BitcastOp::canUsesBeRemoved( const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { return forwardToUsers(*this, newBlockingUses); } @@ -217,7 +222,8 @@ DeletionKind LLVM::BitcastOp::removeBlockingUses( bool LLVM::AddrSpaceCastOp::canUsesBeRemoved( const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { return forwardToUsers(*this, newBlockingUses); } @@ -228,7 +234,8 @@ DeletionKind LLVM::AddrSpaceCastOp::removeBlockingUses( bool LLVM::LifetimeStartOp::canUsesBeRemoved( const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { return true; } @@ -239,7 +246,8 @@ DeletionKind LLVM::LifetimeStartOp::removeBlockingUses( bool LLVM::LifetimeEndOp::canUsesBeRemoved( const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { return true; } @@ -250,7 +258,8 @@ DeletionKind LLVM::LifetimeEndOp::removeBlockingUses( bool LLVM::InvariantStartOp::canUsesBeRemoved( const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { return true; } @@ -261,7 +270,8 @@ DeletionKind LLVM::InvariantStartOp::removeBlockingUses( bool LLVM::InvariantEndOp::canUsesBeRemoved( const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { return true; } @@ -272,7 +282,8 @@ DeletionKind LLVM::InvariantEndOp::removeBlockingUses( bool LLVM::DbgDeclareOp::canUsesBeRemoved( const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { return true; } @@ -283,7 +294,8 @@ DeletionKind LLVM::DbgDeclareOp::removeBlockingUses( bool LLVM::DbgValueOp::canUsesBeRemoved( const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { // There is only one operand that we can remove the use of. if (blockingUses.size() != 1) return false; @@ -318,7 +330,8 @@ static bool hasAllZeroIndices(LLVM::GEPOp gepOp) { bool LLVM::GEPOp::canUsesBeRemoved( const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { // GEP can be removed as long as it is a no-op and its users can be removed. if (!hasAllZeroIndices(*this)) return false; @@ -337,7 +350,8 @@ static bool isFirstIndexZero(LLVM::GEPOp gep) { } LogicalResult LLVM::GEPOp::ensureOnlySafeAccesses( - const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { + const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { if (getBase() != slot.ptr) return success(); if (slot.elemType != getElemType()) @@ -357,9 +371,9 @@ LogicalResult LLVM::GEPOp::ensureOnlySafeAccesses( bool LLVM::GEPOp::canRewire(const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices, - SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { - auto basePtrType = llvm::dyn_cast<LLVM::LLVMPointerType>(getBase().getType()); - if (!basePtrType) + SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { + if (!isa<LLVM::LLVMPointerType>(getBase().getType())) return false; if (getBase() != slot.ptr || slot.elemType != getElemType()) @@ -386,7 +400,8 @@ bool LLVM::GEPOp::canRewire(const DestructurableMemorySlot &slot, DeletionKind LLVM::GEPOp::rewire(const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots, - RewriterBase &rewriter) { + RewriterBase &rewriter, + const DataLayout &dataLayout) { IntegerAttr firstLevelIndex = llvm::dyn_cast_if_present<IntegerAttr>(getIndices()[1]); const MemorySlot &newSlot = subslots.at(firstLevelIndex); @@ -455,7 +470,7 @@ std::optional<uint64_t> getStaticMemIntrLen(LLVM::MemcpyInlineOp op) { /// of the bounds of the given slot, on a best-effort basis. template <class MemIntr> static bool definitelyWritesOnlyWithinSlot(MemIntr op, const MemorySlot &slot, - DataLayout &dataLayout) { + const DataLayout &dataLayout) { if (!isa<LLVM::LLVMPointerType>(slot.ptr.getType()) || op.getDst() != slot.ptr) return false; @@ -520,7 +535,8 @@ Value LLVM::MemsetOp::getStored(const MemorySlot &slot, bool LLVM::MemsetOp::canUsesBeRemoved( const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { // TODO: Support non-integer types. bool canConvertType = TypeSwitch<Type, bool>(slot.elemType) @@ -534,8 +550,7 @@ bool LLVM::MemsetOp::canUsesBeRemoved( if (getIsVolatile()) return false; - DataLayout layout = DataLayout::closest(*this); - return getStaticMemIntrLen(*this) == layout.getTypeSize(slot.elemType); + return getStaticMemIntrLen(*this) == dataLayout.getTypeSize(slot.elemType); } DeletionKind LLVM::MemsetOp::removeBlockingUses( @@ -545,14 +560,15 @@ DeletionKind LLVM::MemsetOp::removeBlockingUses( } LogicalResult LLVM::MemsetOp::ensureOnlySafeAccesses( - const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { - DataLayout dataLayout = DataLayout::closest(*this); + const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { return success(definitelyWritesOnlyWithinSlot(*this, slot, dataLayout)); } bool LLVM::MemsetOp::canRewire(const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices, - SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { + SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { if (&slot.elemType.getDialect() != getOperation()->getDialect()) return false; @@ -566,13 +582,13 @@ bool LLVM::MemsetOp::canRewire(const DestructurableMemorySlot &slot, if (!areAllIndicesI32(slot)) return false; - DataLayout dataLayout = DataLayout::closest(*this); return definitelyWritesOnlyWithinSlot(*this, slot, dataLayout); } DeletionKind LLVM::MemsetOp::rewire(const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots, - RewriterBase &rewriter) { + RewriterBase &rewriter, + const DataLayout &dataLayout) { std::optional<DenseMap<Attribute, Type>> types = slot.elemType.cast<DestructurableTypeInterface>().getSubelementIndexMap(); @@ -587,7 +603,6 @@ DeletionKind LLVM::MemsetOp::rewire(const DestructurableMemorySlot &slot, packed = structType.isPacked(); Type i32 = IntegerType::get(getContext(), 32); - DataLayout dataLayout = DataLayout::closest(*this); uint64_t memsetLen = memsetLenAttr.getValue().getZExtValue(); uint64_t covered = 0; for (size_t i = 0; i < types->size(); i++) { @@ -650,7 +665,8 @@ template <class MemcpyLike> static bool memcpyCanUsesBeRemoved(MemcpyLike op, const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { // If source and destination are the same, memcpy behavior is undefined and // memmove is a no-op. Because there is no memory change happening here, // simplifying such operations is left to canonicalization. @@ -660,8 +676,7 @@ memcpyCanUsesBeRemoved(MemcpyLike op, const MemorySlot &slot, if (op.getIsVolatile()) return false; - DataLayout layout = DataLayout::closest(op); - return getStaticMemIntrLen(op) == layout.getTypeSize(slot.elemType); + return getStaticMemIntrLen(op) == dataLayout.getTypeSize(slot.elemType); } template <class MemcpyLike> @@ -689,7 +704,8 @@ memcpyEnsureOnlySafeAccesses(MemcpyLike op, const MemorySlot &slot, template <class MemcpyLike> static bool memcpyCanRewire(MemcpyLike op, const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices, - SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { + SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { if (op.getIsVolatile()) return false; @@ -701,7 +717,6 @@ static bool memcpyCanRewire(MemcpyLike op, const DestructurableMemorySlot &slot, return false; // Only full copies are supported. - DataLayout dataLayout = DataLayout::closest(op); if (getStaticMemIntrLen(op) != dataLayout.getTypeSize(slot.elemType)) return false; @@ -741,15 +756,13 @@ void createMemcpyLikeToReplace(RewriterBase &rewriter, const DataLayout &layout, /// Rewires a memcpy-like operation. Only copies to or from the full slot are /// supported. template <class MemcpyLike> -static DeletionKind memcpyRewire(MemcpyLike op, - const DestructurableMemorySlot &slot, - DenseMap<Attribute, MemorySlot> &subslots, - RewriterBase &rewriter) { +static DeletionKind +memcpyRewire(MemcpyLike op, const DestructurableMemorySlot &slot, + DenseMap<Attribute, MemorySlot> &subslots, RewriterBase &rewriter, + const DataLayout &dataLayout) { if (subslots.empty()) return DeletionKind::Delete; - DataLayout layout = DataLayout::closest(op); - assert((slot.ptr == op.getDst()) != (slot.ptr == op.getSrc())); bool isDst = slot.ptr == op.getDst(); @@ -780,7 +793,7 @@ static DeletionKind memcpyRewire(MemcpyLike op, isDst ? op.getSrc() : op.getDst(), gepIndices); // Then create a new memcpy out of this source pointer. - createMemcpyLikeToReplace(rewriter, layout, op, + createMemcpyLikeToReplace(rewriter, dataLayout, op, isDst ? subslot.ptr : subslotPtrInOther, isDst ? subslotPtrInOther : subslot.ptr, subslot.elemType, op.getIsVolatile()); @@ -806,8 +819,10 @@ Value LLVM::MemcpyOp::getStored(const MemorySlot &slot, bool LLVM::MemcpyOp::canUsesBeRemoved( const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { - return memcpyCanUsesBeRemoved(*this, slot, blockingUses, newBlockingUses); + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { + return memcpyCanUsesBeRemoved(*this, slot, blockingUses, newBlockingUses, + dataLayout); } DeletionKind LLVM::MemcpyOp::removeBlockingUses( @@ -818,20 +833,24 @@ DeletionKind LLVM::MemcpyOp::removeBlockingUses( } LogicalResult LLVM::MemcpyOp::ensureOnlySafeAccesses( - const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { + const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { return memcpyEnsureOnlySafeAccesses(*this, slot, mustBeSafelyUsed); } bool LLVM::MemcpyOp::canRewire(const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices, - SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { - return memcpyCanRewire(*this, slot, usedIndices, mustBeSafelyUsed); + SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { + return memcpyCanRewire(*this, slot, usedIndices, mustBeSafelyUsed, + dataLayout); } DeletionKind LLVM::MemcpyOp::rewire(const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots, - RewriterBase &rewriter) { - return memcpyRewire(*this, slot, subslots, rewriter); + RewriterBase &rewriter, + const DataLayout &dataLayout) { + return memcpyRewire(*this, slot, subslots, rewriter, dataLayout); } bool LLVM::MemcpyInlineOp::loadsFrom(const MemorySlot &slot) { @@ -849,8 +868,10 @@ Value LLVM::MemcpyInlineOp::getStored(const MemorySlot &slot, bool LLVM::MemcpyInlineOp::canUsesBeRemoved( const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { - return memcpyCanUsesBeRemoved(*this, slot, blockingUses, newBlockingUses); + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { + return memcpyCanUsesBeRemoved(*this, slot, blockingUses, newBlockingUses, + dataLayout); } DeletionKind LLVM::MemcpyInlineOp::removeBlockingUses( @@ -861,22 +882,26 @@ DeletionKind LLVM::MemcpyInlineOp::removeBlockingUses( } LogicalResult LLVM::MemcpyInlineOp::ensureOnlySafeAccesses( - const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { + const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { return memcpyEnsureOnlySafeAccesses(*this, slot, mustBeSafelyUsed); } bool LLVM::MemcpyInlineOp::canRewire( const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices, - SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { - return memcpyCanRewire(*this, slot, usedIndices, mustBeSafelyUsed); + SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { + return memcpyCanRewire(*this, slot, usedIndices, mustBeSafelyUsed, + dataLayout); } DeletionKind LLVM::MemcpyInlineOp::rewire(const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots, - RewriterBase &rewriter) { - return memcpyRewire(*this, slot, subslots, rewriter); + RewriterBase &rewriter, + const DataLayout &dataLayout) { + return memcpyRewire(*this, slot, subslots, rewriter, dataLayout); } bool LLVM::MemmoveOp::loadsFrom(const MemorySlot &slot) { @@ -894,8 +919,10 @@ Value LLVM::MemmoveOp::getStored(const MemorySlot &slot, bool LLVM::MemmoveOp::canUsesBeRemoved( const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { - return memcpyCanUsesBeRemoved(*this, slot, blockingUses, newBlockingUses); + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { + return memcpyCanUsesBeRemoved(*this, slot, blockingUses, newBlockingUses, + dataLayout); } DeletionKind LLVM::MemmoveOp::removeBlockingUses( @@ -906,20 +933,24 @@ DeletionKind LLVM::MemmoveOp::removeBlockingUses( } LogicalResult LLVM::MemmoveOp::ensureOnlySafeAccesses( - const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { + const MemorySlot &slot, SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { return memcpyEnsureOnlySafeAccesses(*this, slot, mustBeSafelyUsed); } bool LLVM::MemmoveOp::canRewire(const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices, - SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { - return memcpyCanRewire(*this, slot, usedIndices, mustBeSafelyUsed); + SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { + return memcpyCanRewire(*this, slot, usedIndices, mustBeSafelyUsed, + dataLayout); } DeletionKind LLVM::MemmoveOp::rewire(const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots, - RewriterBase &rewriter) { - return memcpyRewire(*this, slot, subslots, rewriter); + RewriterBase &rewriter, + const DataLayout &dataLayout) { + return memcpyRewire(*this, slot, subslots, rewriter, dataLayout); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/MemRef/IR/MemRefMemorySlot.cpp b/mlir/lib/Dialect/MemRef/IR/MemRefMemorySlot.cpp index 561b8619032c..7be4056fb2fc 100644 --- a/mlir/lib/Dialect/MemRef/IR/MemRefMemorySlot.cpp +++ b/mlir/lib/Dialect/MemRef/IR/MemRefMemorySlot.cpp @@ -170,7 +170,8 @@ Value memref::LoadOp::getStored(const MemorySlot &slot, bool memref::LoadOp::canUsesBeRemoved( const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { if (blockingUses.size() != 1) return false; Value blockingUse = (*blockingUses.begin())->get(); @@ -210,7 +211,8 @@ static Attribute getAttributeIndexFromIndexOperands(MLIRContext *ctx, bool memref::LoadOp::canRewire(const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices, - SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { + SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { if (slot.ptr != getMemRef()) return false; Attribute index = getAttributeIndexFromIndexOperands( @@ -223,7 +225,8 @@ bool memref::LoadOp::canRewire(const DestructurableMemorySlot &slot, DeletionKind memref::LoadOp::rewire(const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots, - RewriterBase &rewriter) { + RewriterBase &rewriter, + const DataLayout &dataLayout) { Attribute index = getAttributeIndexFromIndexOperands( getContext(), getIndices(), getMemRefType()); const MemorySlot &memorySlot = subslots.at(index); @@ -247,7 +250,8 @@ Value memref::StoreOp::getStored(const MemorySlot &slot, bool memref::StoreOp::canUsesBeRemoved( const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses, - SmallVectorImpl<OpOperand *> &newBlockingUses) { + SmallVectorImpl<OpOperand *> &newBlockingUses, + const DataLayout &dataLayout) { if (blockingUses.size() != 1) return false; Value blockingUse = (*blockingUses.begin())->get(); @@ -263,7 +267,8 @@ DeletionKind memref::StoreOp::removeBlockingUses( bool memref::StoreOp::canRewire(const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices, - SmallVectorImpl<MemorySlot> &mustBeSafelyUsed) { + SmallVectorImpl<MemorySlot> &mustBeSafelyUsed, + const DataLayout &dataLayout) { if (slot.ptr != getMemRef() || getValue() == slot.ptr) return false; Attribute index = getAttributeIndexFromIndexOperands( @@ -276,7 +281,8 @@ bool memref::StoreOp::canRewire(const DestructurableMemorySlot &slot, DeletionKind memref::StoreOp::rewire(const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots, - RewriterBase &rewriter) { + RewriterBase &rewriter, + const DataLayout &dataLayout) { Attribute index = getAttributeIndexFromIndexOperands( getContext(), getIndices(), getMemRefType()); const MemorySlot &memorySlot = subslots.at(index); diff --git a/mlir/lib/Transforms/Mem2Reg.cpp b/mlir/lib/Transforms/Mem2Reg.cpp index 84ac69b4514b..80e3b7901632 100644 --- a/mlir/lib/Transforms/Mem2Reg.cpp +++ b/mlir/lib/Transforms/Mem2Reg.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "mlir/Transforms/Mem2Reg.h" +#include "mlir/Analysis/DataLayoutAnalysis.h" #include "mlir/Analysis/SliceAnalysis.h" #include "mlir/IR/Builders.h" #include "mlir/IR/Dominance.h" @@ -117,8 +118,9 @@ struct MemorySlotPromotionInfo { /// promotion. This does not mutate IR. class MemorySlotPromotionAnalyzer { public: - MemorySlotPromotionAnalyzer(MemorySlot slot, DominanceInfo &dominance) - : slot(slot), dominance(dominance) {} + MemorySlotPromotionAnalyzer(MemorySlot slot, DominanceInfo &dominance, + const DataLayout &dataLayout) + : slot(slot), dominance(dominance), dataLayout(dataLayout) {} /// Computes the information for slot promotion if promotion is possible, /// returns nothing otherwise. @@ -153,6 +155,7 @@ private: MemorySlot slot; DominanceInfo &dominance; + const DataLayout &dataLayout; }; /// The MemorySlotPromoter handles the state of promoting a memory slot. It @@ -267,10 +270,12 @@ LogicalResult MemorySlotPromotionAnalyzer::computeBlockingUses( // If the operation decides it cannot deal with removing the blocking uses, // promotion must fail. if (auto promotable = dyn_cast<PromotableOpInterface>(user)) { - if (!promotable.canUsesBeRemoved(blockingUses, newBlockingUses)) + if (!promotable.canUsesBeRemoved(blockingUses, newBlockingUses, + dataLayout)) return failure(); } else if (auto promotable = dyn_cast<PromotableMemOpInterface>(user)) { - if (!promotable.canUsesBeRemoved(slot, blockingUses, newBlockingUses)) + if (!promotable.canUsesBeRemoved(slot, blockingUses, newBlockingUses, + dataLayout)) return failure(); } else { // An operation that has blocking uses must be promoted. If it is not @@ -610,7 +615,8 @@ void MemorySlotPromoter::promoteSlot() { LogicalResult mlir::tryToPromoteMemorySlots( ArrayRef<PromotableAllocationOpInterface> allocators, - RewriterBase &rewriter, Mem2RegStatistics statistics) { + RewriterBase &rewriter, const DataLayout &dataLayout, + Mem2RegStatistics statistics) { bool promotedAny = false; for (PromotableAllocationOpInterface allocator : allocators) { @@ -619,7 +625,7 @@ LogicalResult mlir::tryToPromoteMemorySlots( continue; DominanceInfo dominance; - MemorySlotPromotionAnalyzer analyzer(slot, dominance); + MemorySlotPromotionAnalyzer analyzer(slot, dominance, dataLayout); std::optional<MemorySlotPromotionInfo> info = analyzer.computeInfo(); if (info) { MemorySlotPromoter(slot, allocator, rewriter, dominance, @@ -661,8 +667,12 @@ struct Mem2Reg : impl::Mem2RegBase<Mem2Reg> { allocators.emplace_back(allocator); }); + auto &dataLayoutAnalysis = getAnalysis<DataLayoutAnalysis>(); + const DataLayout &dataLayout = dataLayoutAnalysis.getAtOrAbove(scopeOp); + // Attempt promoting until no promotion succeeds. - if (failed(tryToPromoteMemorySlots(allocators, rewriter, statistics))) + if (failed(tryToPromoteMemorySlots(allocators, rewriter, dataLayout, + statistics))) break; changed = true; diff --git a/mlir/lib/Transforms/SROA.cpp b/mlir/lib/Transforms/SROA.cpp index 6111489bdebe..f24cbb7b1725 100644 --- a/mlir/lib/Transforms/SROA.cpp +++ b/mlir/lib/Transforms/SROA.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "mlir/Transforms/SROA.h" +#include "mlir/Analysis/DataLayoutAnalysis.h" #include "mlir/Analysis/SliceAnalysis.h" #include "mlir/Interfaces/MemorySlotInterfaces.h" #include "mlir/Transforms/Passes.h" @@ -42,7 +43,8 @@ struct MemorySlotDestructuringInfo { /// nothing if the slot cannot be destructured or if there is no useful work to /// be done. static std::optional<MemorySlotDestructuringInfo> -computeDestructuringInfo(DestructurableMemorySlot &slot) { +computeDestructuringInfo(DestructurableMemorySlot &slot, + const DataLayout &dataLayout) { assert(isa<DestructurableTypeInterface>(slot.elemType)); if (slot.ptr.use_empty()) @@ -62,7 +64,8 @@ computeDestructuringInfo(DestructurableMemorySlot &slot) { for (OpOperand &use : slot.ptr.getUses()) { if (auto accessor = dyn_cast<DestructurableAccessorOpInterface>(use.getOwner())) { - if (accessor.canRewire(slot, info.usedIndices, usedSafelyWorklist)) { + if (accessor.canRewire(slot, info.usedIndices, usedSafelyWorklist, + dataLayout)) { info.accessors.push_back(accessor); continue; } @@ -82,8 +85,8 @@ computeDestructuringInfo(DestructurableMemorySlot &slot) { Operation *subslotUser = subslotUse.getOwner(); if (auto memOp = dyn_cast<SafeMemorySlotAccessOpInterface>(subslotUser)) - if (succeeded(memOp.ensureOnlySafeAccesses(mustBeUsedSafely, - usedSafelyWorklist))) + if (succeeded(memOp.ensureOnlySafeAccesses( + mustBeUsedSafely, usedSafelyWorklist, dataLayout))) continue; // If it cannot be shown that the operation uses the slot safely, maybe it @@ -110,7 +113,7 @@ computeDestructuringInfo(DestructurableMemorySlot &slot) { SmallVector<OpOperand *> newBlockingUses; // If the operation decides it cannot deal with removing the blocking uses, // destructuring must fail. - if (!promotable.canUsesBeRemoved(blockingUses, newBlockingUses)) + if (!promotable.canUsesBeRemoved(blockingUses, newBlockingUses, dataLayout)) return {}; // Then, register any new blocking uses for coming operations. @@ -132,6 +135,7 @@ computeDestructuringInfo(DestructurableMemorySlot &slot) { static void destructureSlot(DestructurableMemorySlot &slot, DestructurableAllocationOpInterface allocator, RewriterBase &rewriter, + const DataLayout &dataLayout, MemorySlotDestructuringInfo &info, const SROAStatistics &statistics) { RewriterBase::InsertionGuard guard(rewriter); @@ -158,7 +162,8 @@ static void destructureSlot(DestructurableMemorySlot &slot, for (Operation *toRewire : llvm::reverse(usersToRewire)) { rewriter.setInsertionPointAfter(toRewire); if (auto accessor = dyn_cast<DestructurableAccessorOpInterface>(toRewire)) { - if (accessor.rewire(slot, subslots, rewriter) == DeletionKind::Delete) + if (accessor.rewire(slot, subslots, rewriter, dataLayout) == + DeletionKind::Delete) toErase.push_back(accessor); continue; } @@ -186,17 +191,18 @@ static void destructureSlot(DestructurableMemorySlot &slot, LogicalResult mlir::tryToDestructureMemorySlots( ArrayRef<DestructurableAllocationOpInterface> allocators, - RewriterBase &rewriter, SROAStatistics statistics) { + RewriterBase &rewriter, const DataLayout &dataLayout, + SROAStatistics statistics) { bool destructuredAny = false; for (DestructurableAllocationOpInterface allocator : allocators) { for (DestructurableMemorySlot slot : allocator.getDestructurableSlots()) { std::optional<MemorySlotDestructuringInfo> info = - computeDestructuringInfo(slot); + computeDestructuringInfo(slot, dataLayout); if (!info) continue; - destructureSlot(slot, allocator, rewriter, *info, statistics); + destructureSlot(slot, allocator, rewriter, dataLayout, *info, statistics); destructuredAny = true; } } @@ -215,6 +221,8 @@ struct SROA : public impl::SROABase<SROA> { SROAStatistics statistics{&destructuredAmount, &slotsWithMemoryBenefit, &maxSubelementAmount}; + auto &dataLayoutAnalysis = getAnalysis<DataLayoutAnalysis>(); + const DataLayout &dataLayout = dataLayoutAnalysis.getAtOrAbove(scopeOp); bool changed = false; for (Region ®ion : scopeOp->getRegions()) { @@ -235,8 +243,8 @@ struct SROA : public impl::SROABase<SROA> { allocators.emplace_back(allocator); }); - if (failed( - tryToDestructureMemorySlots(allocators, rewriter, statistics))) + if (failed(tryToDestructureMemorySlots(allocators, rewriter, dataLayout, + statistics))) break; changed = true; -- GitLab From ada24ae5e6e3da1002fe4debe9d37a8279d11c11 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <llvm-dev@redking.me.uk> Date: Wed, 20 Mar 2024 13:39:42 +0000 Subject: [PATCH 242/307] Revert 2ac85d8d200a9e1e0ced501c2d2f04404c400bd9 "[VectorCombine] foldBitcastShuf - add support for binary shuffles" Breaks some tests in other subprojects - will recommit with a fix later --- .../Transforms/Vectorize/VectorCombine.cpp | 21 +++++------ .../Transforms/PhaseOrdering/X86/pr67803.ll | 35 ++----------------- 2 files changed, 11 insertions(+), 45 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp index 23494314f132..0b16a8b76769 100644 --- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp +++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp @@ -684,10 +684,10 @@ bool VectorCombine::foldInsExtFNeg(Instruction &I) { /// destination type followed by shuffle. This can enable further transforms by /// moving bitcasts or shuffles together. bool VectorCombine::foldBitcastShuffle(Instruction &I) { - Value *V0, *V1; + Value *V0; ArrayRef<int> Mask; if (!match(&I, m_BitCast(m_OneUse( - m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(Mask)))))) + m_Shuffle(m_Value(V0), m_Undef(), m_Mask(Mask)))))) return false; // 1) Do not fold bitcast shuffle for scalable type. First, shuffle cost for @@ -728,21 +728,17 @@ bool VectorCombine::foldBitcastShuffle(Instruction &I) { FixedVectorType::get(DestTy->getScalarType(), NumSrcElts); auto *OldShuffleTy = FixedVectorType::get(SrcTy->getScalarType(), Mask.size()); - bool IsUnary = isa<UndefValue>(V1); - unsigned NumOps = IsUnary ? 1 : 2; // The new shuffle must not cost more than the old shuffle. TargetTransformInfo::TargetCostKind CK = TargetTransformInfo::TCK_RecipThroughput; TargetTransformInfo::ShuffleKind SK = - IsUnary ? TargetTransformInfo::SK_PermuteSingleSrc - : TargetTransformInfo::SK_PermuteTwoSrc; + TargetTransformInfo::SK_PermuteSingleSrc; InstructionCost DestCost = TTI.getShuffleCost(SK, NewShuffleTy, NewMask, CK) + - (NumOps * TTI.getCastInstrCost(Instruction::BitCast, NewShuffleTy, SrcTy, - TargetTransformInfo::CastContextHint::None, - CK)); + TTI.getCastInstrCost(Instruction::BitCast, NewShuffleTy, SrcTy, + TargetTransformInfo::CastContextHint::None, CK); InstructionCost SrcCost = TTI.getShuffleCost(SK, SrcTy, Mask, CK) + TTI.getCastInstrCost(Instruction::BitCast, DestTy, OldShuffleTy, @@ -750,11 +746,10 @@ bool VectorCombine::foldBitcastShuffle(Instruction &I) { if (DestCost > SrcCost || !DestCost.isValid()) return false; - // bitcast (shuf V0, V1, MaskC) --> shuf (bitcast V0), (bitcast V1), MaskC' + // bitcast (shuf V0, MaskC) --> shuf (bitcast V0), MaskC' ++NumShufOfBitcast; - Value *CastV0 = Builder.CreateBitCast(V0, NewShuffleTy); - Value *CastV1 = Builder.CreateBitCast(V1, NewShuffleTy); - Value *Shuf = Builder.CreateShuffleVector(CastV0, CastV1, NewMask); + Value *CastV = Builder.CreateBitCast(V0, NewShuffleTy); + Value *Shuf = Builder.CreateShuffleVector(CastV, NewMask); replaceValue(I, *Shuf); return true; } diff --git a/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll b/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll index e61b254b7a5f..211c90b5604e 100644 --- a/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll +++ b/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=CHECK -; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=CHECK -; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=AVX512 +; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s +; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s +; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s define <4 x i64> @PR67803(<4 x i64> %x, <4 x i64> %y, <4 x i64> %a, <4 x i64> %b) { ; CHECK-LABEL: @PR67803( @@ -35,35 +35,6 @@ define <4 x i64> @PR67803(<4 x i64> %x, <4 x i64> %y, <4 x i64> %a, <4 x i64> %b ; CHECK-NEXT: [[SHUFFLE_I23:%.*]] = shufflevector <2 x i64> [[TMP12]], <2 x i64> [[TMP20]], <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; CHECK-NEXT: ret <4 x i64> [[SHUFFLE_I23]] ; -; AVX512-LABEL: @PR67803( -; AVX512-NEXT: entry: -; AVX512-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[X:%.*]] to <8 x i32> -; AVX512-NEXT: [[TMP1:%.*]] = bitcast <4 x i64> [[Y:%.*]] to <8 x i32> -; AVX512-NEXT: [[TMP2:%.*]] = icmp sgt <8 x i32> [[TMP0]], [[TMP1]] -; AVX512-NEXT: [[CMP_I21:%.*]] = shufflevector <8 x i1> [[TMP2]], <8 x i1> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3> -; AVX512-NEXT: [[SEXT_I22:%.*]] = sext <4 x i1> [[CMP_I21]] to <4 x i32> -; AVX512-NEXT: [[CMP_I:%.*]] = shufflevector <8 x i1> [[TMP2]], <8 x i1> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7> -; AVX512-NEXT: [[SEXT_I:%.*]] = sext <4 x i1> [[CMP_I]] to <4 x i32> -; AVX512-NEXT: [[TMP3:%.*]] = shufflevector <4 x i32> [[SEXT_I22]], <4 x i32> [[SEXT_I]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> -; AVX512-NEXT: [[TMP4:%.*]] = bitcast <4 x i64> [[A:%.*]] to <32 x i8> -; AVX512-NEXT: [[TMP5:%.*]] = shufflevector <32 x i8> [[TMP4]], <32 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> -; AVX512-NEXT: [[TMP6:%.*]] = bitcast <4 x i64> [[B:%.*]] to <32 x i8> -; AVX512-NEXT: [[TMP7:%.*]] = shufflevector <32 x i8> [[TMP6]], <32 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> -; AVX512-NEXT: [[TMP8:%.*]] = bitcast <8 x i32> [[TMP3]] to <32 x i8> -; AVX512-NEXT: [[TMP9:%.*]] = shufflevector <32 x i8> [[TMP8]], <32 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> -; AVX512-NEXT: [[TMP10:%.*]] = tail call <16 x i8> @llvm.x86.sse41.pblendvb(<16 x i8> [[TMP5]], <16 x i8> [[TMP7]], <16 x i8> [[TMP9]]) -; AVX512-NEXT: [[TMP11:%.*]] = bitcast <16 x i8> [[TMP10]] to <2 x i64> -; AVX512-NEXT: [[TMP12:%.*]] = bitcast <4 x i64> [[A]] to <32 x i8> -; AVX512-NEXT: [[TMP13:%.*]] = shufflevector <32 x i8> [[TMP12]], <32 x i8> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31> -; AVX512-NEXT: [[TMP14:%.*]] = bitcast <4 x i64> [[B]] to <32 x i8> -; AVX512-NEXT: [[TMP15:%.*]] = shufflevector <32 x i8> [[TMP14]], <32 x i8> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31> -; AVX512-NEXT: [[TMP16:%.*]] = bitcast <8 x i32> [[TMP3]] to <32 x i8> -; AVX512-NEXT: [[TMP17:%.*]] = shufflevector <32 x i8> [[TMP16]], <32 x i8> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31> -; AVX512-NEXT: [[TMP18:%.*]] = tail call <16 x i8> @llvm.x86.sse41.pblendvb(<16 x i8> [[TMP13]], <16 x i8> [[TMP15]], <16 x i8> [[TMP17]]) -; AVX512-NEXT: [[TMP19:%.*]] = bitcast <16 x i8> [[TMP18]] to <2 x i64> -; AVX512-NEXT: [[SHUFFLE_I23:%.*]] = shufflevector <2 x i64> [[TMP11]], <2 x i64> [[TMP19]], <4 x i32> <i32 0, i32 1, i32 2, i32 3> -; AVX512-NEXT: ret <4 x i64> [[SHUFFLE_I23]] -; entry: %0 = bitcast <4 x i64> %x to <8 x i32> %extract = shufflevector <8 x i32> %0, <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3> -- GitLab From 9d1cb18d19862fc0627e4a56e1e491a498e84c71 Mon Sep 17 00:00:00 2001 From: Hans <hans@hanshq.net> Date: Wed, 20 Mar 2024 14:51:45 +0100 Subject: [PATCH 243/307] [Coroutines] Ignore instructions more aggressively in addMustTailToCoroResumes() (#85271) The old code used isInstructionTriviallyDead() and removed instructions when walking the path from a resume call to function return to check if the call is in tail position. However, since the code was walking forwards it was not able to get past instructions such as: %gep = getelementptr inbounds i64, ptr %alloc.var, i32 0 %foo = ptrtoint ptr %gep to i64 This patch instead ignores such instructions as long as their values are not needed. This enables the code to emit tail calls in more situations. --- .../coro-symmetric-transfer-04.cpp | 66 ++++++++++++++++ llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 79 +++++++------------ .../Coroutines/coro-split-musttail7.ll | 12 ++- 3 files changed, 104 insertions(+), 53 deletions(-) create mode 100644 clang/test/CodeGenCoroutines/coro-symmetric-transfer-04.cpp diff --git a/clang/test/CodeGenCoroutines/coro-symmetric-transfer-04.cpp b/clang/test/CodeGenCoroutines/coro-symmetric-transfer-04.cpp new file mode 100644 index 000000000000..cf9170d7e711 --- /dev/null +++ b/clang/test/CodeGenCoroutines/coro-symmetric-transfer-04.cpp @@ -0,0 +1,66 @@ +// This tests that the symmetric transfer at the final suspend point could happen successfully. +// Based on https://github.com/llvm/llvm-project/pull/85271#issuecomment-2007554532 +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -O2 -emit-llvm %s -o - | FileCheck %s + +#include "Inputs/coroutine.h" + +struct Task { + struct promise_type { + struct FinalAwaiter { + bool await_ready() const noexcept { return false; } + template <typename PromiseType> + std::coroutine_handle<> await_suspend(std::coroutine_handle<PromiseType> h) noexcept { + return h.promise().continuation; + } + void await_resume() noexcept {} + }; + Task get_return_object() noexcept { + return std::coroutine_handle<promise_type>::from_promise(*this); + } + std::suspend_always initial_suspend() noexcept { return {}; } + FinalAwaiter final_suspend() noexcept { return {}; } + void unhandled_exception() noexcept {} + void return_value(int x) noexcept { + _value = x; + } + std::coroutine_handle<> continuation; + int _value; + }; + + Task(std::coroutine_handle<promise_type> handle) : handle(handle), stuff(123) {} + + struct Awaiter { + std::coroutine_handle<promise_type> handle; + Awaiter(std::coroutine_handle<promise_type> handle) : handle(handle) {} + bool await_ready() const noexcept { return false; } + std::coroutine_handle<void> await_suspend(std::coroutine_handle<void> continuation) noexcept { + handle.promise().continuation = continuation; + return handle; + } + int await_resume() noexcept { + int ret = handle.promise()._value; + handle.destroy(); + return ret; + } + }; + + auto operator co_await() { + auto handle_ = handle; + handle = nullptr; + return Awaiter(handle_); + } + +private: + std::coroutine_handle<promise_type> handle; + int stuff; +}; + +Task task0() { + co_return 43; +} + +// CHECK-LABEL: define{{.*}} void @_Z5task0v.resume +// This checks we are still in the scope of the current function. +// CHECK-NOT: {{^}}} +// CHECK: musttail call fastcc void +// CHECK-NEXT: ret void diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp index 3f3d81474faf..3a43b1edcaba 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -1198,22 +1198,6 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) { assert(InitialInst->getModule()); const DataLayout &DL = InitialInst->getModule()->getDataLayout(); - auto GetFirstValidInstruction = [](Instruction *I) { - while (I) { - // BitCastInst wouldn't generate actual code so that we could skip it. - if (isa<BitCastInst>(I) || I->isDebugOrPseudoInst() || - I->isLifetimeStartOrEnd()) - I = I->getNextNode(); - else if (isInstructionTriviallyDead(I)) - // Duing we are in the middle of the transformation, we need to erase - // the dead instruction manually. - I = &*I->eraseFromParent(); - else - break; - } - return I; - }; - auto TryResolveConstant = [&ResolvedValues](Value *V) { auto It = ResolvedValues.find(V); if (It != ResolvedValues.end()) @@ -1222,8 +1206,9 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) { }; Instruction *I = InitialInst; - while (I->isTerminator() || isa<CmpInst>(I)) { + while (true) { if (isa<ReturnInst>(I)) { + assert(!cast<ReturnInst>(I)->getReturnValue()); ReplaceInstWithInst(InitialInst, I->clone()); return true; } @@ -1247,40 +1232,26 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) { BasicBlock *Succ = BR->getSuccessor(SuccIndex); scanPHIsAndUpdateValueMap(I, Succ, ResolvedValues); - I = GetFirstValidInstruction(Succ->getFirstNonPHIOrDbgOrLifetime()); - + I = Succ->getFirstNonPHIOrDbgOrLifetime(); continue; } - if (auto *CondCmp = dyn_cast<CmpInst>(I)) { + if (auto *Cmp = dyn_cast<CmpInst>(I)) { // If the case number of suspended switch instruction is reduced to // 1, then it is simplified to CmpInst in llvm::ConstantFoldTerminator. - auto *BR = dyn_cast<BranchInst>( - GetFirstValidInstruction(CondCmp->getNextNode())); - if (!BR || !BR->isConditional() || CondCmp != BR->getCondition()) - return false; - - // And the comparsion looks like : %cond = icmp eq i8 %V, constant. - // So we try to resolve constant for the first operand only since the - // second operand should be literal constant by design. - ConstantInt *Cond0 = TryResolveConstant(CondCmp->getOperand(0)); - auto *Cond1 = dyn_cast<ConstantInt>(CondCmp->getOperand(1)); - if (!Cond0 || !Cond1) - return false; - - // Both operands of the CmpInst are Constant. So that we could evaluate - // it immediately to get the destination. - auto *ConstResult = - dyn_cast_or_null<ConstantInt>(ConstantFoldCompareInstOperands( - CondCmp->getPredicate(), Cond0, Cond1, DL)); - if (!ConstResult) - return false; - - ResolvedValues[BR->getCondition()] = ConstResult; - - // Handle this branch in next iteration. - I = BR; - continue; + // Try to constant fold it. + ConstantInt *Cond0 = TryResolveConstant(Cmp->getOperand(0)); + ConstantInt *Cond1 = TryResolveConstant(Cmp->getOperand(1)); + if (Cond0 && Cond1) { + ConstantInt *Result = + dyn_cast_or_null<ConstantInt>(ConstantFoldCompareInstOperands( + Cmp->getPredicate(), Cond0, Cond1, DL)); + if (Result) { + ResolvedValues[Cmp] = Result; + I = I->getNextNode(); + continue; + } + } } if (auto *SI = dyn_cast<SwitchInst>(I)) { @@ -1288,13 +1259,21 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) { if (!Cond) return false; - BasicBlock *BB = SI->findCaseValue(Cond)->getCaseSuccessor(); - scanPHIsAndUpdateValueMap(I, BB, ResolvedValues); - I = GetFirstValidInstruction(BB->getFirstNonPHIOrDbgOrLifetime()); + BasicBlock *Succ = SI->findCaseValue(Cond)->getCaseSuccessor(); + scanPHIsAndUpdateValueMap(I, Succ, ResolvedValues); + I = Succ->getFirstNonPHIOrDbgOrLifetime(); + continue; + } + + if (I->isDebugOrPseudoInst() || I->isLifetimeStartOrEnd() || + wouldInstructionBeTriviallyDead(I)) { + // We can skip instructions without side effects. If their values are + // needed, we'll notice later, e.g. when hitting a conditional branch. + I = I->getNextNode(); continue; } - return false; + break; } return false; diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll index 2257d5aee473..d0d5005587bd 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll @@ -1,6 +1,6 @@ ; Tests that sinked lifetime markers wouldn't provent optimization ; to convert a resuming call to a musttail call. -; The difference between this and coro-split-musttail5.ll and coro-split-musttail5.ll +; The difference between this and coro-split-musttail5.ll and coro-split-musttail6.ll ; is that this contains dead instruction generated during the transformation, ; which makes the optimization harder. ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s @@ -8,7 +8,7 @@ declare void @fakeresume1(ptr align 8) -define void @g() #0 { +define i64 @g() #0 { entry: %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) %alloc = call ptr @malloc(i64 16) #3 @@ -27,6 +27,11 @@ await.suspend: %save2 = call token @llvm.coro.save(ptr null) call fastcc void @fakeresume1(ptr align 8 null) %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) + + ; These (non-trivially) dead instructions are in the way. + %gep = getelementptr inbounds i64, ptr %alloc.var, i32 0 + %foo = ptrtoint ptr %gep to i64 + switch i8 %suspend2, label %exit [ i8 0, label %await.ready i8 1, label %exit @@ -36,8 +41,9 @@ await.ready: call void @llvm.lifetime.end.p0(i64 1, ptr %alloc.var) br label %exit exit: + %result = phi i64 [0, %entry], [0, %entry], [%foo, %await.suspend], [%foo, %await.suspend], [%foo, %await.ready] call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void + ret i64 %result } ; Verify that in the resume part resume call is marked with musttail. -- GitLab From abed4b74764de7df2a40272699e304f43e118994 Mon Sep 17 00:00:00 2001 From: Jay Foad <jay.foad@amd.com> Date: Wed, 20 Mar 2024 13:53:33 +0000 Subject: [PATCH 244/307] [AMDGPU] Simplify definition of GLOBAL_LOAD_TR Real instructions --- llvm/lib/Target/AMDGPU/FLATInstructions.td | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/FLATInstructions.td b/llvm/lib/Target/AMDGPU/FLATInstructions.td index c91fa1477098..db1f8c187265 100644 --- a/llvm/lib/Target/AMDGPU/FLATInstructions.td +++ b/llvm/lib/Target/AMDGPU/FLATInstructions.td @@ -982,11 +982,15 @@ defm SCRATCH_LOAD_LDS_DWORD : FLAT_Scratch_Load_LDS_Pseudo <"scratch_load_lds_d let SubtargetPredicate = isGFX12Plus in { let WaveSizePredicate = isWave32 in { + let Mnemonic = "global_load_tr_b128" in defm GLOBAL_LOAD_TR_B128_w32 : FLAT_Global_Load_Pseudo <"global_load_tr_b128_w32", VReg_128>; + let Mnemonic = "global_load_tr_b64" in defm GLOBAL_LOAD_TR_B64_w32 : FLAT_Global_Load_Pseudo <"global_load_tr_b64_w32", VReg_64>; } let WaveSizePredicate = isWave64 in { + let Mnemonic = "global_load_tr_b128" in defm GLOBAL_LOAD_TR_B128_w64 : FLAT_Global_Load_Pseudo <"global_load_tr_b128_w64", VReg_64>; + let Mnemonic = "global_load_tr_b64" in defm GLOBAL_LOAD_TR_B64_w64 : FLAT_Global_Load_Pseudo <"global_load_tr_b64_w64", VGPR_32>; } } // End SubtargetPredicate = isGFX12Plus @@ -2710,11 +2714,11 @@ defm GLOBAL_ATOMIC_FMIN : VGLOBAL_Real_Atomics_gfx12<0x051, "global_a defm GLOBAL_ATOMIC_FMAX : VGLOBAL_Real_Atomics_gfx12<0x052, "global_atomic_max_num_f32", "global_atomic_max_f32">; defm GLOBAL_ATOMIC_ADD_F32 : VGLOBAL_Real_Atomics_gfx12<0x056>; -defm GLOBAL_LOAD_TR_B128_w32 : VGLOBAL_Real_AllAddr_gfx12<0x057, "global_load_tr_b128">; -defm GLOBAL_LOAD_TR_B64_w32 : VGLOBAL_Real_AllAddr_gfx12<0x058, "global_load_tr_b64">; +defm GLOBAL_LOAD_TR_B128_w32 : VGLOBAL_Real_AllAddr_gfx12<0x057>; +defm GLOBAL_LOAD_TR_B64_w32 : VGLOBAL_Real_AllAddr_gfx12<0x058>; -defm GLOBAL_LOAD_TR_B128_w64 : VGLOBAL_Real_AllAddr_gfx12_w64<0x057, "global_load_tr_b128">; -defm GLOBAL_LOAD_TR_B64_w64 : VGLOBAL_Real_AllAddr_gfx12_w64<0x058, "global_load_tr_b64">; +defm GLOBAL_LOAD_TR_B128_w64 : VGLOBAL_Real_AllAddr_gfx12_w64<0x057>; +defm GLOBAL_LOAD_TR_B64_w64 : VGLOBAL_Real_AllAddr_gfx12_w64<0x058>; defm GLOBAL_ATOMIC_ORDERED_ADD_B64 : VGLOBAL_Real_Atomics_gfx12<0x073>; defm GLOBAL_ATOMIC_PK_ADD_F16 : VGLOBAL_Real_Atomics_gfx12<0x059>; -- GitLab From 3fbac79064e405a54388d11370ab5a8f0f23914d Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Wed, 20 Mar 2024 14:54:02 +0100 Subject: [PATCH 245/307] [AArch64] Don't write to source directory in test --- clang/test/CodeGen/aarch64-soft-float-abi-errors.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/test/CodeGen/aarch64-soft-float-abi-errors.c b/clang/test/CodeGen/aarch64-soft-float-abi-errors.c index 3e5ab9e92a1d..551e53bcd63d 100644 --- a/clang/test/CodeGen/aarch64-soft-float-abi-errors.c +++ b/clang/test/CodeGen/aarch64-soft-float-abi-errors.c @@ -1,9 +1,9 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +fp-armv8 -S -target-abi aapcs -verify=fp-hard %s -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fp-armv8 -S -target-abi aapcs-soft -verify=nofp-soft %s -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fp-armv8 -S -target-abi aapcs -verify=nofp-hard %s -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fp-armv8 -S -target-abi aapcs -O1 -verify=nofp-hard,nofp-hard-opt -emit-llvm %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +fp-armv8 -S -o /dev/null -target-abi aapcs -verify=fp-hard %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fp-armv8 -S -o /dev/null -target-abi aapcs-soft -verify=nofp-soft %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fp-armv8 -S -o /dev/null -target-abi aapcs -verify=nofp-hard %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fp-armv8 -S -o /dev/null -target-abi aapcs -O1 -verify=nofp-hard,nofp-hard-opt -emit-llvm %s // No run line needed for soft-float ABI with an FPU because that is rejected by the driver // With the hard-float ABI and a target with an FPU, FP arguments are passed in -- GitLab From 12329648e2c3f8651228f17d3619b1e1ddab80f0 Mon Sep 17 00:00:00 2001 From: Felipe de Azevedo Piovezan <fpiovezan@apple.com> Date: Wed, 20 Mar 2024 07:03:24 -0700 Subject: [PATCH 246/307] [lldb] Omit --show-globals in `help target var` (#85855) This option doesn't exist. It is currently displayed by `help target var` due to a bug introduced by 41ae8e7445 in 2018. Some code for `target var` and `frame var` is shared, and some hard-code constants are used in order to filter out options that belong only to `frame var`. However, the aforementioned commit failed to update these constants properly. This patch addresses the issue by having a _single_ place where the filtering of options needs to be done. --- .../Interpreter/OptionGroupVariable.cpp | 26 +++++++++---------- .../target_var/TestTargetVar.py | 10 +++++++ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/lldb/source/Interpreter/OptionGroupVariable.cpp b/lldb/source/Interpreter/OptionGroupVariable.cpp index 0e35a641361b..99644b3f423c 100644 --- a/lldb/source/Interpreter/OptionGroupVariable.cpp +++ b/lldb/source/Interpreter/OptionGroupVariable.cpp @@ -50,6 +50,11 @@ static constexpr OptionDefinition g_variable_options[] = { "Specify a summary string to use to format the variable output."}, }; +static constexpr auto g_num_frame_options = 4; +static const auto g_variable_options_noframe = + llvm::ArrayRef<OptionDefinition>(g_variable_options) + .drop_front(g_num_frame_options); + static Status ValidateNamedSummary(const char *str, void *) { if (!str || !str[0]) return Status("must specify a valid named summary"); @@ -77,9 +82,9 @@ OptionGroupVariable::SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { Status error; - if (!include_frame_options) - option_idx += 3; - const int short_option = g_variable_options[option_idx].short_option; + llvm::ArrayRef<OptionDefinition> variable_options = + include_frame_options ? g_variable_options : g_variable_options_noframe; + const int short_option = variable_options[option_idx].short_option; switch (short_option) { case 'r': use_regex = true; @@ -128,16 +133,9 @@ void OptionGroupVariable::OptionParsingStarting( summary_string.Clear(); } -#define NUM_FRAME_OPTS 3 - llvm::ArrayRef<OptionDefinition> OptionGroupVariable::GetDefinitions() { - auto result = llvm::ArrayRef(g_variable_options); - // Show the "--no-args", "--no-locals" and "--show-globals" options if we are - // showing frame specific options - if (include_frame_options) - return result; - - // Skip the "--no-args", "--no-locals" and "--show-globals" options if we are - // not showing frame specific options (globals only) - return result.drop_front(NUM_FRAME_OPTS); + // Show the "--no-args", "--no-recognized-args", "--no-locals" and + // "--show-globals" options if we are showing frame specific options + return include_frame_options ? g_variable_options + : g_variable_options_noframe; } diff --git a/lldb/test/API/functionalities/target_var/TestTargetVar.py b/lldb/test/API/functionalities/target_var/TestTargetVar.py index a0f3663f0365..54b7b77b6773 100644 --- a/lldb/test/API/functionalities/target_var/TestTargetVar.py +++ b/lldb/test/API/functionalities/target_var/TestTargetVar.py @@ -15,6 +15,16 @@ class targetCommandTestCase(TestBase): def testTargetVarExpr(self): self.build() lldbutil.run_to_name_breakpoint(self, "main") + self.expect( + "help target variable", + substrs=[ + "--no-args", + "--no-recognized-args", + "--no-locals", + "--show-globals", + ], + matching=False, + ) self.expect("target variable i", substrs=["i", "42"]) self.expect( "target variable var", patterns=["\(incomplete \*\) var = 0[xX](0)*dead"] -- GitLab From 5f5a64134b679d0b97d8fbd4ea65da361bb22cae Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Wed, 20 Mar 2024 15:08:37 +0100 Subject: [PATCH 247/307] Revert "[DAGCombiner] Simplifying `{si|ui}tofp` when only signbit is needed" This reverts commit 353fbeb0a294d2c7cef6d88607fa0fd50ee81462. It crashes when it encounters an UINT_TO_FP. llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1618 in SDValue llvm::SelectionDAG::getConstant(const ConstantInt &, const SDLoc &, EVT, bool, bool): VT.isInteger() && "Cannot create FP integer constant!" --- .../CodeGen/SelectionDAG/TargetLowering.cpp | 30 ------------------- .../CodeGen/X86/combine-sse41-intrinsics.ll | 3 +- llvm/test/CodeGen/X86/int-to-fp-demanded.ll | 21 ++++++++----- 3 files changed, 16 insertions(+), 38 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 16069c6c0dc3..57f8fc409de4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -611,25 +611,6 @@ bool TargetLowering::ShrinkDemandedOp(SDValue Op, unsigned BitWidth, return false; } -static SDValue simplifyUseOfIntToFP(SDValue Op, const APInt &DemandedBits, - SelectionDAG &DAG) { - unsigned Opc = Op.getOpcode(); - assert((Opc == ISD::SINT_TO_FP || Opc == ISD::UINT_TO_FP) && - "Invalid Int -> FP Opcode"); - if (!DemandedBits.isSignMask()) - return SDValue(); - - EVT VT = Op.getValueType(); - if (Opc == ISD::UINT_TO_FP) - return DAG.getConstant(0, SDLoc(Op), VT); - - EVT InnerVT = Op.getOperand(0).getValueType(); - if (VT.getScalarSizeInBits() == InnerVT.getScalarSizeInBits()) - return DAG.getBitcast(VT, Op.getOperand(0)); - - return SDValue(); -} - bool TargetLowering::SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; @@ -835,11 +816,6 @@ SDValue TargetLowering::SimplifyMultipleUseDemandedBits( } break; } - case ISD::UINT_TO_FP: - case ISD::SINT_TO_FP: - if (SDValue R = simplifyUseOfIntToFP(Op, DemandedBits, DAG)) - return R; - break; case ISD::SIGN_EXTEND_INREG: { // If none of the extended bits are demanded, eliminate the sextinreg. SDValue Op0 = Op.getOperand(0); @@ -2337,12 +2313,6 @@ bool TargetLowering::SimplifyDemandedBits( Known = TLO.DAG.computeKnownBits(Op, DemandedElts, Depth); break; } - case ISD::UINT_TO_FP: - case ISD::SINT_TO_FP: - if (SDValue R = simplifyUseOfIntToFP(Op, DemandedBits, TLO.DAG)) - return TLO.CombineTo(Op, R); - Known = TLO.DAG.computeKnownBits(Op, DemandedElts, Depth); - break; case ISD::SIGN_EXTEND_INREG: { SDValue Op0 = Op.getOperand(0); EVT ExVT = cast<VTSDNode>(Op.getOperand(1))->getVT(); diff --git a/llvm/test/CodeGen/X86/combine-sse41-intrinsics.ll b/llvm/test/CodeGen/X86/combine-sse41-intrinsics.ll index a332b3e89080..cbb5bd09c239 100644 --- a/llvm/test/CodeGen/X86/combine-sse41-intrinsics.ll +++ b/llvm/test/CodeGen/X86/combine-sse41-intrinsics.ll @@ -164,13 +164,14 @@ define <4 x float> @demandedbits_sitofp_blendvps(<4 x float> %a0, <4 x float> %a ; SSE-LABEL: demandedbits_sitofp_blendvps: ; SSE: # %bb.0: ; SSE-NEXT: movaps %xmm0, %xmm3 -; SSE-NEXT: movaps %xmm2, %xmm0 +; SSE-NEXT: cvtdq2ps %xmm2, %xmm0 ; SSE-NEXT: blendvps %xmm0, %xmm1, %xmm3 ; SSE-NEXT: movaps %xmm3, %xmm0 ; SSE-NEXT: retq ; ; AVX-LABEL: demandedbits_sitofp_blendvps: ; AVX: # %bb.0: +; AVX-NEXT: vcvtdq2ps %xmm2, %xmm2 ; AVX-NEXT: vblendvps %xmm2, %xmm1, %xmm0, %xmm0 ; AVX-NEXT: retq %cvt = sitofp <4 x i32> %a2 to <4 x float> diff --git a/llvm/test/CodeGen/X86/int-to-fp-demanded.ll b/llvm/test/CodeGen/X86/int-to-fp-demanded.ll index 8652136ae5cd..cdde03fb0534 100644 --- a/llvm/test/CodeGen/X86/int-to-fp-demanded.ll +++ b/llvm/test/CodeGen/X86/int-to-fp-demanded.ll @@ -7,13 +7,19 @@ declare void @use.i32(i32) define i32 @sitofp_signbit_only(i32 %i_in) nounwind { ; X86-LABEL: sitofp_signbit_only: ; X86: # %bb.0: +; X86-NEXT: subl $8, %esp +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl %eax, (%esp) +; X86-NEXT: fildl (%esp) +; X86-NEXT: fstps {{[0-9]+}}(%esp) ; X86-NEXT: movl $-2147483648, %eax # imm = 0x80000000 ; X86-NEXT: andl {{[0-9]+}}(%esp), %eax +; X86-NEXT: addl $8, %esp ; X86-NEXT: retl ; ; X64-LABEL: sitofp_signbit_only: ; X64: # %bb.0: -; X64-NEXT: movd %edi, %xmm0 +; X64-NEXT: cvtsi2ss %edi, %xmm0 ; X64-NEXT: movmskps %xmm0, %eax ; X64-NEXT: shll $31, %eax ; X64-NEXT: retq @@ -38,8 +44,8 @@ define i32 @sitofp_signbit_only_okay_width(i16 %i_in) nounwind { ; ; X64-LABEL: sitofp_signbit_only_okay_width: ; X64: # %bb.0: -; X64-NEXT: shll $16, %edi -; X64-NEXT: movd %edi, %xmm0 +; X64-NEXT: movswl %di, %eax +; X64-NEXT: cvtsi2ss %eax, %xmm0 ; X64-NEXT: movmskps %xmm0, %eax ; X64-NEXT: shll $31, %eax ; X64-NEXT: retq @@ -76,14 +82,15 @@ define <2 x i16> @sitofp_signbit_only_fail_bad_width2(i32 %i_in) nounwind { ; X86-LABEL: sitofp_signbit_only_fail_bad_width2: ; X86: # %bb.0: ; X86-NEXT: subl $8, %esp -; X86-NEXT: movl {{[0-9]+}}(%esp), %edx -; X86-NEXT: movl %edx, (%esp) +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl %eax, (%esp) ; X86-NEXT: fildl (%esp) ; X86-NEXT: fstps {{[0-9]+}}(%esp) +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl %eax, %edx ; X86-NEXT: shrl $16, %edx +; X86-NEXT: andl $32768, %eax # imm = 0x8000 ; X86-NEXT: andl $32768, %edx # imm = 0x8000 -; X86-NEXT: movl $32768, %eax # imm = 0x8000 -; X86-NEXT: andl {{[0-9]+}}(%esp), %eax ; X86-NEXT: # kill: def $ax killed $ax killed $eax ; X86-NEXT: # kill: def $dx killed $dx killed $edx ; X86-NEXT: addl $8, %esp -- GitLab From 2137894a6f5475e51c541b6d16e8902125a8f002 Mon Sep 17 00:00:00 2001 From: Guillaume Chatelet <gchatelet@google.com> Date: Wed, 20 Mar 2024 15:10:19 +0100 Subject: [PATCH 248/307] [libc][NFC] Move `Sign` type to separate header (#85930) --- libc/src/__support/CMakeLists.txt | 8 ++++ libc/src/__support/FPUtil/CMakeLists.txt | 1 + libc/src/__support/FPUtil/FPBits.h | 27 +------------ libc/src/__support/FPUtil/fpbits_str.h | 1 - libc/src/__support/sign.h | 40 +++++++++++++++++++ libc/src/__support/str_to_float.h | 4 +- libc/src/math/generic/acosf.cpp | 2 +- libc/src/math/generic/asinf.cpp | 2 +- libc/src/math/generic/atanf.cpp | 1 - libc/src/math/generic/atanhf.cpp | 2 +- libc/src/math/generic/cosf.cpp | 2 +- libc/src/math/generic/coshf.cpp | 2 +- libc/src/math/generic/exp.cpp | 2 +- libc/src/math/generic/exp10.cpp | 2 +- libc/src/math/generic/exp2.cpp | 2 +- libc/src/math/generic/expm1.cpp | 4 +- libc/src/math/generic/log.cpp | 4 +- libc/src/math/generic/log10.cpp | 4 +- libc/src/math/generic/log10f.cpp | 2 +- libc/src/math/generic/log1p.cpp | 4 +- libc/src/math/generic/log1pf.cpp | 2 +- libc/src/math/generic/log2.cpp | 4 +- libc/src/math/generic/log2f.cpp | 2 +- libc/src/math/generic/log_range_reduction.h | 1 - libc/src/math/generic/logf.cpp | 2 +- libc/src/math/generic/powf.cpp | 4 +- .../stdio/printf_core/float_dec_converter.h | 2 +- libc/test/UnitTest/FPMatcher.h | 3 +- libc/test/src/__support/FPUtil/CMakeLists.txt | 1 + .../__support/FPUtil/dyadic_float_test.cpp | 1 - .../test/src/__support/FPUtil/fpbits_test.cpp | 2 +- libc/test/src/math/FDimTest.h | 1 - libc/test/src/math/FmaTest.h | 1 - libc/test/src/math/HypotTest.h | 2 +- libc/test/src/math/ILogbTest.h | 2 +- libc/test/src/math/LdExpTest.h | 1 - libc/test/src/math/NextAfterTest.h | 1 - libc/test/src/math/RIntTest.h | 1 - libc/test/src/math/RemQuoTest.h | 1 - libc/test/src/math/RoundToIntegerTest.h | 1 - libc/test/src/math/atanhf_test.cpp | 2 +- libc/test/src/math/smoke/FDimTest.h | 1 - libc/test/src/math/smoke/FmaTest.h | 1 - libc/test/src/math/smoke/HypotTest.h | 2 +- libc/test/src/math/smoke/ILogbTest.h | 1 - libc/test/src/math/smoke/LdExpTest.h | 1 - libc/test/src/math/smoke/NextAfterTest.h | 1 - libc/test/src/math/smoke/NextTowardTest.h | 1 - libc/test/src/math/smoke/RIntTest.h | 1 - libc/test/src/math/smoke/RemQuoTest.h | 1 - libc/test/src/math/smoke/RoundToIntegerTest.h | 1 - libc/test/src/math/smoke/atanhf_test.cpp | 2 +- .../llvm-project-overlay/libc/BUILD.bazel | 9 +++++ .../test/src/__support/FPUtil/BUILD.bazel | 1 + 54 files changed, 94 insertions(+), 82 deletions(-) create mode 100644 libc/src/__support/sign.h diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt index 4c1f271e1df4..7b1820d9bf35 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -41,6 +41,14 @@ add_header_library( libc.src.__support.macros.config ) +add_header_library( + sign + HDRS + sign.h + DEPENDS + libc.src.__support.macros.attributes +) + add_header_library( error_or HDRS diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt index f1c6fba22856..4ded70a675ea 100644 --- a/libc/src/__support/FPUtil/CMakeLists.txt +++ b/libc/src/__support/FPUtil/CMakeLists.txt @@ -35,6 +35,7 @@ add_header_library( libc.src.__support.macros.attributes libc.src.__support.macros.properties.types libc.src.__support.math_extras + libc.src.__support.sign libc.src.__support.uint128 ) diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h index b06b3f7b7395..155bff2f5581 100644 --- a/libc/src/__support/FPUtil/FPBits.h +++ b/libc/src/__support/FPUtil/FPBits.h @@ -17,6 +17,7 @@ #include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR #include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_FLOAT128 #include "src/__support/math_extras.h" // mask_trailing_ones +#include "src/__support/sign.h" // Sign #include <stdint.h> @@ -32,32 +33,6 @@ enum class FPType { X86_Binary80, }; -// A type to interact with floating point type signs. -// This may be moved outside of 'fputil' if useful. -struct Sign { - LIBC_INLINE constexpr bool is_pos() const { return !is_negative; } - LIBC_INLINE constexpr bool is_neg() const { return is_negative; } - - LIBC_INLINE friend constexpr bool operator==(Sign a, Sign b) { - return a.is_negative == b.is_negative; - } - LIBC_INLINE friend constexpr bool operator!=(Sign a, Sign b) { - return !(a == b); - } - - static const Sign POS; - static const Sign NEG; - -private: - LIBC_INLINE constexpr explicit Sign(bool is_negative) - : is_negative(is_negative) {} - - bool is_negative; -}; - -LIBC_INLINE_VAR constexpr Sign Sign::NEG = Sign(true); -LIBC_INLINE_VAR constexpr Sign Sign::POS = Sign(false); - // The classes hierarchy is as follows: // // ┌───────────────────┐ diff --git a/libc/src/__support/FPUtil/fpbits_str.h b/libc/src/__support/FPUtil/fpbits_str.h index 212265bb9ad4..97689867da4d 100644 --- a/libc/src/__support/FPUtil/fpbits_str.h +++ b/libc/src/__support/FPUtil/fpbits_str.h @@ -35,7 +35,6 @@ using ZeroPaddedHexFmt = IntegerToString< // floating encoding. template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) { using StorageType = typename fputil::FPBits<T>::StorageType; - using Sign = fputil::Sign; if (x.is_nan()) return "(NaN)"; diff --git a/libc/src/__support/sign.h b/libc/src/__support/sign.h new file mode 100644 index 000000000000..28cfae4bab1d --- /dev/null +++ b/libc/src/__support/sign.h @@ -0,0 +1,40 @@ +//===-- A simple sign type --------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_SIGN_H +#define LLVM_LIBC_SRC___SUPPORT_SIGN_H + +#include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR + +// A type to interact with signed arithmetic types. +struct Sign { + LIBC_INLINE constexpr bool is_pos() const { return !is_negative; } + LIBC_INLINE constexpr bool is_neg() const { return is_negative; } + + LIBC_INLINE friend constexpr bool operator==(Sign a, Sign b) { + return a.is_negative == b.is_negative; + } + + LIBC_INLINE friend constexpr bool operator!=(Sign a, Sign b) { + return !(a == b); + } + + static const Sign POS; + static const Sign NEG; + +private: + LIBC_INLINE constexpr explicit Sign(bool is_negative) + : is_negative(is_negative) {} + + bool is_negative; +}; + +LIBC_INLINE_VAR constexpr Sign Sign::NEG = Sign(true); +LIBC_INLINE_VAR constexpr Sign Sign::POS = Sign(false); + +#endif // LLVM_LIBC_SRC___SUPPORT_SIGN_H diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h index 2cf2cfb02724..f622b7edaa8a 100644 --- a/libc/src/__support/str_to_float.h +++ b/libc/src/__support/str_to_float.h @@ -513,7 +513,6 @@ clinger_fast_path(ExpandedFloat<T> init_num, RoundDirection round = RoundDirection::Nearest) { using FPBits = typename fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = fputil::Sign; StorageType mantissa = init_num.mantissa; int32_t exp10 = init_num.exponent; @@ -1085,7 +1084,6 @@ template <class T> LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) { using FPBits = typename fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = fputil::Sign; FPBits result = FPBits(); bool seen_digit = false; @@ -1223,7 +1221,7 @@ template <class T> LIBC_INLINE StrToNumResult<T> strtonan(const char *arg) { if (arg[index] == '\0') nan_mantissa = nan_mantissa_from_ncharseq<T>(cpp::string_view(arg, index)); - result = FPBits::quiet_nan(fputil::Sign::POS, nan_mantissa); + result = FPBits::quiet_nan(Sign::POS, nan_mantissa); return {result.get_val(), 0, error}; } diff --git a/libc/src/math/generic/acosf.cpp b/libc/src/math/generic/acosf.cpp index 0c1fdbc68693..e6e28d43ef61 100644 --- a/libc/src/math/generic/acosf.cpp +++ b/libc/src/math/generic/acosf.cpp @@ -38,7 +38,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ACOSF_EXCEPTS = {{ LLVM_LIBC_FUNCTION(float, acosf, (float x)) { using FPBits = typename fputil::FPBits<float>; - using Sign = fputil::Sign; + FPBits xbits(x); uint32_t x_uint = xbits.uintval(); uint32_t x_abs = xbits.uintval() & 0x7fff'ffffU; diff --git a/libc/src/math/generic/asinf.cpp b/libc/src/math/generic/asinf.cpp index 6e3a27238ac9..d9133333d256 100644 --- a/libc/src/math/generic/asinf.cpp +++ b/libc/src/math/generic/asinf.cpp @@ -44,7 +44,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINF_EXCEPTS_HI = {{ LLVM_LIBC_FUNCTION(float, asinf, (float x)) { using FPBits = typename fputil::FPBits<float>; - using Sign = fputil::Sign; + FPBits xbits(x); uint32_t x_uint = xbits.uintval(); uint32_t x_abs = xbits.uintval() & 0x7fff'ffffU; diff --git a/libc/src/math/generic/atanf.cpp b/libc/src/math/generic/atanf.cpp index 5f66ea52d0d7..4adda429cc04 100644 --- a/libc/src/math/generic/atanf.cpp +++ b/libc/src/math/generic/atanf.cpp @@ -20,7 +20,6 @@ namespace LIBC_NAMESPACE { LLVM_LIBC_FUNCTION(float, atanf, (float x)) { using FPBits = typename fputil::FPBits<float>; - using Sign = fputil::Sign; constexpr double FINAL_SIGN[2] = {1.0, -1.0}; constexpr double SIGNED_PI_OVER_2[2] = {0x1.921fb54442d18p0, diff --git a/libc/src/math/generic/atanhf.cpp b/libc/src/math/generic/atanhf.cpp index fe2c36494a72..97fd1b233600 100644 --- a/libc/src/math/generic/atanhf.cpp +++ b/libc/src/math/generic/atanhf.cpp @@ -15,7 +15,7 @@ namespace LIBC_NAMESPACE { LLVM_LIBC_FUNCTION(float, atanhf, (float x)) { using FPBits = typename fputil::FPBits<float>; - using Sign = fputil::Sign; + FPBits xbits(x); Sign sign = xbits.sign(); uint32_t x_abs = xbits.abs().uintval(); diff --git a/libc/src/math/generic/cosf.cpp b/libc/src/math/generic/cosf.cpp index d59304933d60..180a44e947ea 100644 --- a/libc/src/math/generic/cosf.cpp +++ b/libc/src/math/generic/cosf.cpp @@ -42,7 +42,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> COSF_EXCEPTS{{ LLVM_LIBC_FUNCTION(float, cosf, (float x)) { using FPBits = typename fputil::FPBits<float>; - using Sign = fputil::Sign; + FPBits xbits(x); xbits.set_sign(Sign::POS); diff --git a/libc/src/math/generic/coshf.cpp b/libc/src/math/generic/coshf.cpp index a618056a64dc..a8ea324c9505 100644 --- a/libc/src/math/generic/coshf.cpp +++ b/libc/src/math/generic/coshf.cpp @@ -17,7 +17,7 @@ namespace LIBC_NAMESPACE { LLVM_LIBC_FUNCTION(float, coshf, (float x)) { using FPBits = typename fputil::FPBits<float>; - using Sign = fputil::Sign; + FPBits xbits(x); xbits.set_sign(Sign::POS); x = xbits.get_val(); diff --git a/libc/src/math/generic/exp.cpp b/libc/src/math/generic/exp.cpp index 42a4491131a0..3d060bcbd3be 100644 --- a/libc/src/math/generic/exp.cpp +++ b/libc/src/math/generic/exp.cpp @@ -31,7 +31,7 @@ namespace LIBC_NAMESPACE { using fputil::DoubleDouble; using fputil::TripleDouble; using Float128 = typename fputil::DyadicFloat<128>; -using Sign = fputil::Sign; + using LIBC_NAMESPACE::operator""_u128; // log2(e) diff --git a/libc/src/math/generic/exp10.cpp b/libc/src/math/generic/exp10.cpp index 72ece6697656..a4ae41407112 100644 --- a/libc/src/math/generic/exp10.cpp +++ b/libc/src/math/generic/exp10.cpp @@ -31,7 +31,7 @@ namespace LIBC_NAMESPACE { using fputil::DoubleDouble; using fputil::TripleDouble; using Float128 = typename fputil::DyadicFloat<128>; -using Sign = fputil::Sign; + using LIBC_NAMESPACE::operator""_u128; // log2(10) diff --git a/libc/src/math/generic/exp2.cpp b/libc/src/math/generic/exp2.cpp index 83f545eb116b..1a2fa3feb83e 100644 --- a/libc/src/math/generic/exp2.cpp +++ b/libc/src/math/generic/exp2.cpp @@ -31,7 +31,7 @@ namespace LIBC_NAMESPACE { using fputil::DoubleDouble; using fputil::TripleDouble; using Float128 = typename fputil::DyadicFloat<128>; -using Sign = fputil::Sign; + using LIBC_NAMESPACE::operator""_u128; // Error bounds: diff --git a/libc/src/math/generic/expm1.cpp b/libc/src/math/generic/expm1.cpp index 9f14a8c2068e..574c4b9aaf39 100644 --- a/libc/src/math/generic/expm1.cpp +++ b/libc/src/math/generic/expm1.cpp @@ -39,7 +39,7 @@ namespace LIBC_NAMESPACE { using fputil::DoubleDouble; using fputil::TripleDouble; using Float128 = typename fputil::DyadicFloat<128>; -using Sign = fputil::Sign; + using LIBC_NAMESPACE::operator""_u128; // log2(e) @@ -276,7 +276,7 @@ double set_exceptional(double x) { LLVM_LIBC_FUNCTION(double, expm1, (double x)) { using FPBits = typename fputil::FPBits<double>; - using Sign = fputil::Sign; + FPBits xbits(x); bool x_is_neg = xbits.is_neg(); diff --git a/libc/src/math/generic/log.cpp b/libc/src/math/generic/log.cpp index 339e0297560f..6de0d90be80e 100644 --- a/libc/src/math/generic/log.cpp +++ b/libc/src/math/generic/log.cpp @@ -24,7 +24,7 @@ namespace LIBC_NAMESPACE { // 128-bit precision dyadic floating point numbers. using Float128 = typename fputil::DyadicFloat<128>; -using Sign = fputil::Sign; + using LIBC_NAMESPACE::operator""_u128; namespace { @@ -735,7 +735,7 @@ double log_accurate(int e_x, int index, double m_x) { LLVM_LIBC_FUNCTION(double, log, (double x)) { using FPBits_t = typename fputil::FPBits<double>; - using Sign = fputil::Sign; + FPBits_t xbits(x); uint64_t x_u = xbits.uintval(); diff --git a/libc/src/math/generic/log10.cpp b/libc/src/math/generic/log10.cpp index c690ca287040..fb839c111e6a 100644 --- a/libc/src/math/generic/log10.cpp +++ b/libc/src/math/generic/log10.cpp @@ -24,7 +24,7 @@ namespace LIBC_NAMESPACE { // 128-bit precision dyadic floating point numbers. using Float128 = typename fputil::DyadicFloat<128>; -using Sign = fputil::Sign; + using LIBC_NAMESPACE::operator""_u128; namespace { @@ -737,7 +737,7 @@ double log10_accurate(int e_x, int index, double m_x) { LLVM_LIBC_FUNCTION(double, log10, (double x)) { using FPBits_t = typename fputil::FPBits<double>; - using Sign = fputil::Sign; + FPBits_t xbits(x); uint64_t x_u = xbits.uintval(); diff --git a/libc/src/math/generic/log10f.cpp b/libc/src/math/generic/log10f.cpp index 0216bb2133f1..1b6979d4414a 100644 --- a/libc/src/math/generic/log10f.cpp +++ b/libc/src/math/generic/log10f.cpp @@ -106,7 +106,7 @@ LLVM_LIBC_FUNCTION(float, log10f, (float x)) { constexpr double LOG10_2 = 0x1.34413509f79ffp-2; using FPBits = typename fputil::FPBits<float>; - using Sign = fputil::Sign; + FPBits xbits(x); uint32_t x_u = xbits.uintval(); diff --git a/libc/src/math/generic/log1p.cpp b/libc/src/math/generic/log1p.cpp index 26bb4d369278..83bd753cde5d 100644 --- a/libc/src/math/generic/log1p.cpp +++ b/libc/src/math/generic/log1p.cpp @@ -23,7 +23,7 @@ namespace LIBC_NAMESPACE { // 128-bit precision dyadic floating point numbers. using Float128 = typename fputil::DyadicFloat<128>; -using Sign = fputil::Sign; + using LIBC_NAMESPACE::operator""_u128; namespace { @@ -877,7 +877,7 @@ LIBC_INLINE double log1p_accurate(int e_x, int index, LLVM_LIBC_FUNCTION(double, log1p, (double x)) { using FPBits_t = typename fputil::FPBits<double>; - using Sign = fputil::Sign; + constexpr int EXP_BIAS = FPBits_t::EXP_BIAS; constexpr int FRACTION_LEN = FPBits_t::FRACTION_LEN; constexpr uint64_t FRACTION_MASK = FPBits_t::FRACTION_MASK; diff --git a/libc/src/math/generic/log1pf.cpp b/libc/src/math/generic/log1pf.cpp index 28426a88e649..e3c7d95418b1 100644 --- a/libc/src/math/generic/log1pf.cpp +++ b/libc/src/math/generic/log1pf.cpp @@ -106,7 +106,7 @@ LLVM_LIBC_FUNCTION(float, log1pf, (float x)) { case 0xbf800000U: // x = -1.0 fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_DIVBYZERO); - return FPBits::inf(fputil::Sign::NEG).get_val(); + return FPBits::inf(Sign::NEG).get_val(); #ifndef LIBC_TARGET_CPU_HAS_FMA case 0x4cc1c80bU: // x = 0x1.839016p+26f return fputil::round_result_slightly_down(0x1.26fc04p+4f); diff --git a/libc/src/math/generic/log2.cpp b/libc/src/math/generic/log2.cpp index 648850b80b04..c68bc60e8468 100644 --- a/libc/src/math/generic/log2.cpp +++ b/libc/src/math/generic/log2.cpp @@ -24,7 +24,7 @@ namespace LIBC_NAMESPACE { // 128-bit precision dyadic floating point numbers. using Float128 = typename fputil::DyadicFloat<128>; -using Sign = fputil::Sign; + using LIBC_NAMESPACE::operator""_u128; namespace { @@ -857,7 +857,7 @@ double log2_accurate(int e_x, int index, double m_x) { LLVM_LIBC_FUNCTION(double, log2, (double x)) { using FPBits_t = typename fputil::FPBits<double>; - using Sign = fputil::Sign; + FPBits_t xbits(x); uint64_t x_u = xbits.uintval(); diff --git a/libc/src/math/generic/log2f.cpp b/libc/src/math/generic/log2f.cpp index 8651316d282c..c9f7b2121519 100644 --- a/libc/src/math/generic/log2f.cpp +++ b/libc/src/math/generic/log2f.cpp @@ -55,7 +55,7 @@ namespace LIBC_NAMESPACE { LLVM_LIBC_FUNCTION(float, log2f, (float x)) { using FPBits = typename fputil::FPBits<float>; - using Sign = fputil::Sign; + FPBits xbits(x); uint32_t x_u = xbits.uintval(); diff --git a/libc/src/math/generic/log_range_reduction.h b/libc/src/math/generic/log_range_reduction.h index 8c9b7d2eabeb..64c0fc3aa4f5 100644 --- a/libc/src/math/generic/log_range_reduction.h +++ b/libc/src/math/generic/log_range_reduction.h @@ -37,7 +37,6 @@ log_range_reduction(double m_x, const LogRR &log_table, fputil::DyadicFloat<128> &sum) { using Float128 = typename fputil::DyadicFloat<128>; using MType = typename Float128::MantissaType; - using Sign = fputil::Sign; int64_t v = static_cast<int64_t>(m_x * 0x1.0p60); // ulp = 2^-60 diff --git a/libc/src/math/generic/logf.cpp b/libc/src/math/generic/logf.cpp index 49d258ecc133..5296ba6bc13c 100644 --- a/libc/src/math/generic/logf.cpp +++ b/libc/src/math/generic/logf.cpp @@ -54,7 +54,7 @@ namespace LIBC_NAMESPACE { LLVM_LIBC_FUNCTION(float, logf, (float x)) { constexpr double LOG_2 = 0x1.62e42fefa39efp-1; using FPBits = typename fputil::FPBits<float>; - using Sign = fputil::Sign; + FPBits xbits(x); uint32_t x_u = xbits.uintval(); diff --git a/libc/src/math/generic/powf.cpp b/libc/src/math/generic/powf.cpp index 2c666bab6d62..0450ffd711ff 100644 --- a/libc/src/math/generic/powf.cpp +++ b/libc/src/math/generic/powf.cpp @@ -424,7 +424,7 @@ LIBC_INLINE bool larger_exponent(double a, double b) { double powf_double_double(int idx_x, double dx, double y6, double lo6_hi, const DoubleDouble &exp2_hi_mid) { using DoubleBits = typename fputil::FPBits<double>; - using Sign = fputil::Sign; + // Perform a second range reduction step: // idx2 = round(2^14 * (dx + 2^-8)) = round ( dx * 2^14 + 2^6) // dx2 = (1 + dx) * r2 - 1 @@ -513,7 +513,7 @@ double powf_double_double(int idx_x, double dx, double y6, double lo6_hi, LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) { using FloatBits = typename fputil::FPBits<float>; using DoubleBits = typename fputil::FPBits<double>; - using Sign = fputil::Sign; + FloatBits xbits(x), ybits(y); uint32_t x_u = xbits.uintval(); diff --git a/libc/src/stdio/printf_core/float_dec_converter.h b/libc/src/stdio/printf_core/float_dec_converter.h index 5270fc9de037..c4e8aaa2f0e2 100644 --- a/libc/src/stdio/printf_core/float_dec_converter.h +++ b/libc/src/stdio/printf_core/float_dec_converter.h @@ -48,7 +48,7 @@ constexpr uint32_t MAX_BLOCK = 999999999; constexpr char DECIMAL_POINT = '.'; LIBC_INLINE RoundDirection get_round_direction(int last_digit, bool truncated, - fputil::Sign sign) { + Sign sign) { switch (fputil::quick_get_round()) { case FE_TONEAREST: // Round to nearest, if it's exactly halfway then round to even. diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h index 43000efa09a3..ee618a623efe 100644 --- a/libc/test/UnitTest/FPMatcher.h +++ b/libc/test/UnitTest/FPMatcher.h @@ -63,7 +63,6 @@ template <TestCond C, typename T> FPMatcher<T, C> getMatcher(T expectedValue) { template <typename T> struct FPTest : public Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; static constexpr StorageType STORAGE_MAX = LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::max(); static constexpr T zero = FPBits::zero(Sign::POS).get_val(); @@ -92,7 +91,7 @@ template <typename T> struct FPTest : public Test { #define DECLARE_SPECIAL_CONSTANTS(T) \ using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; \ using StorageType = typename FPBits::StorageType; \ - using Sign = LIBC_NAMESPACE::fputil::Sign; \ + \ static constexpr StorageType STORAGE_MAX = \ LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::max(); \ const T zero = FPBits::zero(Sign::POS).get_val(); \ diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt index f1a027a514ba..1cbeec0cc4eb 100644 --- a/libc/test/src/__support/FPUtil/CMakeLists.txt +++ b/libc/test/src/__support/FPUtil/CMakeLists.txt @@ -24,6 +24,7 @@ add_libc_test( libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.fpbits_str libc.src.__support.integer_literals + libc.src.__support.sign ) add_fp_unittest( diff --git a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp index 625aa70973b9..5ee9aaad5638 100644 --- a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp +++ b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp @@ -15,7 +15,6 @@ using Float128 = LIBC_NAMESPACE::fputil::DyadicFloat<128>; using Float192 = LIBC_NAMESPACE::fputil::DyadicFloat<192>; using Float256 = LIBC_NAMESPACE::fputil::DyadicFloat<256>; -using Sign = LIBC_NAMESPACE::fputil::Sign; TEST(LlvmLibcDyadicFloatTest, BasicConversions) { Float128 x(Sign::POS, /*exponent*/ 0, diff --git a/libc/test/src/__support/FPUtil/fpbits_test.cpp b/libc/test/src/__support/FPUtil/fpbits_test.cpp index f5c27d4fc030..af20b1a0bdc7 100644 --- a/libc/test/src/__support/FPUtil/fpbits_test.cpp +++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp @@ -9,11 +9,11 @@ #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/fpbits_str.h" #include "src/__support/integer_literals.h" +#include "src/__support/sign.h" // Sign #include "test/UnitTest/Test.h" using LIBC_NAMESPACE::fputil::FPBits; using LIBC_NAMESPACE::fputil::FPType; -using LIBC_NAMESPACE::fputil::Sign; using LIBC_NAMESPACE::fputil::internal::FPRep; using LIBC_NAMESPACE::operator""_u16; diff --git a/libc/test/src/math/FDimTest.h b/libc/test/src/math/FDimTest.h index 76f0f18bbc68..df8de91b4298 100644 --- a/libc/test/src/math/FDimTest.h +++ b/libc/test/src/math/FDimTest.h @@ -18,7 +18,6 @@ public: using FuncPtr = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/FmaTest.h b/libc/test/src/math/FmaTest.h index 34c582c18242..0c93ec858a12 100644 --- a/libc/test/src/math/FmaTest.h +++ b/libc/test/src/math/FmaTest.h @@ -23,7 +23,6 @@ private: using Func = T (*)(T, T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T min_subnormal = FPBits::min_subnormal(Sign::POS).get_val(); const T min_normal = FPBits::min_normal(Sign::POS).get_val(); diff --git a/libc/test/src/math/HypotTest.h b/libc/test/src/math/HypotTest.h index 46fcc462a279..df69965d5dbc 100644 --- a/libc/test/src/math/HypotTest.h +++ b/libc/test/src/math/HypotTest.h @@ -23,7 +23,7 @@ class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test { private: using Func = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; - using Sign = LIBC_NAMESPACE::fputil::Sign; + using StorageType = typename FPBits::StorageType; const T nan = FPBits::quiet_nan().get_val(); const T inf = FPBits::inf().get_val(); diff --git a/libc/test/src/math/ILogbTest.h b/libc/test/src/math/ILogbTest.h index dcc9d554eb3c..ad47b9bb3961 100644 --- a/libc/test/src/math/ILogbTest.h +++ b/libc/test/src/math/ILogbTest.h @@ -24,7 +24,7 @@ public: template <typename T> void test_special_numbers(typename ILogbFunc<T>::Func func) { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; - using Sign = LIBC_NAMESPACE::fputil::Sign; + EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::POS).get_val())); EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::NEG).get_val())); EXPECT_EQ(FP_ILOGBNAN, func(FPBits::quiet_nan().get_val())); diff --git a/libc/test/src/math/LdExpTest.h b/libc/test/src/math/LdExpTest.h index 738135d6afe2..8bfd022973b4 100644 --- a/libc/test/src/math/LdExpTest.h +++ b/libc/test/src/math/LdExpTest.h @@ -23,7 +23,6 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/NextAfterTest.h b/libc/test/src/math/NextAfterTest.h index d45d819bfdb6..05803fb45ee2 100644 --- a/libc/test/src/math/NextAfterTest.h +++ b/libc/test/src/math/NextAfterTest.h @@ -21,7 +21,6 @@ template <typename T> class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/RIntTest.h b/libc/test/src/math/RIntTest.h index d392d4fb14a2..301655c64ed3 100644 --- a/libc/test/src/math/RIntTest.h +++ b/libc/test/src/math/RIntTest.h @@ -32,7 +32,6 @@ public: private: using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/RemQuoTest.h b/libc/test/src/math/RemQuoTest.h index d61b97554199..1cb8cdbe81a2 100644 --- a/libc/test/src/math/RemQuoTest.h +++ b/libc/test/src/math/RemQuoTest.h @@ -22,7 +22,6 @@ template <typename T> class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h index 017f5867fc8d..d2fabd0b4c9c 100644 --- a/libc/test/src/math/RoundToIntegerTest.h +++ b/libc/test/src/math/RoundToIntegerTest.h @@ -31,7 +31,6 @@ public: private: using FPBits = LIBC_NAMESPACE::fputil::FPBits<F>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const F zero = FPBits::zero().get_val(); const F neg_zero = FPBits::zero(Sign::NEG).get_val(); diff --git a/libc/test/src/math/atanhf_test.cpp b/libc/test/src/math/atanhf_test.cpp index 39c067f3e764..c659f17d13b0 100644 --- a/libc/test/src/math/atanhf_test.cpp +++ b/libc/test/src/math/atanhf_test.cpp @@ -22,7 +22,7 @@ using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>; namespace mpfr = LIBC_NAMESPACE::testing::mpfr; TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) { - using Sign = LIBC_NAMESPACE::fputil::Sign; + LIBC_NAMESPACE::libc_errno = 0; LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN)); diff --git a/libc/test/src/math/smoke/FDimTest.h b/libc/test/src/math/smoke/FDimTest.h index 5cb3dd117348..e557b40d90ef 100644 --- a/libc/test/src/math/smoke/FDimTest.h +++ b/libc/test/src/math/smoke/FDimTest.h @@ -17,7 +17,6 @@ public: using FuncPtr = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/smoke/FmaTest.h b/libc/test/src/math/smoke/FmaTest.h index d04f648c2d7d..c66035927d98 100644 --- a/libc/test/src/math/smoke/FmaTest.h +++ b/libc/test/src/math/smoke/FmaTest.h @@ -19,7 +19,6 @@ private: using Func = T (*)(T, T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/smoke/HypotTest.h b/libc/test/src/math/smoke/HypotTest.h index 43499267b711..80816033f28f 100644 --- a/libc/test/src/math/smoke/HypotTest.h +++ b/libc/test/src/math/smoke/HypotTest.h @@ -21,7 +21,7 @@ private: using Func = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; + const T nan = FPBits::quiet_nan().get_val(); const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/smoke/ILogbTest.h b/libc/test/src/math/smoke/ILogbTest.h index cbee25b139d4..bb5bc33b6b3a 100644 --- a/libc/test/src/math/smoke/ILogbTest.h +++ b/libc/test/src/math/smoke/ILogbTest.h @@ -18,7 +18,6 @@ template <typename OutType, typename InType> class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits<InType>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; public: typedef OutType (*Func)(InType); diff --git a/libc/test/src/math/smoke/LdExpTest.h b/libc/test/src/math/smoke/LdExpTest.h index 7d17071f5b30..c3e852a2a473 100644 --- a/libc/test/src/math/smoke/LdExpTest.h +++ b/libc/test/src/math/smoke/LdExpTest.h @@ -22,7 +22,6 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/smoke/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h index 23b3b1534740..403ea6bd8df6 100644 --- a/libc/test/src/math/smoke/NextAfterTest.h +++ b/libc/test/src/math/smoke/NextAfterTest.h @@ -32,7 +32,6 @@ template <typename T> class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/smoke/NextTowardTest.h b/libc/test/src/math/smoke/NextTowardTest.h index caf98262c5d1..0c2abf815c23 100644 --- a/libc/test/src/math/smoke/NextTowardTest.h +++ b/libc/test/src/math/smoke/NextTowardTest.h @@ -34,7 +34,6 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using ToFPBits = LIBC_NAMESPACE::fputil::FPBits<long double>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/smoke/RIntTest.h b/libc/test/src/math/smoke/RIntTest.h index 903fbe9ce343..5a283a8bc0b5 100644 --- a/libc/test/src/math/smoke/RIntTest.h +++ b/libc/test/src/math/smoke/RIntTest.h @@ -29,7 +29,6 @@ public: private: using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/smoke/RemQuoTest.h b/libc/test/src/math/smoke/RemQuoTest.h index a9fa405b2700..cf56b1d6460f 100644 --- a/libc/test/src/math/smoke/RemQuoTest.h +++ b/libc/test/src/math/smoke/RemQuoTest.h @@ -19,7 +19,6 @@ template <typename T> class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const T inf = FPBits::inf(Sign::POS).get_val(); const T neg_inf = FPBits::inf(Sign::NEG).get_val(); diff --git a/libc/test/src/math/smoke/RoundToIntegerTest.h b/libc/test/src/math/smoke/RoundToIntegerTest.h index 1b5135d016cc..44b3f8996df5 100644 --- a/libc/test/src/math/smoke/RoundToIntegerTest.h +++ b/libc/test/src/math/smoke/RoundToIntegerTest.h @@ -28,7 +28,6 @@ public: private: using FPBits = LIBC_NAMESPACE::fputil::FPBits<F>; using StorageType = typename FPBits::StorageType; - using Sign = LIBC_NAMESPACE::fputil::Sign; const F zero = FPBits::zero(Sign::POS).get_val(); const F neg_zero = FPBits::zero(Sign::NEG).get_val(); diff --git a/libc/test/src/math/smoke/atanhf_test.cpp b/libc/test/src/math/smoke/atanhf_test.cpp index df0746e0c9c3..590a7ab60f04 100644 --- a/libc/test/src/math/smoke/atanhf_test.cpp +++ b/libc/test/src/math/smoke/atanhf_test.cpp @@ -19,7 +19,7 @@ using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>; TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) { - using Sign = LIBC_NAMESPACE::fputil::Sign; + LIBC_NAMESPACE::libc_errno = 0; LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 59b0bbbda2f5..c4f6eab06221 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -501,6 +501,14 @@ libc_support_library( ], ) +libc_support_library( + name = "__support_sign", + hdrs = ["src/__support/sign.h"], + deps = [ + ":__support_macros_properties_types", + ], +) + libc_support_library( name = "__support_uint128", hdrs = ["src/__support/UInt128.h"], @@ -734,6 +742,7 @@ libc_support_library( deps = [ ":__support_common", ":__support_cpp_bit", + ":__support_sign", ":__support_cpp_type_traits", ":__support_libc_assert", ":__support_macros_attributes", diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/__support/FPUtil/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/__support/FPUtil/BUILD.bazel index 76443fc5d9f8..18683e42724a 100644 --- a/utils/bazel/llvm-project-overlay/libc/test/src/__support/FPUtil/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/src/__support/FPUtil/BUILD.bazel @@ -17,6 +17,7 @@ libc_test( "//libc:__support_fputil_fp_bits", "//libc:__support_fputil_fpbits_str", "//libc:__support_integer_literals", + "//libc:__support_sign", ], ) -- GitLab From f872043e055f4163c3c4b1b86ca0354490174987 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Wed, 20 Mar 2024 15:12:33 +0100 Subject: [PATCH 249/307] Revert "[VPlan] Replace disjoint or with add instead of dropping disjoint. (#83821)" This reverts commit c2c1e6ee4ce0df3d000ba880fa6cf58441da6462. It creates a use after free. ==8342==ERROR: AddressSanitizer: heap-use-after-free on address 0x50f000001760 at pc 0x55b9fb84a8fb bp 0x7ffc18468a10 sp 0x7ffc18468a08 READ of size 1 at 0x50f000001760 thread T0 #0 0x55b9fb84a8fa in dropPoisonGeneratingFlags llvm/lib/Transforms/Vectorize/VPlan.h:1040:13 #1 0x55b9fb84a8fa in llvm::VPlanTransforms::dropPoisonGeneratingRecipes(llvm::VPlan&, llvm::function_ref<bool (llvm::BasicBlock*)>)::$_0::operator()(llvm::VPRecipeBase*) const llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:1236:23 #2 0x55b9fb84a196 in llvm::VPlanTransforms::dropPoisonGeneratingRecipes(llvm::VPlan&, llvm::function_ref<bool (llvm::BasicBlock*)>) llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp Can be reproduced with asan on Transforms/LoopVectorize/AArch64/sve-interleaved-masked-accesses.ll Transforms/LoopVectorize/X86/pr81872.ll Transforms/LoopVectorize/X86/x86-interleaved-accesses-masked-group.ll --- .../Vectorize/LoopVectorizationPlanner.h | 3 --- llvm/lib/Transforms/Vectorize/VPlan.h | 6 ------ .../Transforms/Vectorize/VPlanPatternMatch.h | 5 ----- .../Transforms/Vectorize/VPlanTransforms.cpp | 17 ----------------- .../Transforms/LoopVectorize/X86/pr81872.ll | 2 +- 5 files changed, 1 insertion(+), 32 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h index 5d03b66b0ce3..e86705e89889 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h +++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h @@ -68,9 +68,6 @@ class VPBuilder { public: VPBuilder() = default; VPBuilder(VPBasicBlock *InsertBB) { setInsertPoint(InsertBB); } - VPBuilder(VPRecipeBase *InsertPt) { - setInsertPoint(InsertPt->getParent(), InsertPt->getIterator()); - } /// Clear the insertion point: created instructions will not be inserted into /// a block. diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index d720f17a3a88..d77c7554d50e 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1127,12 +1127,6 @@ public: return WrapFlags.HasNSW; } - bool isDisjoint() const { - assert(OpType == OperationType::DisjointOp && - "recipe cannot have a disjoing flag"); - return DisjointFlags.IsDisjoint; - } - #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void printFlags(raw_ostream &O) const; #endif diff --git a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h index a03a408686ef..aa2535906945 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h +++ b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h @@ -261,11 +261,6 @@ m_Mul(const Op0_t &Op0, const Op1_t &Op1) { return m_Binary<Instruction::Mul, Op0_t, Op1_t>(Op0, Op1); } -template <typename Op0_t, typename Op1_t> -inline AllBinaryRecipe_match<Op0_t, Op1_t, Instruction::Or> -m_Or(const Op0_t &Op0, const Op1_t &Op1) { - return m_Binary<Instruction::Or, Op0_t, Op1_t>(Op0, Op1); -} } // namespace VPlanPatternMatch } // namespace llvm diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index c6ec99fbbf0a..a91ccefe4b6d 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -1216,23 +1216,6 @@ void VPlanTransforms::dropPoisonGeneratingRecipes( // load/store. If the underlying instruction has poison-generating flags, // drop them directly. if (auto *RecWithFlags = dyn_cast<VPRecipeWithIRFlags>(CurRec)) { - VPValue *A, *B; - using namespace llvm::VPlanPatternMatch; - // Dropping disjoint from an OR may yield incorrect results, as some - // analysis may have converted it to an Add implicitly (e.g. SCEV used - // for dependence analysis). Instead, replace it with an equivalent Add. - // This is possible as all users of the disjoint OR only access lanes - // where the operands are disjoint or poison otherwise. - if (match(RecWithFlags, m_Or(m_VPValue(A), m_VPValue(B))) && - RecWithFlags->isDisjoint()) { - VPBuilder Builder(RecWithFlags); - VPInstruction *New = Builder.createOverflowingOp( - Instruction::Add, {A, B}, {false, false}, - RecWithFlags->getDebugLoc()); - RecWithFlags->replaceAllUsesWith(New); - RecWithFlags->eraseFromParent(); - CurRec = New; - } RecWithFlags->dropPoisonGeneratingFlags(); } else { Instruction *Instr = dyn_cast_or_null<Instruction>( diff --git a/llvm/test/Transforms/LoopVectorize/X86/pr81872.ll b/llvm/test/Transforms/LoopVectorize/X86/pr81872.ll index 3f38abc75a58..14acb6f57aa0 100644 --- a/llvm/test/Transforms/LoopVectorize/X86/pr81872.ll +++ b/llvm/test/Transforms/LoopVectorize/X86/pr81872.ll @@ -29,7 +29,7 @@ define void @test(ptr noundef align 8 dereferenceable_or_null(16) %arr) #0 { ; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i64> [[VEC_IND]], <i64 1, i64 1, i64 1, i64 1> ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq <4 x i64> [[TMP2]], zeroinitializer ; CHECK-NEXT: [[TMP4:%.*]] = select <4 x i1> [[TMP1]], <4 x i1> [[TMP3]], <4 x i1> zeroinitializer -; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[TMP0]], 1 +; CHECK-NEXT: [[TMP5:%.*]] = or i64 [[TMP0]], 1 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i64, ptr [[ARR]], i64 [[TMP5]] ; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i64, ptr [[TMP6]], i32 0 ; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i64, ptr [[TMP7]], i32 -3 -- GitLab From 9f168591f36952d8cca543a5ba67906dc07096ff Mon Sep 17 00:00:00 2001 From: Cyndy Ishida <cyndy_ishida@apple.com> Date: Wed, 20 Mar 2024 07:26:08 -0700 Subject: [PATCH 250/307] [InstallAPI] Simplify & improve symbol printing for diagnostics (#85894) * Defer mangling of symbols until an error is ready to report * Pass around fewer parameters when reporting --- .../include/clang/InstallAPI/DylibVerifier.h | 4 + clang/include/clang/InstallAPI/MachO.h | 2 + clang/lib/InstallAPI/DylibVerifier.cpp | 134 +++++++++--------- clang/test/InstallAPI/diagnostics-cpp.test | 4 +- 4 files changed, 73 insertions(+), 71 deletions(-) diff --git a/clang/include/clang/InstallAPI/DylibVerifier.h b/clang/include/clang/InstallAPI/DylibVerifier.h index 8269715c7f23..bbfa8711313e 100644 --- a/clang/include/clang/InstallAPI/DylibVerifier.h +++ b/clang/include/clang/InstallAPI/DylibVerifier.h @@ -128,6 +128,10 @@ private: /// Find matching dylib slice for target triple that is being parsed. void assignSlice(const Target &T); + /// Gather annotations for symbol for error reporting. + std::string getAnnotatedName(const Record *R, SymbolContext &SymCtx, + bool ValidSourceLoc = true); + // Symbols in dylib. llvm::MachO::Records Dylib; diff --git a/clang/include/clang/InstallAPI/MachO.h b/clang/include/clang/InstallAPI/MachO.h index a77766511fa3..f0dea8bbd24c 100644 --- a/clang/include/clang/InstallAPI/MachO.h +++ b/clang/include/clang/InstallAPI/MachO.h @@ -26,11 +26,13 @@ using SymbolFlags = llvm::MachO::SymbolFlags; using RecordLinkage = llvm::MachO::RecordLinkage; using Record = llvm::MachO::Record; +using EncodeKind = llvm::MachO::EncodeKind; using GlobalRecord = llvm::MachO::GlobalRecord; using ObjCContainerRecord = llvm::MachO::ObjCContainerRecord; using ObjCInterfaceRecord = llvm::MachO::ObjCInterfaceRecord; using ObjCCategoryRecord = llvm::MachO::ObjCCategoryRecord; using ObjCIVarRecord = llvm::MachO::ObjCIVarRecord; +using ObjCIFSymbolKind = llvm::MachO::ObjCIFSymbolKind; using Records = llvm::MachO::Records; using RecordsSlice = llvm::MachO::RecordsSlice; using BinaryAttrs = llvm::MachO::RecordsSlice::BinaryAttrs; diff --git a/clang/lib/InstallAPI/DylibVerifier.cpp b/clang/lib/InstallAPI/DylibVerifier.cpp index 700763b3fee0..24e0d0addf2f 100644 --- a/clang/lib/InstallAPI/DylibVerifier.cpp +++ b/clang/lib/InstallAPI/DylibVerifier.cpp @@ -10,9 +10,6 @@ namespace installapi { /// Metadata stored about a mapping of a declaration to a symbol. struct DylibVerifier::SymbolContext { - // Name to use for printing in diagnostics. - std::string PrettyPrintName{""}; - // Name to use for all querying and verification // purposes. std::string SymbolName{""}; @@ -30,11 +27,35 @@ struct DylibVerifier::SymbolContext { bool Inlined = false; }; -static std::string -getAnnotatedName(const Record *R, EncodeKind Kind, StringRef Name, - bool ValidSourceLoc = true, - ObjCIFSymbolKind ObjCIF = ObjCIFSymbolKind::None) { - assert(!Name.empty() && "Need symbol name for printing"); +static bool isCppMangled(StringRef Name) { + // InstallAPI currently only supports itanium manglings. + return (Name.starts_with("_Z") || Name.starts_with("__Z") || + Name.starts_with("___Z")); +} + +static std::string demangle(StringRef Name) { + // InstallAPI currently only supports itanium manglings. + if (!isCppMangled(Name)) + return Name.str(); + char *Result = llvm::itaniumDemangle(Name); + if (!Result) + return Name.str(); + + std::string Demangled(Result); + free(Result); + return Demangled; +} + +std::string DylibVerifier::getAnnotatedName(const Record *R, + SymbolContext &SymCtx, + bool ValidSourceLoc) { + assert(!SymCtx.SymbolName.empty() && "Expected symbol name"); + + const StringRef SymbolName = SymCtx.SymbolName; + std::string PrettyName = + (Demangle && (SymCtx.Kind == EncodeKind::GlobalSymbol)) + ? demangle(SymbolName) + : SymbolName.str(); std::string Annotation; if (R->isWeakDefined()) @@ -45,15 +66,16 @@ getAnnotatedName(const Record *R, EncodeKind Kind, StringRef Name, Annotation += "(tlv) "; // Check if symbol represents only part of a @interface declaration. - const bool IsAnnotatedObjCClass = ((ObjCIF != ObjCIFSymbolKind::None) && - (ObjCIF <= ObjCIFSymbolKind::EHType)); + const bool IsAnnotatedObjCClass = + ((SymCtx.ObjCIFKind != ObjCIFSymbolKind::None) && + (SymCtx.ObjCIFKind <= ObjCIFSymbolKind::EHType)); if (IsAnnotatedObjCClass) { - if (ObjCIF == ObjCIFSymbolKind::EHType) + if (SymCtx.ObjCIFKind == ObjCIFSymbolKind::EHType) Annotation += "Exception Type of "; - if (ObjCIF == ObjCIFSymbolKind::MetaClass) + if (SymCtx.ObjCIFKind == ObjCIFSymbolKind::MetaClass) Annotation += "Metaclass of "; - if (ObjCIF == ObjCIFSymbolKind::Class) + if (SymCtx.ObjCIFKind == ObjCIFSymbolKind::Class) Annotation += "Class of "; } @@ -61,42 +83,30 @@ getAnnotatedName(const Record *R, EncodeKind Kind, StringRef Name, // tied to it. This can only ever happen when the location has to come from // debug info. if (ValidSourceLoc) { - if ((Kind == EncodeKind::GlobalSymbol) && Name.starts_with("_")) - return Annotation + Name.drop_front(1).str(); - return Annotation + Name.str(); + StringRef PrettyNameRef(PrettyName); + if ((SymCtx.Kind == EncodeKind::GlobalSymbol) && + !isCppMangled(SymbolName) && PrettyNameRef.starts_with("_")) + return Annotation + PrettyNameRef.drop_front(1).str(); + return Annotation + PrettyName; } if (IsAnnotatedObjCClass) - return Annotation + Name.str(); + return Annotation + PrettyName; - switch (Kind) { + switch (SymCtx.Kind) { case EncodeKind::GlobalSymbol: - return Annotation + Name.str(); + return Annotation + PrettyName; case EncodeKind::ObjectiveCInstanceVariable: - return Annotation + "(ObjC IVar) " + Name.str(); + return Annotation + "(ObjC IVar) " + PrettyName; case EncodeKind::ObjectiveCClass: - return Annotation + "(ObjC Class) " + Name.str(); + return Annotation + "(ObjC Class) " + PrettyName; case EncodeKind::ObjectiveCClassEHType: - return Annotation + "(ObjC Class EH) " + Name.str(); + return Annotation + "(ObjC Class EH) " + PrettyName; } llvm_unreachable("unexpected case for EncodeKind"); } -static std::string demangle(StringRef Name) { - // InstallAPI currently only supports itanium manglings. - if (!(Name.starts_with("_Z") || Name.starts_with("__Z") || - Name.starts_with("___Z"))) - return Name.str(); - char *Result = llvm::itaniumDemangle(Name); - if (!Result) - return Name.str(); - - std::string Demangled(Result); - free(Result); - return Demangled; -} - static DylibVerifier::Result updateResult(const DylibVerifier::Result Prev, const DylibVerifier::Result Curr) { if (Prev == Curr) @@ -193,19 +203,18 @@ bool DylibVerifier::compareObjCInterfaceSymbols(const Record *R, // The decl represents a complete ObjCInterface, but the symbols in the // dylib do not. Determine which symbol is missing. To keep older projects // building, treat this as a warning. - if (!DR->isExportedSymbol(ObjCIFSymbolKind::Class)) + if (!DR->isExportedSymbol(ObjCIFSymbolKind::Class)) { + SymCtx.ObjCIFKind = ObjCIFSymbolKind::Class; PrintDiagnostic(DR->getLinkageForSymbol(ObjCIFSymbolKind::Class), R, - getAnnotatedName(R, SymCtx.Kind, SymCtx.PrettyPrintName, - /*ValidSourceLoc=*/true, - ObjCIFSymbolKind::Class), + getAnnotatedName(R, SymCtx), /*PrintAsWarning=*/true); - - if (!DR->isExportedSymbol(ObjCIFSymbolKind::MetaClass)) + } + if (!DR->isExportedSymbol(ObjCIFSymbolKind::MetaClass)) { + SymCtx.ObjCIFKind = ObjCIFSymbolKind::MetaClass; PrintDiagnostic(DR->getLinkageForSymbol(ObjCIFSymbolKind::MetaClass), R, - getAnnotatedName(R, SymCtx.Kind, SymCtx.PrettyPrintName, - /*ValidSourceLoc=*/true, - ObjCIFSymbolKind::MetaClass), + getAnnotatedName(R, SymCtx), /*PrintAsWarning=*/true); + } return true; } @@ -221,7 +230,7 @@ bool DylibVerifier::compareObjCInterfaceSymbols(const Record *R, // At this point that means there was not a matching class symbol // to represent the one discovered as a declaration. PrintDiagnostic(DR->getLinkageForSymbol(SymCtx.ObjCIFKind), R, - SymCtx.PrettyPrintName); + SymCtx.SymbolName); return false; } @@ -234,7 +243,7 @@ DylibVerifier::Result DylibVerifier::compareVisibility(const Record *R, Ctx.emitDiag([&]() { Ctx.Diag->Report(SymCtx.FA->D->getLocation(), diag::err_library_missing_symbol) - << SymCtx.PrettyPrintName; + << getAnnotatedName(R, SymCtx); }); return Result::Invalid; } @@ -242,7 +251,7 @@ DylibVerifier::Result DylibVerifier::compareVisibility(const Record *R, Ctx.emitDiag([&]() { Ctx.Diag->Report(SymCtx.FA->D->getLocation(), diag::err_library_hidden_symbol) - << SymCtx.PrettyPrintName; + << getAnnotatedName(R, SymCtx); }); return Result::Invalid; } @@ -269,7 +278,7 @@ DylibVerifier::Result DylibVerifier::compareVisibility(const Record *R, } Ctx.emitDiag([&]() { Ctx.Diag->Report(SymCtx.FA->D->getLocation(), ID) - << SymCtx.PrettyPrintName; + << getAnnotatedName(R, SymCtx); }); return Outcome; } @@ -293,14 +302,14 @@ DylibVerifier::Result DylibVerifier::compareAvailability(const Record *R, Ctx.emitDiag([&]() { Ctx.Diag->Report(SymCtx.FA->D->getLocation(), diag::warn_header_availability_mismatch) - << SymCtx.PrettyPrintName << IsDeclAvailable << IsDeclAvailable; + << getAnnotatedName(R, SymCtx) << IsDeclAvailable << IsDeclAvailable; }); return Result::Ignore; case VerificationMode::Pedantic: Ctx.emitDiag([&]() { Ctx.Diag->Report(SymCtx.FA->D->getLocation(), diag::err_header_availability_mismatch) - << SymCtx.PrettyPrintName << IsDeclAvailable << IsDeclAvailable; + << getAnnotatedName(R, SymCtx) << IsDeclAvailable << IsDeclAvailable; }); return Result::Invalid; case VerificationMode::ErrorsOnly: @@ -313,15 +322,11 @@ DylibVerifier::Result DylibVerifier::compareAvailability(const Record *R, bool DylibVerifier::compareSymbolFlags(const Record *R, SymbolContext &SymCtx, const Record *DR) { - std::string DisplayName = - Demangle ? demangle(DR->getName()) : DR->getName().str(); - if (DR->isThreadLocalValue() && !R->isThreadLocalValue()) { Ctx.emitDiag([&]() { Ctx.Diag->Report(SymCtx.FA->D->getLocation(), diag::err_dylib_symbol_flags_mismatch) - << getAnnotatedName(DR, SymCtx.Kind, DisplayName) - << DR->isThreadLocalValue(); + << getAnnotatedName(DR, SymCtx) << DR->isThreadLocalValue(); }); return false; } @@ -329,7 +334,7 @@ bool DylibVerifier::compareSymbolFlags(const Record *R, SymbolContext &SymCtx, Ctx.emitDiag([&]() { SymCtx.FA->D->getLocation(), Ctx.Diag->Report(diag::err_header_symbol_flags_mismatch) - << SymCtx.PrettyPrintName << R->isThreadLocalValue(); + << getAnnotatedName(DR, SymCtx) << R->isThreadLocalValue(); }); return false; } @@ -338,8 +343,7 @@ bool DylibVerifier::compareSymbolFlags(const Record *R, SymbolContext &SymCtx, Ctx.emitDiag([&]() { Ctx.Diag->Report(SymCtx.FA->D->getLocation(), diag::err_dylib_symbol_flags_mismatch) - << getAnnotatedName(DR, SymCtx.Kind, DisplayName) - << R->isWeakDefined(); + << getAnnotatedName(DR, SymCtx) << R->isWeakDefined(); }); return false; } @@ -347,7 +351,7 @@ bool DylibVerifier::compareSymbolFlags(const Record *R, SymbolContext &SymCtx, Ctx.emitDiag([&]() { Ctx.Diag->Report(SymCtx.FA->D->getLocation(), diag::err_header_symbol_flags_mismatch) - << SymCtx.PrettyPrintName << R->isWeakDefined(); + << getAnnotatedName(R, SymCtx) << R->isWeakDefined(); }); return false; } @@ -457,10 +461,7 @@ DylibVerifier::Result DylibVerifier::verify(ObjCIVarRecord *R, std::string FullName = ObjCIVarRecord::createScopedName(SuperClass, R->getName()); - SymbolContext SymCtx{ - getAnnotatedName(R, EncodeKind::ObjectiveCInstanceVariable, - Demangle ? demangle(FullName) : FullName), - FullName, EncodeKind::ObjectiveCInstanceVariable, FA}; + SymbolContext SymCtx{FullName, EncodeKind::ObjectiveCInstanceVariable, FA}; return verifyImpl(R, SymCtx); } @@ -485,11 +486,8 @@ DylibVerifier::Result DylibVerifier::verify(ObjCInterfaceRecord *R, SymCtx.SymbolName = R->getName(); SymCtx.ObjCIFKind = assignObjCIFSymbolKind(R); - std::string DisplayName = - Demangle ? demangle(SymCtx.SymbolName) : SymCtx.SymbolName; SymCtx.Kind = R->hasExceptionAttribute() ? EncodeKind::ObjectiveCClassEHType : EncodeKind::ObjectiveCClass; - SymCtx.PrettyPrintName = getAnnotatedName(R, SymCtx.Kind, DisplayName); SymCtx.FA = FA; return verifyImpl(R, SymCtx); @@ -504,8 +502,6 @@ DylibVerifier::Result DylibVerifier::verify(GlobalRecord *R, SimpleSymbol Sym = parseSymbol(R->getName()); SymbolContext SymCtx; SymCtx.SymbolName = Sym.Name; - SymCtx.PrettyPrintName = - getAnnotatedName(R, Sym.Kind, Demangle ? demangle(Sym.Name) : Sym.Name); SymCtx.Kind = Sym.Kind; SymCtx.FA = FA; SymCtx.Inlined = R->isInlined(); diff --git a/clang/test/InstallAPI/diagnostics-cpp.test b/clang/test/InstallAPI/diagnostics-cpp.test index 9319a7a61d48..658886537507 100644 --- a/clang/test/InstallAPI/diagnostics-cpp.test +++ b/clang/test/InstallAPI/diagnostics-cpp.test @@ -12,8 +12,8 @@ // RUN: --verify-mode=Pedantic -o %t/output.tbd --demangle 2> %t/errors.log // RUN: FileCheck -input-file %t/errors.log %s -CHECK: warning: violations found for arm64-apple-macos13 -CHECK: CPP.h:5:7: error: declaration has external linkage, but symbol has internal linkage in dynamic library 'vtable for Bar' +CHECK: warning: violations found for arm64-apple-macos13 +CHECK: CPP.h:5:7: error: declaration has external linkage, but symbol has internal linkage in dynamic library 'vtable for Bar' CHECK-NEXT: class Bar : Foo { CHECK-NEXT: ^ CHECK-NEXT: CPP.h:5:7: error: declaration has external linkage, but symbol has internal linkage in dynamic library 'typeinfo for Bar' -- GitLab From 05bde30585710a51592eee0a6cf6df8184d09c92 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson <paulson1@linux.ibm.com> Date: Wed, 20 Mar 2024 10:29:12 -0400 Subject: [PATCH 251/307] Move assertion for AdjustsStack from PEI to MachineVerifier. (#85698) Have the verifier report a missing AdjustsStack flag rather than waiting until PEI asserts. --- llvm/lib/CodeGen/MachineVerifier.cpp | 6 +++++ llvm/lib/CodeGen/PrologEpilogInserter.cpp | 2 -- .../clear-dead-implicit-def-impdef.mir | 2 ++ ...plicit-def-remat-requires-impdef-check.mir | 2 ++ ...implicit-def-with-impdef-greedy-assert.mir | 2 ++ .../CodeGen/AMDGPU/fold-restore-undef-use.mir | 2 ++ .../greedy-alloc-fail-sgpr1024-spill.mir | 1 + .../ran-out-of-sgprs-allocation-failure.mir | 1 + .../CodeGen/AMDGPU/sched-crash-dbg-value.mir | 2 ++ .../AMDGPU/sgpr-spill-wrong-stack-id.mir | 1 + .../AMDGPU/snippet-copy-bundle-regression.mir | 1 + .../virtregrewrite-undef-identity-copy.mir | 1 + ...no-register-coalescing-in-returnsTwice.mir | 2 ++ .../CodeGen/Hexagon/regalloc-bad-undef.mir | 2 +- .../SystemZ/RAbasic-invalid-LR-update.mir | 2 ++ .../SystemZ/clear-liverange-spillreg.mir | 1 + llvm/test/CodeGen/SystemZ/int-cmp-56.mir | 4 +++ .../SystemZ/regcoal-subranges-update.mir | 2 ++ llvm/test/CodeGen/X86/callbr-asm-kill.mir | 1 + llvm/test/CodeGen/X86/regalloc-copy-hints.mir | 1 + .../CodeGen/X86/statepoint-fastregalloc.mir | 4 +++ .../X86/statepoint-invoke-ra-enter-at-end.mir | 2 +- .../X86/statepoint-invoke-ra-hoist-copies.mir | 2 +- .../statepoint-invoke-ra-inline-spiller.mir | 2 +- ...tatepoint-invoke-ra-remove-back-copies.mir | 2 +- .../test/CodeGen/X86/statepoint-invoke-ra.mir | 2 +- .../CodeGen/X86/statepoint-vreg-folding.mir | 2 +- .../DebugInfo/MIR/InstrRef/phi-coalescing.mir | 1 + .../Mips/livedebugvars-stop-trimming-loc.mir | 2 ++ .../MachineVerifier/test_adjustsstack.mir | 26 +++++++++++++++++++ 30 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 llvm/test/MachineVerifier/test_adjustsstack.mir diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index c69d36fc7fdd..005efe48ac0c 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -3697,6 +3697,9 @@ void MachineVerifier::verifyStackFrame() { if (I.getOpcode() == FrameSetupOpcode) { if (BBState.ExitIsSetup) report("FrameSetup is after another FrameSetup", &I); + if (!MRI->isSSA() && !MF->getFrameInfo().adjustsStack()) + report("AdjustsStack not set in presence of a frame pseudo " + "instruction.", &I); BBState.ExitValue -= TII->getFrameTotalSize(I); BBState.ExitIsSetup = true; } @@ -3712,6 +3715,9 @@ void MachineVerifier::verifyStackFrame() { errs() << "FrameDestroy <" << Size << "> is after FrameSetup <" << AbsSPAdj << ">.\n"; } + if (!MRI->isSSA() && !MF->getFrameInfo().adjustsStack()) + report("AdjustsStack not set in presence of a frame pseudo " + "instruction.", &I); BBState.ExitValue += Size; BBState.ExitIsSetup = false; } diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index eaf96ec5cbde..c942b8a3e268 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -372,8 +372,6 @@ void PEI::calculateCallFrameInfo(MachineFunction &MF) { MFI.computeMaxCallFrameSize(MF, &FrameSDOps); assert(MFI.getMaxCallFrameSize() <= MaxCFSIn && "Recomputing MaxCFS gave a larger value."); - assert((FrameSDOps.empty() || MF.getFrameInfo().adjustsStack()) && - "AdjustsStack not set in presence of a frame pseudo instruction."); if (TFI->canSimplifyCallFramePseudos(MF)) { // If call frames are not being included as part of the stack frame, and diff --git a/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir b/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir index 9040937d027d..2532c76b1336 100644 --- a/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir +++ b/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir @@ -2,6 +2,8 @@ # RUN: llc -mtriple=arm64-apple-macosx -mcpu=apple-m1 -verify-regalloc -run-pass=greedy -o - %s | FileCheck %s --- name: func +frameInfo: + adjustsStack: true tracksRegLiveness: true body: | bb.0: diff --git a/llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir b/llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir index aa94a03786f5..47aa34e3c011 100644 --- a/llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir +++ b/llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir @@ -22,6 +22,7 @@ name: inst_stores_to_dead_spill_implicit_def_impdef tracksRegLiveness: true frameInfo: + adjustsStack: true hasCalls: true body: | bb.0: @@ -59,6 +60,7 @@ body: | name: inst_stores_to_dead_spill_movimm_impdef tracksRegLiveness: true frameInfo: + adjustsStack: true hasCalls: true body: | bb.0: diff --git a/llvm/test/CodeGen/AArch64/implicit-def-with-impdef-greedy-assert.mir b/llvm/test/CodeGen/AArch64/implicit-def-with-impdef-greedy-assert.mir index e5395b20afd4..d55cf71cead6 100644 --- a/llvm/test/CodeGen/AArch64/implicit-def-with-impdef-greedy-assert.mir +++ b/llvm/test/CodeGen/AArch64/implicit-def-with-impdef-greedy-assert.mir @@ -3,6 +3,8 @@ --- name: widget +frameInfo: + adjustsStack: true tracksRegLiveness: true jumpTable: kind: label-difference32 diff --git a/llvm/test/CodeGen/AMDGPU/fold-restore-undef-use.mir b/llvm/test/CodeGen/AMDGPU/fold-restore-undef-use.mir index 3616d617f84a..054eeec9e33f 100644 --- a/llvm/test/CodeGen/AMDGPU/fold-restore-undef-use.mir +++ b/llvm/test/CodeGen/AMDGPU/fold-restore-undef-use.mir @@ -7,6 +7,8 @@ --- name: restore_undef_copy_use +frameInfo: + adjustsStack: true tracksRegLiveness: true machineFunctionInfo: maxKernArgAlign: 1 diff --git a/llvm/test/CodeGen/AMDGPU/greedy-alloc-fail-sgpr1024-spill.mir b/llvm/test/CodeGen/AMDGPU/greedy-alloc-fail-sgpr1024-spill.mir index bdd89a907790..dde84af57ed2 100644 --- a/llvm/test/CodeGen/AMDGPU/greedy-alloc-fail-sgpr1024-spill.mir +++ b/llvm/test/CodeGen/AMDGPU/greedy-alloc-fail-sgpr1024-spill.mir @@ -13,6 +13,7 @@ name: greedy_fail_alloc_sgpr1024_spill tracksRegLiveness: true frameInfo: + adjustsStack: true hasCalls: true machineFunctionInfo: explicitKernArgSize: 16 diff --git a/llvm/test/CodeGen/AMDGPU/ran-out-of-sgprs-allocation-failure.mir b/llvm/test/CodeGen/AMDGPU/ran-out-of-sgprs-allocation-failure.mir index 2ccc24152a9f..fdfc9b043cc9 100644 --- a/llvm/test/CodeGen/AMDGPU/ran-out-of-sgprs-allocation-failure.mir +++ b/llvm/test/CodeGen/AMDGPU/ran-out-of-sgprs-allocation-failure.mir @@ -24,6 +24,7 @@ registers: - { id: 10, class: sreg_64_xexec, preferred-register: '$vcc' } frameInfo: maxAlignment: 1 + adjustsStack: true hasCalls: true machineFunctionInfo: maxKernArgAlign: 1 diff --git a/llvm/test/CodeGen/AMDGPU/sched-crash-dbg-value.mir b/llvm/test/CodeGen/AMDGPU/sched-crash-dbg-value.mir index c0d199920bd9..158874e7c827 100644 --- a/llvm/test/CodeGen/AMDGPU/sched-crash-dbg-value.mir +++ b/llvm/test/CodeGen/AMDGPU/sched-crash-dbg-value.mir @@ -180,6 +180,8 @@ exposesReturnsTwice: false legalized: false regBankSelected: false selected: false +frameInfo: + adjustsStack: true tracksRegLiveness: true liveins: - { reg: '$vgpr0', virtual-reg: '%0' } diff --git a/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir b/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir index efbdbca9da6b..c6ccbd99bf89 100644 --- a/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir +++ b/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir @@ -78,6 +78,7 @@ name: sgpr_spill_wrong_stack_id tracksRegLiveness: true frameInfo: + adjustsStack: true hasCalls: true machineFunctionInfo: scratchRSrcReg: $sgpr0_sgpr1_sgpr2_sgpr3 diff --git a/llvm/test/CodeGen/AMDGPU/snippet-copy-bundle-regression.mir b/llvm/test/CodeGen/AMDGPU/snippet-copy-bundle-regression.mir index 355829825146..f8ec6bb5d943 100644 --- a/llvm/test/CodeGen/AMDGPU/snippet-copy-bundle-regression.mir +++ b/llvm/test/CodeGen/AMDGPU/snippet-copy-bundle-regression.mir @@ -21,6 +21,7 @@ name: kernel tracksRegLiveness: true frameInfo: + adjustsStack: true hasCalls: true machineFunctionInfo: isEntryFunction: true diff --git a/llvm/test/CodeGen/AMDGPU/virtregrewrite-undef-identity-copy.mir b/llvm/test/CodeGen/AMDGPU/virtregrewrite-undef-identity-copy.mir index 3d9db687ffa1..6659e9532376 100644 --- a/llvm/test/CodeGen/AMDGPU/virtregrewrite-undef-identity-copy.mir +++ b/llvm/test/CodeGen/AMDGPU/virtregrewrite-undef-identity-copy.mir @@ -20,6 +20,7 @@ name: undef_identity_copy tracksRegLiveness: true frameInfo: maxAlignment: 4 + adjustsStack: true hasCalls: true machineFunctionInfo: isEntryFunction: true diff --git a/llvm/test/CodeGen/ARM/no-register-coalescing-in-returnsTwice.mir b/llvm/test/CodeGen/ARM/no-register-coalescing-in-returnsTwice.mir index 5c59566247d8..b4bbb9be8ae4 100644 --- a/llvm/test/CodeGen/ARM/no-register-coalescing-in-returnsTwice.mir +++ b/llvm/test/CodeGen/ARM/no-register-coalescing-in-returnsTwice.mir @@ -86,6 +86,8 @@ --- name: main exposesReturnsTwice: true +frameInfo: + adjustsStack: true stack: - { id: 0, name: P0, size: 80, alignment: 8, local-offset: -80 } - { id: 1, name: jb1, size: 160, alignment: 8, local-offset: -240 } diff --git a/llvm/test/CodeGen/Hexagon/regalloc-bad-undef.mir b/llvm/test/CodeGen/Hexagon/regalloc-bad-undef.mir index 67f4dd72ea0b..9468b18bf8e4 100644 --- a/llvm/test/CodeGen/Hexagon/regalloc-bad-undef.mir +++ b/llvm/test/CodeGen/Hexagon/regalloc-bad-undef.mir @@ -135,7 +135,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 - adjustsStack: false + adjustsStack: true hasCalls: true maxCallFrameSize: 0 hasOpaqueSPAdjustment: false diff --git a/llvm/test/CodeGen/SystemZ/RAbasic-invalid-LR-update.mir b/llvm/test/CodeGen/SystemZ/RAbasic-invalid-LR-update.mir index 3b308ce3d0d2..fbe2b687e850 100644 --- a/llvm/test/CodeGen/SystemZ/RAbasic-invalid-LR-update.mir +++ b/llvm/test/CodeGen/SystemZ/RAbasic-invalid-LR-update.mir @@ -24,6 +24,8 @@ --- name: autogen_SD21418 alignment: 4 +frameInfo: + adjustsStack: true tracksRegLiveness: true registers: - { id: 0, class: vr128bit } diff --git a/llvm/test/CodeGen/SystemZ/clear-liverange-spillreg.mir b/llvm/test/CodeGen/SystemZ/clear-liverange-spillreg.mir index 7ff7d9b8b709..197c3d8551fc 100644 --- a/llvm/test/CodeGen/SystemZ/clear-liverange-spillreg.mir +++ b/llvm/test/CodeGen/SystemZ/clear-liverange-spillreg.mir @@ -157,6 +157,7 @@ registers: - { id: 129, class: grx32bit } - { id: 130, class: fp64bit } frameInfo: + adjustsStack: true hasCalls: true body: | bb.0: diff --git a/llvm/test/CodeGen/SystemZ/int-cmp-56.mir b/llvm/test/CodeGen/SystemZ/int-cmp-56.mir index e52fd44ae47d..3e00b6065eb9 100644 --- a/llvm/test/CodeGen/SystemZ/int-cmp-56.mir +++ b/llvm/test/CodeGen/SystemZ/int-cmp-56.mir @@ -48,6 +48,7 @@ liveins: - { reg: '$r2d', virtual-reg: '%0' } frameInfo: maxAlignment: 1 + adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | @@ -125,6 +126,7 @@ liveins: - { reg: '$r2d', virtual-reg: '%0' } frameInfo: maxAlignment: 1 + adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | @@ -202,6 +204,7 @@ liveins: - { reg: '$r2d', virtual-reg: '%0' } frameInfo: maxAlignment: 1 + adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | @@ -279,6 +282,7 @@ liveins: - { reg: '$r2d', virtual-reg: '%0' } frameInfo: maxAlignment: 1 + adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | diff --git a/llvm/test/CodeGen/SystemZ/regcoal-subranges-update.mir b/llvm/test/CodeGen/SystemZ/regcoal-subranges-update.mir index f709b70ff1b7..d3ef9b0b9abf 100644 --- a/llvm/test/CodeGen/SystemZ/regcoal-subranges-update.mir +++ b/llvm/test/CodeGen/SystemZ/regcoal-subranges-update.mir @@ -48,6 +48,8 @@ body: | # represented for the value carried by %7. --- name: segfault +frameInfo: + adjustsStack: true tracksRegLiveness: true liveins: [] body: | diff --git a/llvm/test/CodeGen/X86/callbr-asm-kill.mir b/llvm/test/CodeGen/X86/callbr-asm-kill.mir index 86c58c4715ed..0dded37c97af 100644 --- a/llvm/test/CodeGen/X86/callbr-asm-kill.mir +++ b/llvm/test/CodeGen/X86/callbr-asm-kill.mir @@ -45,6 +45,7 @@ liveins: - { reg: '$rsi', virtual-reg: '%3' } frameInfo: maxAlignment: 1 + adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | diff --git a/llvm/test/CodeGen/X86/regalloc-copy-hints.mir b/llvm/test/CodeGen/X86/regalloc-copy-hints.mir index 13b5a541fa22..d09bcd6a6b40 100644 --- a/llvm/test/CodeGen/X86/regalloc-copy-hints.mir +++ b/llvm/test/CodeGen/X86/regalloc-copy-hints.mir @@ -103,6 +103,7 @@ registers: - { id: 82, class: gr32 } frameInfo: maxAlignment: 4 + adjustsStack: true hasCalls: true fixedStack: - { id: 0, size: 4, alignment: 4, stack-id: default, isImmutable: true } diff --git a/llvm/test/CodeGen/X86/statepoint-fastregalloc.mir b/llvm/test/CodeGen/X86/statepoint-fastregalloc.mir index 02c931067300..87ffdd7c4e6b 100644 --- a/llvm/test/CodeGen/X86/statepoint-fastregalloc.mir +++ b/llvm/test/CodeGen/X86/statepoint-fastregalloc.mir @@ -5,6 +5,8 @@ # Tied def/use must be assigned to the same register. --- name: test_relocate +frameInfo: + adjustsStack: true tracksRegLiveness: true body: | bb.0.entry: @@ -24,6 +26,8 @@ body: | # These regmasks have no real meaning and chosen to allow only single register to be assignable ($rbp) --- name: test_relocate_multi_regmasks +frameInfo: + adjustsStack: true tracksRegLiveness: true body: | bb.0.entry: diff --git a/llvm/test/CodeGen/X86/statepoint-invoke-ra-enter-at-end.mir b/llvm/test/CodeGen/X86/statepoint-invoke-ra-enter-at-end.mir index 11968f17c70a..5f05270729fd 100644 --- a/llvm/test/CodeGen/X86/statepoint-invoke-ra-enter-at-end.mir +++ b/llvm/test/CodeGen/X86/statepoint-invoke-ra-enter-at-end.mir @@ -231,7 +231,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 1 - adjustsStack: false + adjustsStack: true hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/CodeGen/X86/statepoint-invoke-ra-hoist-copies.mir b/llvm/test/CodeGen/X86/statepoint-invoke-ra-hoist-copies.mir index aae2f3870138..cf9128260f19 100644 --- a/llvm/test/CodeGen/X86/statepoint-invoke-ra-hoist-copies.mir +++ b/llvm/test/CodeGen/X86/statepoint-invoke-ra-hoist-copies.mir @@ -398,7 +398,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 1 - adjustsStack: false + adjustsStack: true hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/CodeGen/X86/statepoint-invoke-ra-inline-spiller.mir b/llvm/test/CodeGen/X86/statepoint-invoke-ra-inline-spiller.mir index 87f5f0f96c50..fcebc69d9b2e 100644 --- a/llvm/test/CodeGen/X86/statepoint-invoke-ra-inline-spiller.mir +++ b/llvm/test/CodeGen/X86/statepoint-invoke-ra-inline-spiller.mir @@ -175,7 +175,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 4 - adjustsStack: false + adjustsStack: true hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/CodeGen/X86/statepoint-invoke-ra-remove-back-copies.mir b/llvm/test/CodeGen/X86/statepoint-invoke-ra-remove-back-copies.mir index 49253968fcca..8bb39a03f7e3 100644 --- a/llvm/test/CodeGen/X86/statepoint-invoke-ra-remove-back-copies.mir +++ b/llvm/test/CodeGen/X86/statepoint-invoke-ra-remove-back-copies.mir @@ -226,7 +226,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 4 - adjustsStack: false + adjustsStack: true hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/CodeGen/X86/statepoint-invoke-ra.mir b/llvm/test/CodeGen/X86/statepoint-invoke-ra.mir index 858ff3f1888b..da651039ce21 100644 --- a/llvm/test/CodeGen/X86/statepoint-invoke-ra.mir +++ b/llvm/test/CodeGen/X86/statepoint-invoke-ra.mir @@ -172,7 +172,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 4 - adjustsStack: false + adjustsStack: true hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/CodeGen/X86/statepoint-vreg-folding.mir b/llvm/test/CodeGen/X86/statepoint-vreg-folding.mir index e24d5e8af1f5..d40a9a06d162 100644 --- a/llvm/test/CodeGen/X86/statepoint-vreg-folding.mir +++ b/llvm/test/CodeGen/X86/statepoint-vreg-folding.mir @@ -114,7 +114,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 8 - adjustsStack: false + adjustsStack: true hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir b/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir index bc1c7ebac6ce..6460263c6025 100644 --- a/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir +++ b/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir @@ -106,6 +106,7 @@ liveins: - { reg: '$rsi', virtual-reg: '%5' } frameInfo: maxAlignment: 1 + adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | diff --git a/llvm/test/DebugInfo/MIR/Mips/livedebugvars-stop-trimming-loc.mir b/llvm/test/DebugInfo/MIR/Mips/livedebugvars-stop-trimming-loc.mir index 35ab906efc90..ac67b9671f53 100644 --- a/llvm/test/DebugInfo/MIR/Mips/livedebugvars-stop-trimming-loc.mir +++ b/llvm/test/DebugInfo/MIR/Mips/livedebugvars-stop-trimming-loc.mir @@ -71,6 +71,8 @@ --- name: fn2 alignment: 4 +frameInfo: + adjustsStack: true tracksRegLiveness: true registers: - { id: 0, class: gpr32, preferred-register: '' } diff --git a/llvm/test/MachineVerifier/test_adjustsstack.mir b/llvm/test/MachineVerifier/test_adjustsstack.mir new file mode 100644 index 000000000000..d333737e000c --- /dev/null +++ b/llvm/test/MachineVerifier/test_adjustsstack.mir @@ -0,0 +1,26 @@ +# RUN: not --crash llc -o - -start-before=twoaddressinstruction -verify-machineinstrs %s 2>&1 \ +# RUN: | FileCheck %s +# REQUIRES: aarch64-registered-target +--- | + target triple = "aarch64-unknown-linux" + declare i32 @bar(i32) nounwind + define i32 @foo() nounwind { + call i32 @bar(i32 0) + ret i32 0 + } +... +--- +name: foo +registers: + - { id: 0, class: gpr32 } +body: | + bb.0 (%ir-block.0): + ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp + %0 = COPY $wzr + $w0 = COPY %0 + BL @bar, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $w0, implicit-def $sp, implicit-def $w0 + ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp + $w0 = COPY killed %0 + RET_ReallyLR implicit $w0 +... +# CHECK-LABEL: Bad machine code: AdjustsStack not set in presence of a frame pseudo instruction. -- GitLab From 5fb2797f23343999cace3afe24480e8711df4566 Mon Sep 17 00:00:00 2001 From: Neumann Hon <neumann.hon@ibm.com> Date: Wed, 20 Mar 2024 10:30:30 -0400 Subject: [PATCH 252/307] [GOFF][z/OS] Change PrivateGlobalPrefix and PrivateLabelPrefix to be L# (#85730) The current values for PrivateGlobalPrefix and PrivateLabelPrefix (@@ and @ respectively) are, in hindsight, poor choices for multiple reasons: First, there exist externally visible routines from the language environment that begin with @@. These functions are certainly not local/private by any means and they should not share a prefix with private globals. Secondly, both private globals and private labels should be handled the same way by GOFF, so it doesn't make much sense for them to have separate prefixes. GOFF remains the only file format where these are different and there is no reason for that to be the case --- clang/test/CodeGen/SystemZ/systemz-ppa2.c | 4 ++-- llvm/include/llvm/IR/DataLayout.h | 2 +- llvm/lib/MC/MCAsmInfoGOFF.cpp | 4 ++-- llvm/test/CodeGen/SystemZ/call-zos-01.ll | 14 +++++++------- llvm/test/CodeGen/SystemZ/call-zos-i128.ll | 4 ++-- llvm/test/CodeGen/SystemZ/call-zos-vararg.ll | 6 +++--- llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll | 6 +++--- llvm/test/CodeGen/SystemZ/zos-landingpad.ll | 2 +- llvm/test/CodeGen/SystemZ/zos-ppa2.ll | 14 +++++++------- llvm/test/CodeGen/SystemZ/zos-prologue-epilog.ll | 14 +++++++------- llvm/test/MC/GOFF/ppa1.ll | 10 +++++----- llvm/unittests/IR/ManglerTest.cpp | 2 +- 12 files changed, 41 insertions(+), 41 deletions(-) diff --git a/clang/test/CodeGen/SystemZ/systemz-ppa2.c b/clang/test/CodeGen/SystemZ/systemz-ppa2.c index 0ff4cba5edfb..26b068ff03d5 100644 --- a/clang/test/CodeGen/SystemZ/systemz-ppa2.c +++ b/clang/test/CodeGen/SystemZ/systemz-ppa2.c @@ -13,14 +13,14 @@ // REQUIRES: systemz-registered-target // RUN: %clang_cc1 -triple s390x-ibm-zos -xc -S -o - %s | FileCheck %s --check-prefix CHECK-C -// CHECK-C: [[PPA2:(.L)|(@@)PPA2]]: +// CHECK-C: [[PPA2:(.L)|(L#)PPA2]]: // CHECK-C-NEXT: .byte 3{{[[:space:]]*}}.byte 0 // CHECK-C-NEXT: .byte 34{{$}} // CHECK-C-NEXT: .byte {{4}} // CHECK-C-NEXT: .long {{(CELQSTRT)}}-[[PPA2]] // RUN: %clang_cc1 -triple s390x-ibm-zos -xc++ -S -o - %s | FileCheck %s --check-prefix CHECK-CXX -// CHECK-CXX: [[PPA2:(.L)|(@@)PPA2]]: +// CHECK-CXX: [[PPA2:(.L)|(L#)PPA2]]: // CHECK-CXX-NEXT: .byte 3{{[[:space:]]*}}.byte 1 // CHECK-CXX-NEXT: .byte 34{{$}} // CHECK-CXX-NEXT: .byte {{4}} diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h index 71f7f51d8ee4..d14adfe1590b 100644 --- a/llvm/include/llvm/IR/DataLayout.h +++ b/llvm/include/llvm/IR/DataLayout.h @@ -337,7 +337,7 @@ public: case MM_WinCOFF: return ".L"; case MM_GOFF: - return "@"; + return "L#"; case MM_Mips: return "$"; case MM_MachO: diff --git a/llvm/lib/MC/MCAsmInfoGOFF.cpp b/llvm/lib/MC/MCAsmInfoGOFF.cpp index 81704ffe4b24..3c81a466e82e 100644 --- a/llvm/lib/MC/MCAsmInfoGOFF.cpp +++ b/llvm/lib/MC/MCAsmInfoGOFF.cpp @@ -21,7 +21,7 @@ void MCAsmInfoGOFF::anchor() {} MCAsmInfoGOFF::MCAsmInfoGOFF() { Data64bitsDirective = "\t.quad\t"; HasDotTypeDotSizeDirective = false; - PrivateGlobalPrefix = "@@"; - PrivateLabelPrefix = "@"; + PrivateGlobalPrefix = "L#"; + PrivateLabelPrefix = "L#"; ZeroDirective = "\t.space\t"; } diff --git a/llvm/test/CodeGen/SystemZ/call-zos-01.ll b/llvm/test/CodeGen/SystemZ/call-zos-01.ll index 77776861186b..fc7a85caa37e 100644 --- a/llvm/test/CodeGen/SystemZ/call-zos-01.ll +++ b/llvm/test/CodeGen/SystemZ/call-zos-01.ll @@ -104,7 +104,7 @@ entry: } ; CHECK-LABEL: call_double: -; CHECK: larl [[GENREG:[0-9]+]], @{{CPI[0-9]+_[0-9]+}} +; CHECK: larl [[GENREG:[0-9]+]], L#{{CPI[0-9]+_[0-9]+}} ; CHECK-NEXT: ld 0, 0([[GENREG]]) define double @call_double() { entry: @@ -113,7 +113,7 @@ entry: } ; CHECK-LABEL: call_longdouble: -; CHECK: larl [[GENREG:[0-9]+]], @{{CPI[0-9]+_[0-9]+}} +; CHECK: larl [[GENREG:[0-9]+]], L#{{CPI[0-9]+_[0-9]+}} ; CHECK-NEXT: ld 0, 0([[GENREG]]) ; CHECK-NEXT: ld 2, 8([[GENREG]]) define fp128 @call_longdouble() { @@ -123,7 +123,7 @@ entry: } ; CHECK-LABEL: call_floats0 -; CHECK: larl [[GENREG:[0-9]+]], @{{CPI[0-9]+_[0-9]+}} +; CHECK: larl [[GENREG:[0-9]+]], L#{{CPI[0-9]+_[0-9]+}} ; CHECK-NEXT: ld 1, 0([[GENREG]]) ; CHECK-NEXT: ld 3, 8([[GENREG]]) ; CHECK: lxr 5, 0 @@ -146,7 +146,7 @@ entry: } ; CHECK-LABEL: pass_float: -; CHECK: larl 1, @{{CPI[0-9]+_[0-9]+}} +; CHECK: larl 1, L#{{CPI[0-9]+_[0-9]+}} ; CHECK: aeb 0, 0(1) define float @pass_float(float %arg) { entry: @@ -155,7 +155,7 @@ entry: } ; CHECK-LABEL: pass_double: -; CHECK: larl 1, @{{CPI[0-9]+_[0-9]+}} +; CHECK: larl 1, L#{{CPI[0-9]+_[0-9]+}} ; CHECK: adb 0, 0(1) define double @pass_double(double %arg) { entry: @@ -164,7 +164,7 @@ entry: } ; CHECK-LABEL: pass_longdouble -; CHECK: larl 1, @{{CPI[0-9]+_[0-9]+}} +; CHECK: larl 1, L#{{CPI[0-9]+_[0-9]+}} ; CHECK: lxdb 1, 0(1) ; CHECK: axbr 0, 1 define fp128 @pass_longdouble(fp128 %arg) { @@ -174,7 +174,7 @@ entry: } ; CHECK-LABEL: pass_floats0 -; CHECK: larl 1, @{{CPI[0-9]+_[0-9]+}} +; CHECK: larl 1, L#{{CPI[0-9]+_[0-9]+}} ; CHECK: axbr 0, 4 ; CHECK: axbr 1, 0 ; CHECK: cxbr 1, 5 diff --git a/llvm/test/CodeGen/SystemZ/call-zos-i128.ll b/llvm/test/CodeGen/SystemZ/call-zos-i128.ll index ccdac161d08a..775483374a32 100644 --- a/llvm/test/CodeGen/SystemZ/call-zos-i128.ll +++ b/llvm/test/CodeGen/SystemZ/call-zos-i128.ll @@ -3,10 +3,10 @@ ; RUN: llc < %s -mtriple=s390x-ibm-zos -mcpu=z13 | FileCheck %s ; CHECK-LABEL: call_i128: -; CHECK-DAG: larl 1, @CPI0_0 +; CHECK-DAG: larl 1, L#CPI0_0 ; CHECK-DAG: vl 0, 0(1), 3 ; CHECK-DAG: vst 0, 2256(4), 3 -; CHECK-DAG: larl 1, @CPI0_1 +; CHECK-DAG: larl 1, L#CPI0_1 ; CHECK-DAG: vl 0, 0(1), 3 ; CHECK-DAG: vst 0, 2272(4), 3 ; CHECK-DAG: la 1, 2288(4) diff --git a/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll b/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll index bde59a6be782..8290dbfe2310 100644 --- a/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll +++ b/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll @@ -108,7 +108,7 @@ define i64 @call_vararg_both0(i64 %arg0, double %arg1) { ; CHECK-LABEL: call_vararg_long_double0: ; CHECK: stmg 6, 7, 1872(4) ; CHECK-NEXT: aghi 4, -192 -; CHECK-NEXT: larl 1, @CPI5_0 +; CHECK-NEXT: larl 1, L#CPI5_0 ; CHECK-NEXT: ld 0, 0(1) ; CHECK-NEXT: ld 2, 8(1) ; CHECK-NEXT: lg 6, 8(5) @@ -202,7 +202,7 @@ define void @call_vec_vararg_test0(<2 x double> %v) { } ; ARCH12-LABEL: call_vec_vararg_test1 -; ARCH12: larl 1, @CPI10_0 +; ARCH12: larl 1, L#CPI10_0 ; ARCH12: vl 0, 0(1), 3 ; ARCH12: vlgvg 3, 24, 0 ; ARCH12: vrepg 2, 0, 1 @@ -294,7 +294,7 @@ entry: ; CHECK-NEXT: aghi 4, -192 ; CHECK-NEXT: lg 6, 72(5) ; CHECK-NEXT: lg 5, 64(5) -; CHECK-NEXT: larl 1, @CPI17_0 +; CHECK-NEXT: larl 1, L#CPI17_0 ; CHECK-NEXT: le 0, 0(1) ; CHECK-NEXT: llihf 0, 1073692672 ; CHECK-NEXT: llihh 2, 16384 diff --git a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll index e25246917ec0..db67ac578186 100644 --- a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll +++ b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll @@ -56,9 +56,9 @@ entry: declare signext i32 @callout(i32 signext) ; CHECK: .section ".ada" -; CHECK: .set @@DoFunc@indirect0, DoFunc -; CHECK: .indirect_symbol @@DoFunc@indirect0 -; CHECK: .quad V(@@DoFunc@indirect0) * Offset 0 pointer to function descriptor DoFunc +; CHECK: .set L#DoFunc@indirect0, DoFunc +; CHECK: .indirect_symbol L#DoFunc@indirect0 +; CHECK: .quad V(L#DoFunc@indirect0) * Offset 0 pointer to function descriptor DoFunc ; CHECK: .quad R(Caller) * Offset 8 function descriptor of Caller ; CHECK: .quad V(Caller) ; CHECK: .quad A(i2) * Offset 24 pointer to data symbol i2 diff --git a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll index 7f3214d57424..9db10114e979 100644 --- a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll +++ b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll @@ -19,7 +19,7 @@ done: lpad: %0 = landingpad { ptr, i32 } cleanup ; The Exception Pointer is %r1; the Exception Selector, %r2. -; CHECK: @BB{{[^%]*}} %lpad +; CHECK: L#BB{{[^%]*}} %lpad ; CHECK-DAG: stg 1, {{.*}} ; CHECK-DAG: st 2, {{.*}} %1 = extractvalue { ptr, i32 } %0, 0 diff --git a/llvm/test/CodeGen/SystemZ/zos-ppa2.ll b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll index 60580aeb6d83..189b5a3757ee 100644 --- a/llvm/test/CodeGen/SystemZ/zos-ppa2.ll +++ b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll @@ -2,24 +2,24 @@ ; REQUIRES: systemz-registered-target ; CHECK: .section ".ppa2" -; CHECK: @@PPA2: +; CHECK: L#PPA2: ; CHECK: .byte 3 ; CHECK: .byte 231 ; CHECK: .byte 34 ; CHECK: .byte 4 -; CHECK: .long CELQSTRT-@@PPA2 +; CHECK: .long CELQSTRT-L#PPA2 ; CHECK: .long 0 -; CHECK: .long @@DVS-@@PPA2 +; CHECK: .long L#DVS-L#PPA2 ; CHECK: .long 0 ; CHECK: .byte 129 ; CHECK: .byte 0 ; CHECK: .short 0 -; CHECK: @@DVS: +; CHECK: L#DVS: ; CHECK: .ascii "\361\371\367\360\360\361\360\361\360\360\360\360\360\360" ; CHECK: .short 0 -; CHECK: .quad @@PPA2-CELQSTRT * A(PPA2-CELQSTRT) -; CHECK: @@PPA1_void_test_0: -; CHECK: .long @@PPA2-@@PPA1_void_test_0 * Offset to PPA2 +; CHECK: .quad L#PPA2-CELQSTRT * A(PPA2-CELQSTRT) +; CHECK: L#PPA1_void_test_0: +; CHECK: .long L#PPA2-L#PPA1_void_test_0 * Offset to PPA2 ; CHECK: .section "B_IDRL" ; CHECK: .byte 0 ; CHECK: .byte 3 diff --git a/llvm/test/CodeGen/SystemZ/zos-prologue-epilog.ll b/llvm/test/CodeGen/SystemZ/zos-prologue-epilog.ll index 8c0411629da7..d3e5823fcb1f 100644 --- a/llvm/test/CodeGen/SystemZ/zos-prologue-epilog.ll +++ b/llvm/test/CodeGen/SystemZ/zos-prologue-epilog.ll @@ -15,7 +15,7 @@ ; CHECK64: aghi 4, 192 ; CHECK64: b 2(7) -; CHECK64: @@PPA1_func0_0: +; CHECK64: L#PPA1_func0_0: ; CHECK64: .short 0 * Length/4 of Parms define void @func0() { call i64 (i64) @fun(i64 10) @@ -31,7 +31,7 @@ define void @func0() { ; CHECK64: aghi 4, 160 ; CHECK64: b 2(7) -; CHECK64: @@PPA1_func1_0: +; CHECK64: L#PPA1_func1_0: ; CHECK64: .short 2 * Length/4 of Parms define void @func1(ptr %ptr) { %l01 = load volatile i64, ptr %ptr @@ -336,16 +336,16 @@ define void @large_stack0() { ; CHECK64: lgr 0, 3 ; CHECK64: llgt 3, 1208 ; CHECK64: cg 4, 64(3) -; CHECK64: jhe @BB7_2 +; CHECK64: jhe L#BB7_2 ; CHECK64: %bb.1: ; CHECK64: lg 3, 72(3) ; CHECK64: basr 3, 3 ; CHECK64: bcr 0, 7 -; CHECK64: @BB7_2: +; CHECK64: L#BB7_2: ; CHECK64: stmg 6, 7, 2064(4) ; CHECK64: lgr 3, 0 -; CHECK64: @@PPA1_large_stack1_0: +; CHECK64: L#PPA1_large_stack1_0: ; CHECK64: .short 6 * Length/4 of Parms define void @large_stack1(i64 %n1, i64 %n2, i64 %n3) { %arr = alloca [131072 x i64], align 8 @@ -361,12 +361,12 @@ define void @large_stack1(i64 %n1, i64 %n2, i64 %n3) { ; CHECK64: agfi 4, -1048768 ; CHECK64: llgt 3, 1208 ; CHECK64: cg 4, 64(3) -; CHECK64: jhe @BB8_2 +; CHECK64: jhe L#BB8_2 ; CHECK64: %bb.1: ; CHECK64: lg 3, 72(3) ; CHECK64: basr 3, 3 ; CHECK64: bcr 0, 7 -; CHECK64: @BB8_2: +; CHECK64: L#BB8_2: ; CHECK64: lgr 3, 0 ; CHECK64: lg 3, 2192(3) ; CHECK64: stmg 4, 12, 2048(4) diff --git a/llvm/test/MC/GOFF/ppa1.ll b/llvm/test/MC/GOFF/ppa1.ll index 40fc9e93780d..13971c7ec8e7 100644 --- a/llvm/test/MC/GOFF/ppa1.ll +++ b/llvm/test/MC/GOFF/ppa1.ll @@ -1,7 +1,7 @@ ; RUN: llc -mtriple s390x-ibm-zos < %s | FileCheck %s ; REQUIRES: systemz-registered-target -; CHECK: @@EPM_void_test_0: * @void_test +; CHECK: L#EPM_void_test_0: * @void_test ; CHECK: * XPLINK Routine Layout Entry ; CHECK: .long 12779717 * Eyecatcher 0x00C300C500C500 ; CHECK: .short 197 @@ -11,9 +11,9 @@ ; CHECK: * Entry Flags ; CHECK: * Bit 1: 1 = Leaf function ; CHECK: * Bit 2: 0 = Does not use alloca -; CHECK: @@func_end0: +; CHECK: L#func_end0: ; CHECK: .section ".ppa1" -; CHECK: @@PPA1_void_test_0: * PPA1 +; CHECK: L#PPA1_void_test_0: * PPA1 ; CHECK: .byte 2 * Version ; CHECK: .byte 206 * LE Signature X'CE' ; CHECK: .short 0 * Saved GPR Mask @@ -25,8 +25,8 @@ ; CHECK: .byte 0 * PPA1 Flags 3 ; CHECK: .byte 129 * PPA1 Flags 4 ; CHECK: .short 0 * Length/4 of Parms -; CHECK: .long @@func_end0-@@EPM_void_test_0 * Length of Code -; CHECK: .long @@EPM_void_test_0-@@PPA1_void_test_0 +; CHECK: .long L#func_end0-L#EPM_void_test_0 * Length of Code +; CHECK: .long L#EPM_void_test_0-L#PPA1_void_test_0 ; CHECK: .section ".text" ; CHECK: * -- End function define void @void_test() { diff --git a/llvm/unittests/IR/ManglerTest.cpp b/llvm/unittests/IR/ManglerTest.cpp index 8ad95a83b692..f2b78a1f9876 100644 --- a/llvm/unittests/IR/ManglerTest.cpp +++ b/llvm/unittests/IR/ManglerTest.cpp @@ -171,7 +171,7 @@ TEST(ManglerTest, GOFF) { "foo"); EXPECT_EQ(mangleFunc("foo", llvm::GlobalValue::PrivateLinkage, llvm::CallingConv::C, Mod, Mang), - "@foo"); + "L#foo"); } } // end anonymous namespace -- GitLab From 972f65a83f933b0f90cf975ef89452f4210e9b06 Mon Sep 17 00:00:00 2001 From: martinboehme <mboehme@google.com> Date: Wed, 20 Mar 2024 15:34:11 +0100 Subject: [PATCH 253/307] [clang][NFC] Add documentation for `CastExpr::path()`. (#85623) This didn't have any documentation, so I had to do some experimenting in godbolt when I used this in https://github.com/llvm/llvm-project/pull/84138, and my reviewer later also had some [questions](https://github.com/llvm/llvm-project/pull/84138#discussion_r1524855434) about this, so I figured it would be worth adding documentation. --- clang/include/clang/AST/Expr.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index f9313f87be38..6e153ebe024b 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -3562,6 +3562,18 @@ public: path_const_iterator path_begin() const { return path_buffer(); } path_const_iterator path_end() const { return path_buffer() + path_size(); } + /// Path through the class hierarchy taken by casts between base and derived + /// classes (see implementation of `CastConsistency()` for a full list of + /// cast kinds that have a path). + /// + /// For each derived-to-base edge in the path, the path contains a + /// `CXXBaseSpecifier` for the base class of that edge; the entries are + /// ordered from derived class to base class. + /// + /// For example, given classes `Base`, `Intermediate : public Base` and + /// `Derived : public Intermediate`, the path for a cast from `Derived *` to + /// `Base *` contains two entries: One for `Intermediate`, and one for `Base`, + /// in that order. llvm::iterator_range<path_iterator> path() { return llvm::make_range(path_begin(), path_end()); } -- GitLab From 647d75d3a883c008c19a79bce265388b3c95e742 Mon Sep 17 00:00:00 2001 From: Tina Jung <tinamaria.jung@amd.com> Date: Wed, 20 Mar 2024 16:00:05 +0100 Subject: [PATCH 254/307] [mlir][emitc] Restrict integer and float types (#85788) Restrict which integers and floating-point types are valid in EmitC. This should cover the types which are supported in C++ and is aligned with what the emitter currently supports. The checks are implemented as functions and not fully in tablegen to allow them to be re-used by conversions to EmitC. --- mlir/include/mlir/Dialect/EmitC/IR/EmitC.h | 4 +++ mlir/include/mlir/Dialect/EmitC/IR/EmitC.td | 4 +-- .../mlir/Dialect/EmitC/IR/EmitCTypes.td | 6 ++++ mlir/lib/Dialect/EmitC/IR/EmitC.cpp | 29 +++++++++++++++++++ mlir/test/Dialect/EmitC/invalid_ops.mlir | 8 ++--- mlir/test/Dialect/EmitC/invalid_types.mlir | 16 ++++++++++ 6 files changed, 61 insertions(+), 6 deletions(-) diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h index 1f0df3cb336b..725a1bcb4e6c 100644 --- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h +++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h @@ -30,6 +30,10 @@ namespace mlir { namespace emitc { void buildTerminatedBody(OpBuilder &builder, Location loc); +/// Determines whether \p type is a valid integer type in EmitC. +bool isSupportedIntegerType(mlir::Type type); +/// Determines whether \p type is a valid floating-point type in EmitC. +bool isSupportedFloatType(mlir::Type type); } // namespace emitc } // namespace mlir diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td index 78bfd561171f..d746222ff37a 100644 --- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td +++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td @@ -51,8 +51,8 @@ class EmitC_BinaryOp<string mnemonic, list<Trait> traits = []> : def CExpression : NativeOpTrait<"emitc::CExpression">; // Types only used in binary arithmetic operations. -def IntegerIndexOrOpaqueType : AnyTypeOf<[AnyInteger, Index, EmitC_OpaqueType]>; -def FloatIntegerIndexOrOpaqueType : AnyTypeOf<[AnyFloat, IntegerIndexOrOpaqueType]>; +def IntegerIndexOrOpaqueType : AnyTypeOf<[EmitCIntegerType, Index, EmitC_OpaqueType]>; +def FloatIntegerIndexOrOpaqueType : AnyTypeOf<[EmitCFloatType, IntegerIndexOrOpaqueType]>; def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression]> { let summary = "Addition operation"; diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td index a2ba45a1f6a1..bce5807230ce 100644 --- a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td +++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td @@ -22,6 +22,12 @@ include "mlir/IR/BuiltinTypeInterfaces.td" // EmitC type definitions //===----------------------------------------------------------------------===// +def EmitCIntegerType : Type<CPred<"emitc::isSupportedIntegerType($_self)">, + "integer type supported by EmitC">; + +def EmitCFloatType : Type<CPred<"emitc::isSupportedFloatType($_self)">, + "floating-point type supported by EmitC">; + class EmitC_Type<string name, string typeMnemonic, list<Trait> traits = []> : TypeDef<EmitC_Dialect, name, traits> { let mnemonic = typeMnemonic; diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp index e401a83bcb42..ab5c418e844f 100644 --- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp +++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp @@ -54,6 +54,35 @@ void mlir::emitc::buildTerminatedBody(OpBuilder &builder, Location loc) { builder.create<emitc::YieldOp>(loc); } +bool mlir::emitc::isSupportedIntegerType(Type type) { + if (auto intType = llvm::dyn_cast<IntegerType>(type)) { + switch (intType.getWidth()) { + case 1: + case 8: + case 16: + case 32: + case 64: + return true; + default: + return false; + } + } + return false; +} + +bool mlir::emitc::isSupportedFloatType(Type type) { + if (auto floatType = llvm::dyn_cast<FloatType>(type)) { + switch (floatType.getWidth()) { + case 32: + case 64: + return true; + default: + return false; + } + } + return false; +} + /// Check that the type of the initial value is compatible with the operations /// result type. static LogicalResult verifyInitializationAttribute(Operation *op, diff --git a/mlir/test/Dialect/EmitC/invalid_ops.mlir b/mlir/test/Dialect/EmitC/invalid_ops.mlir index 6294c853d999..22423cf61b55 100644 --- a/mlir/test/Dialect/EmitC/invalid_ops.mlir +++ b/mlir/test/Dialect/EmitC/invalid_ops.mlir @@ -170,7 +170,7 @@ func.func @add_float_pointer(%arg0: f32, %arg1: !emitc.ptr<f32>) { // ----- func.func @div_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) { - // expected-error @+1 {{'emitc.div' op operand #0 must be floating-point or integer or index or EmitC opaque type, but got 'tensor<i32>'}} + // expected-error @+1 {{'emitc.div' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'tensor<i32>'}} %1 = "emitc.div" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32> return } @@ -178,7 +178,7 @@ func.func @div_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) { // ----- func.func @mul_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) { - // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point or integer or index or EmitC opaque type, but got 'tensor<i32>'}} + // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'tensor<i32>'}} %1 = "emitc.mul" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32> return } @@ -186,7 +186,7 @@ func.func @mul_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) { // ----- func.func @rem_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) { - // expected-error @+1 {{'emitc.rem' op operand #0 must be integer or index or EmitC opaque type, but got 'tensor<i32>'}} + // expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC opaque type, but got 'tensor<i32>'}} %1 = "emitc.rem" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32> return } @@ -194,7 +194,7 @@ func.func @rem_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) { // ----- func.func @rem_float(%arg0: f32, %arg1: f32) { - // expected-error @+1 {{'emitc.rem' op operand #0 must be integer or index or EmitC opaque type, but got 'f32'}} + // expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC opaque type, but got 'f32'}} %1 = "emitc.rem" (%arg0, %arg1) : (f32, f32) -> f32 return } diff --git a/mlir/test/Dialect/EmitC/invalid_types.mlir b/mlir/test/Dialect/EmitC/invalid_types.mlir index 079371b39b9d..f9d517bf689b 100644 --- a/mlir/test/Dialect/EmitC/invalid_types.mlir +++ b/mlir/test/Dialect/EmitC/invalid_types.mlir @@ -81,3 +81,19 @@ func.func @illegal_array_with_tensor_element_type( %arg0: !emitc.array<4xtensor<4xi32>> ) { } + +// ----- + +func.func @illegal_integer_type(%arg0: i11, %arg1: i11) -> i11 { + // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'i11'}} + %mul = "emitc.mul" (%arg0, %arg1) : (i11, i11) -> i11 + return +} + +// ----- + +func.func @illegal_float_type(%arg0: f80, %arg1: f80) { + // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'f80'}} + %mul = "emitc.mul" (%arg0, %arg1) : (f80, f80) -> f80 + return +} -- GitLab From a9fe23cde3ee554f4bd6118edcc2e747f3a8d8d5 Mon Sep 17 00:00:00 2001 From: chrulski-intel <christopher.m.chrulski@intel.com> Date: Wed, 20 Mar 2024 08:02:43 -0700 Subject: [PATCH 255/307] [LLD] [COFF] Port -lto-sample-profile to COFF version of LLD (#85701) Following the commit of #83972 which added COFF support for SPGO, this patch ports the support of the option -lto-sample-profile that was only available in the ELF variant of LLD to the COFF variant to enable running the SPGO passes in the LTO/thinLTO pipelines. --- lld/COFF/Config.h | 3 +++ lld/COFF/Driver.cpp | 1 + lld/COFF/LTO.cpp | 1 + lld/COFF/Options.td | 1 + lld/test/COFF/Inputs/lto-sample-profile.prof | 1 + lld/test/COFF/lto-sample-profile.ll | 23 ++++++++++++++++++++ 6 files changed, 30 insertions(+) create mode 100644 lld/test/COFF/Inputs/lto-sample-profile.prof create mode 100644 lld/test/COFF/lto-sample-profile.ll diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 018f03b211e4..8f85929f1bea 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -263,6 +263,9 @@ struct Configuration { // Used for /lto-pgo-warn-mismatch: bool ltoPGOWarnMismatch = true; + // Used for /lto-sample-profile: + llvm::StringRef ltoSampleProfileName; + // Used for /call-graph-ordering-file: llvm::MapVector<std::pair<const SectionChunk *, const SectionChunk *>, uint64_t> diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 22ee2f133be9..1b075389325a 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2028,6 +2028,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) { config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path); config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate); config->ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file); + config->ltoSampleProfileName = args.getLastArgValue(OPT_lto_sample_profile); // Handle miscellaneous boolean flags. config->ltoPGOWarnMismatch = args.hasFlag(OPT_lto_pgo_warn_mismatch, OPT_lto_pgo_warn_mismatch_no, true); diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp index 7df931911213..be49aa6e8bb3 100644 --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -86,6 +86,7 @@ lto::Config BitcodeCompiler::createConfig() { c.CSIRProfile = std::string(ctx.config.ltoCSProfileFile); c.RunCSIRInstr = ctx.config.ltoCSProfileGenerate; c.PGOWarnMismatch = ctx.config.ltoPGOWarnMismatch; + c.SampleProfile = ctx.config.ltoSampleProfileName; c.TimeTraceEnabled = ctx.config.timeTraceEnabled; c.TimeTraceGranularity = ctx.config.timeTraceGranularity; diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index 4dab4a207173..1e78a560bca8 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -79,6 +79,7 @@ def lldltocachepolicy : P<"lldltocachepolicy", "Pruning policy for the ThinLTO cache">; def lldsavetemps : F<"lldsavetemps">, HelpText<"Save intermediate LTO compilation results">; +def lto_sample_profile: P<"lto-sample-profile", "Sample profile file path">; def machine : P<"machine", "Specify target platform">; def merge : P<"merge", "Combine sections">; def mllvm : P<"mllvm", "Options to pass to LLVM">; diff --git a/lld/test/COFF/Inputs/lto-sample-profile.prof b/lld/test/COFF/Inputs/lto-sample-profile.prof new file mode 100644 index 000000000000..0ccd747bd376 --- /dev/null +++ b/lld/test/COFF/Inputs/lto-sample-profile.prof @@ -0,0 +1 @@ +f:0:0 diff --git a/lld/test/COFF/lto-sample-profile.ll b/lld/test/COFF/lto-sample-profile.ll new file mode 100644 index 000000000000..64d4c8ab6328 --- /dev/null +++ b/lld/test/COFF/lto-sample-profile.ll @@ -0,0 +1,23 @@ +; REQUIRES: x86 +; RUN: opt -module-summary %s -o %t1.o +; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o + +; RUN: rm -f %t1.o.4.opt.bc +; RUN: lld-link /lto-sample-profile:%p/Inputs/lto-sample-profile.prof /lldsavetemps /entry:f /subsystem:console %t1.o %t2.o /out:%t3.exe +; RUN: opt -S %t1.o.4.opt.bc | FileCheck %s + +target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.0.24215" + +; CHECK: ![[#]] = !{i32 1, !"ProfileSummary", ![[#]]} +declare void @g(...) + +define void @h() { + ret void +} +define void @f() { +entry: + call void (...) @g() + call void (...) @h() + ret void +} -- GitLab From caf8b1f654122342dc846ae4d9a86d5c6f93f945 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme <thomas.preudhomme@arm.com> Date: Wed, 20 Mar 2024 15:04:10 +0000 Subject: [PATCH 256/307] [MLIR] Add missing MLIRDialectUtils dep to TilingInterface (#84544) This fixes the following failure when doing a clean build (in particular no .ninja* lying around) of lib/libMLIRTilingInterface.a only: ``` In file included from mlir/include/mlir/Interfaces/TilingInterface.h:17, from mlir/lib/Interfaces/TilingInterface.cpp:13: mlir/include/mlir/Dialect/Utils/StructuredOpsUtils.h:27:10: fatal error: mlir/Dialect/Utils/DialectUtilsEnums.h.inc: No such file or directory ``` --- mlir/lib/Interfaces/CMakeLists.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/mlir/lib/Interfaces/CMakeLists.txt b/mlir/lib/Interfaces/CMakeLists.txt index e7c76e70ed6b..d3b7bf65ad3e 100644 --- a/mlir/lib/Interfaces/CMakeLists.txt +++ b/mlir/lib/Interfaces/CMakeLists.txt @@ -101,7 +101,20 @@ add_mlir_library(MLIRSubsetOpInterface MLIRValueBoundsOpInterface ) -add_mlir_interface_library(TilingInterface) +add_mlir_library(MLIRTilingInterface + TilingInterface.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Interfaces + + DEPENDS + MLIRTilingInterfaceIncGen + MLIRDialectUtils + + LINK_LIBS PUBLIC + MLIRIR +) + add_mlir_interface_library(VectorInterfaces) add_mlir_interface_library(ViewLikeInterface) -- GitLab From 7812fcf3d79ef7fe9ec6bcdfc8fd9143864956cb Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <llvm-dev@redking.me.uk> Date: Wed, 20 Mar 2024 14:36:45 +0000 Subject: [PATCH 257/307] [VectorCombine] foldBitcastShuf - add support for binary shuffles (REAPPLIED) Generalise fold to "bitcast (shuf V0, V1, MaskC) --> shuf (bitcast V0), (bitcast V1), MaskC'". Reapplied with a clang codegen test fix. Further prep work for #67803 --- clang/test/CodeGen/X86/avx-shuffle-builtins.c | 9 +++-- .../Transforms/Vectorize/VectorCombine.cpp | 21 ++++++----- .../Transforms/PhaseOrdering/X86/pr67803.ll | 35 +++++++++++++++++-- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/clang/test/CodeGen/X86/avx-shuffle-builtins.c b/clang/test/CodeGen/X86/avx-shuffle-builtins.c index 9109247e534f..82be43bc0504 100644 --- a/clang/test/CodeGen/X86/avx-shuffle-builtins.c +++ b/clang/test/CodeGen/X86/avx-shuffle-builtins.c @@ -60,7 +60,8 @@ __m256 test_mm256_permute2f128_ps(__m256 a, __m256 b) { __m256i test_mm256_permute2f128_si256(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_permute2f128_si256 - // CHECK: shufflevector{{.*}} <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11> + // X64: shufflevector{{.*}}<i32 0, i32 1, i32 4, i32 5> + // X86: shufflevector{{.*}}<i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11> return _mm256_permute2f128_si256(a, b, 0x20); } @@ -104,7 +105,8 @@ __m256d test_mm256_insertf128_pd_0(__m256d a, __m128d b) { __m256i test_mm256_insertf128_si256_0(__m256i a, __m128i b) { // CHECK-LABEL: test_mm256_insertf128_si256_0 - // CHECK: shufflevector{{.*}}<i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15> + // X64: shufflevector{{.*}}<i32 0, i32 1, i32 6, i32 7> + // X86: shufflevector{{.*}}<i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15> return _mm256_insertf128_si256(a, b, 0); } @@ -122,7 +124,8 @@ __m256d test_mm256_insertf128_pd_1(__m256d a, __m128d b) { __m256i test_mm256_insertf128_si256_1(__m256i a, __m128i b) { // CHECK-LABEL: test_mm256_insertf128_si256_1 - // CHECK: shufflevector{{.*}}<i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11> + // X64: shufflevector{{.*}}<i32 0, i32 1, i32 4, i32 5> + // X86: shufflevector{{.*}}<i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11> return _mm256_insertf128_si256(a, b, 1); } diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp index 0b16a8b76769..23494314f132 100644 --- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp +++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp @@ -684,10 +684,10 @@ bool VectorCombine::foldInsExtFNeg(Instruction &I) { /// destination type followed by shuffle. This can enable further transforms by /// moving bitcasts or shuffles together. bool VectorCombine::foldBitcastShuffle(Instruction &I) { - Value *V0; + Value *V0, *V1; ArrayRef<int> Mask; if (!match(&I, m_BitCast(m_OneUse( - m_Shuffle(m_Value(V0), m_Undef(), m_Mask(Mask)))))) + m_Shuffle(m_Value(V0), m_Value(V1), m_Mask(Mask)))))) return false; // 1) Do not fold bitcast shuffle for scalable type. First, shuffle cost for @@ -728,17 +728,21 @@ bool VectorCombine::foldBitcastShuffle(Instruction &I) { FixedVectorType::get(DestTy->getScalarType(), NumSrcElts); auto *OldShuffleTy = FixedVectorType::get(SrcTy->getScalarType(), Mask.size()); + bool IsUnary = isa<UndefValue>(V1); + unsigned NumOps = IsUnary ? 1 : 2; // The new shuffle must not cost more than the old shuffle. TargetTransformInfo::TargetCostKind CK = TargetTransformInfo::TCK_RecipThroughput; TargetTransformInfo::ShuffleKind SK = - TargetTransformInfo::SK_PermuteSingleSrc; + IsUnary ? TargetTransformInfo::SK_PermuteSingleSrc + : TargetTransformInfo::SK_PermuteTwoSrc; InstructionCost DestCost = TTI.getShuffleCost(SK, NewShuffleTy, NewMask, CK) + - TTI.getCastInstrCost(Instruction::BitCast, NewShuffleTy, SrcTy, - TargetTransformInfo::CastContextHint::None, CK); + (NumOps * TTI.getCastInstrCost(Instruction::BitCast, NewShuffleTy, SrcTy, + TargetTransformInfo::CastContextHint::None, + CK)); InstructionCost SrcCost = TTI.getShuffleCost(SK, SrcTy, Mask, CK) + TTI.getCastInstrCost(Instruction::BitCast, DestTy, OldShuffleTy, @@ -746,10 +750,11 @@ bool VectorCombine::foldBitcastShuffle(Instruction &I) { if (DestCost > SrcCost || !DestCost.isValid()) return false; - // bitcast (shuf V0, MaskC) --> shuf (bitcast V0), MaskC' + // bitcast (shuf V0, V1, MaskC) --> shuf (bitcast V0), (bitcast V1), MaskC' ++NumShufOfBitcast; - Value *CastV = Builder.CreateBitCast(V0, NewShuffleTy); - Value *Shuf = Builder.CreateShuffleVector(CastV, NewMask); + Value *CastV0 = Builder.CreateBitCast(V0, NewShuffleTy); + Value *CastV1 = Builder.CreateBitCast(V1, NewShuffleTy); + Value *Shuf = Builder.CreateShuffleVector(CastV0, CastV1, NewMask); replaceValue(I, *Shuf); return true; } diff --git a/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll b/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll index 211c90b5604e..e61b254b7a5f 100644 --- a/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll +++ b/llvm/test/Transforms/PhaseOrdering/X86/pr67803.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s -; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s -; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s +; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=CHECK +; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=CHECK +; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=AVX512 define <4 x i64> @PR67803(<4 x i64> %x, <4 x i64> %y, <4 x i64> %a, <4 x i64> %b) { ; CHECK-LABEL: @PR67803( @@ -35,6 +35,35 @@ define <4 x i64> @PR67803(<4 x i64> %x, <4 x i64> %y, <4 x i64> %a, <4 x i64> %b ; CHECK-NEXT: [[SHUFFLE_I23:%.*]] = shufflevector <2 x i64> [[TMP12]], <2 x i64> [[TMP20]], <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; CHECK-NEXT: ret <4 x i64> [[SHUFFLE_I23]] ; +; AVX512-LABEL: @PR67803( +; AVX512-NEXT: entry: +; AVX512-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[X:%.*]] to <8 x i32> +; AVX512-NEXT: [[TMP1:%.*]] = bitcast <4 x i64> [[Y:%.*]] to <8 x i32> +; AVX512-NEXT: [[TMP2:%.*]] = icmp sgt <8 x i32> [[TMP0]], [[TMP1]] +; AVX512-NEXT: [[CMP_I21:%.*]] = shufflevector <8 x i1> [[TMP2]], <8 x i1> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3> +; AVX512-NEXT: [[SEXT_I22:%.*]] = sext <4 x i1> [[CMP_I21]] to <4 x i32> +; AVX512-NEXT: [[CMP_I:%.*]] = shufflevector <8 x i1> [[TMP2]], <8 x i1> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7> +; AVX512-NEXT: [[SEXT_I:%.*]] = sext <4 x i1> [[CMP_I]] to <4 x i32> +; AVX512-NEXT: [[TMP3:%.*]] = shufflevector <4 x i32> [[SEXT_I22]], <4 x i32> [[SEXT_I]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> +; AVX512-NEXT: [[TMP4:%.*]] = bitcast <4 x i64> [[A:%.*]] to <32 x i8> +; AVX512-NEXT: [[TMP5:%.*]] = shufflevector <32 x i8> [[TMP4]], <32 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> +; AVX512-NEXT: [[TMP6:%.*]] = bitcast <4 x i64> [[B:%.*]] to <32 x i8> +; AVX512-NEXT: [[TMP7:%.*]] = shufflevector <32 x i8> [[TMP6]], <32 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> +; AVX512-NEXT: [[TMP8:%.*]] = bitcast <8 x i32> [[TMP3]] to <32 x i8> +; AVX512-NEXT: [[TMP9:%.*]] = shufflevector <32 x i8> [[TMP8]], <32 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> +; AVX512-NEXT: [[TMP10:%.*]] = tail call <16 x i8> @llvm.x86.sse41.pblendvb(<16 x i8> [[TMP5]], <16 x i8> [[TMP7]], <16 x i8> [[TMP9]]) +; AVX512-NEXT: [[TMP11:%.*]] = bitcast <16 x i8> [[TMP10]] to <2 x i64> +; AVX512-NEXT: [[TMP12:%.*]] = bitcast <4 x i64> [[A]] to <32 x i8> +; AVX512-NEXT: [[TMP13:%.*]] = shufflevector <32 x i8> [[TMP12]], <32 x i8> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31> +; AVX512-NEXT: [[TMP14:%.*]] = bitcast <4 x i64> [[B]] to <32 x i8> +; AVX512-NEXT: [[TMP15:%.*]] = shufflevector <32 x i8> [[TMP14]], <32 x i8> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31> +; AVX512-NEXT: [[TMP16:%.*]] = bitcast <8 x i32> [[TMP3]] to <32 x i8> +; AVX512-NEXT: [[TMP17:%.*]] = shufflevector <32 x i8> [[TMP16]], <32 x i8> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31> +; AVX512-NEXT: [[TMP18:%.*]] = tail call <16 x i8> @llvm.x86.sse41.pblendvb(<16 x i8> [[TMP13]], <16 x i8> [[TMP15]], <16 x i8> [[TMP17]]) +; AVX512-NEXT: [[TMP19:%.*]] = bitcast <16 x i8> [[TMP18]] to <2 x i64> +; AVX512-NEXT: [[SHUFFLE_I23:%.*]] = shufflevector <2 x i64> [[TMP11]], <2 x i64> [[TMP19]], <4 x i32> <i32 0, i32 1, i32 2, i32 3> +; AVX512-NEXT: ret <4 x i64> [[SHUFFLE_I23]] +; entry: %0 = bitcast <4 x i64> %x to <8 x i32> %extract = shufflevector <8 x i32> %0, <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3> -- GitLab From 55c82f149c5065947f3de3fcde137e8172eee223 Mon Sep 17 00:00:00 2001 From: Alexey Bataev <a.bataev@outlook.com> Date: Wed, 20 Mar 2024 08:07:28 -0700 Subject: [PATCH 258/307] [SLP][NFC]Add a test with arguments of functions, reduced by minbitwidth analysis. --- .../cmp-after-intrinsic-call-minbitwidth.ll | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 llvm/test/Transforms/SLPVectorizer/X86/cmp-after-intrinsic-call-minbitwidth.ll diff --git a/llvm/test/Transforms/SLPVectorizer/X86/cmp-after-intrinsic-call-minbitwidth.ll b/llvm/test/Transforms/SLPVectorizer/X86/cmp-after-intrinsic-call-minbitwidth.ll new file mode 100644 index 000000000000..a05d4fdd6315 --- /dev/null +++ b/llvm/test/Transforms/SLPVectorizer/X86/cmp-after-intrinsic-call-minbitwidth.ll @@ -0,0 +1,40 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 +; RUN: opt --passes=slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu -mcpu=cascadelake < %s | FileCheck %s + +define void @test() { +; CHECK-LABEL: define void @test( +; CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> zeroinitializer, <2 x i32> zeroinitializer) +; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> zeroinitializer, <2 x i32> zeroinitializer, <2 x i32> [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i32> [[TMP1]], zeroinitializer +; CHECK-NEXT: [[ADD:%.*]] = extractelement <2 x i32> [[TMP2]], i32 1 +; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[ADD]], 0 +; CHECK-NEXT: [[ADD45:%.*]] = extractelement <2 x i32> [[TMP2]], i32 0 +; CHECK-NEXT: [[ADD152:%.*]] = or i32 [[ADD45]], [[ADD]] +; CHECK-NEXT: [[IDXPROM153:%.*]] = sext i32 [[ADD152]] to i64 +; CHECK-NEXT: [[ARRAYIDX154:%.*]] = getelementptr i8, ptr null, i64 [[IDXPROM153]] +; CHECK-NEXT: [[CALL155:%.*]] = tail call i32 null(ptr null, i32 0, ptr [[ARRAYIDX154]], i32 0) +; CHECK-NEXT: ret void +; +entry: + %conv = sext i16 0 to i32 + %cmp.i = icmp sgt i32 0, %conv + %cond.i = tail call i32 @llvm.smin.i32(i32 %conv, i32 0) + %cond5.i = select i1 %cmp.i, i32 0, i32 %cond.i + %conv43 = sext i16 0 to i32 + %cmp.i6193 = icmp sgt i32 0, %conv43 + %cond.i6194 = tail call i32 @llvm.smin.i32(i32 %conv43, i32 0) + %cond5.i6195 = select i1 %cmp.i6193, i32 0, i32 %cond.i6194 + %add = or i32 %cond5.i, 0 + %shr = ashr i32 %add, 0 + %add45 = or i32 %cond5.i6195, 0 + %add152 = or i32 %add45, %add + %idxprom153 = sext i32 %add152 to i64 + %arrayidx154 = getelementptr i8, ptr null, i64 %idxprom153 + %call155 = tail call i32 null(ptr null, i32 0, ptr %arrayidx154, i32 0) + ret void +} + +declare i32 @llvm.smin.i32(i32, i32) + -- GitLab From 4095a326c026a2b6dcb839a8c1c75906c6ba5b0a Mon Sep 17 00:00:00 2001 From: Christian Ulmann <christianulmann@gmail.com> Date: Wed, 20 Mar 2024 16:08:38 +0100 Subject: [PATCH 259/307] [MLIR][LLVM] Add extraData field to the DIDerivedType attribute (#85935) This commit extends the DIDerivedTypeAttr with the `extraData` field. For now, the type of it is limited to be a `DINodeAttr`, as extending the debug metadata handling to support arbitrary metadata nodes does not seem to be necessary so far. --- mlir/include/mlir-c/Dialect/LLVM.h | 2 +- .../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 3 ++- mlir/lib/CAPI/Dialect/LLVM.cpp | 19 +++++++++---------- mlir/lib/Target/LLVMIR/DebugImporter.cpp | 4 +++- mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 2 +- mlir/test/CAPI/llvm.c | 2 +- mlir/test/Dialect/LLVMIR/debuginfo.mlir | 5 +++-- mlir/test/Target/LLVMIR/Import/debug-info.ll | 4 ++-- mlir/test/Target/LLVMIR/llvmir-debug.mlir | 5 +++-- 9 files changed, 25 insertions(+), 21 deletions(-) diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h index b3d7a788ccbb..4f1d646f5bc8 100644 --- a/mlir/include/mlir-c/Dialect/LLVM.h +++ b/mlir/include/mlir-c/Dialect/LLVM.h @@ -238,7 +238,7 @@ MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDICompositeTypeAttrGet( MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIDerivedTypeAttrGet( MlirContext ctx, unsigned int tag, MlirAttribute name, MlirAttribute baseType, uint64_t sizeInBits, uint32_t alignInBits, - uint64_t offsetInBits); + uint64_t offsetInBits, MlirAttribute extraData); /// Gets the base type from a LLVM DIDerivedType attribute. MLIR_CAPI_EXPORTED MlirAttribute diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index d4d56ae0f762..1b1824a28e99 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -405,7 +405,8 @@ def LLVM_DIDerivedTypeAttr : LLVM_Attr<"DIDerivedType", "di_derived_type", OptionalParameter<"DITypeAttr">:$baseType, OptionalParameter<"uint64_t">:$sizeInBits, OptionalParameter<"uint32_t">:$alignInBits, - OptionalParameter<"uint64_t">:$offsetInBits + OptionalParameter<"uint64_t">:$offsetInBits, + OptionalParameter<"DINodeAttr">:$extraData ); let assemblyFormat = "`<` struct(params) `>`"; } diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp index d0fd5ceecfff..71f2b73dd73b 100644 --- a/mlir/lib/CAPI/Dialect/LLVM.cpp +++ b/mlir/lib/CAPI/Dialect/LLVM.cpp @@ -168,16 +168,15 @@ MlirAttribute mlirLLVMDICompositeTypeAttrGet( [](Attribute a) { return a.cast<DINodeAttr>(); }))); } -MlirAttribute mlirLLVMDIDerivedTypeAttrGet(MlirContext ctx, unsigned int tag, - MlirAttribute name, - MlirAttribute baseType, - uint64_t sizeInBits, - uint32_t alignInBits, - uint64_t offsetInBits) { - return wrap(DIDerivedTypeAttr::get(unwrap(ctx), tag, - cast<StringAttr>(unwrap(name)), - cast<DITypeAttr>(unwrap(baseType)), - sizeInBits, alignInBits, offsetInBits)); +MlirAttribute +mlirLLVMDIDerivedTypeAttrGet(MlirContext ctx, unsigned int tag, + MlirAttribute name, MlirAttribute baseType, + uint64_t sizeInBits, uint32_t alignInBits, + uint64_t offsetInBits, MlirAttribute extraData) { + return wrap(DIDerivedTypeAttr::get( + unwrap(ctx), tag, cast<StringAttr>(unwrap(name)), + cast<DITypeAttr>(unwrap(baseType)), sizeInBits, alignInBits, offsetInBits, + cast<DINodeAttr>(unwrap(extraData)))); } MlirAttribute diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp index 5ba90bba18b1..4bdc03a3e282 100644 --- a/mlir/lib/Target/LLVMIR/DebugImporter.cpp +++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp @@ -85,10 +85,12 @@ DIDerivedTypeAttr DebugImporter::translateImpl(llvm::DIDerivedType *node) { DITypeAttr baseType = translate(node->getBaseType()); if (node->getBaseType() && !baseType) return nullptr; + DINodeAttr extraData = + translate(dyn_cast_or_null<llvm::DINode>(node->getExtraData())); return DIDerivedTypeAttr::get( context, node->getTag(), getStringAttrOrNull(node->getRawName()), baseType, node->getSizeInBits(), node->getAlignInBits(), - node->getOffsetInBits()); + node->getOffsetInBits(), extraData); } DIFileAttr DebugImporter::translateImpl(llvm::DIFile *node) { diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp index 126a671a58e8..642359a23756 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -163,7 +163,7 @@ llvm::DIDerivedType *DebugTranslation::translateImpl(DIDerivedTypeAttr attr) { /*Scope=*/nullptr, translate(attr.getBaseType()), attr.getSizeInBits(), attr.getAlignInBits(), attr.getOffsetInBits(), /*DWARFAddressSpace=*/std::nullopt, /*PtrAuthData=*/std::nullopt, - /*Flags=*/llvm::DINode::FlagZero); + /*Flags=*/llvm::DINode::FlagZero, translate(attr.getExtraData())); } llvm::DIFile *DebugTranslation::translateImpl(DIFileAttr attr) { diff --git a/mlir/test/CAPI/llvm.c b/mlir/test/CAPI/llvm.c index 48b887ee4a95..9c3c7da46c4c 100644 --- a/mlir/test/CAPI/llvm.c +++ b/mlir/test/CAPI/llvm.c @@ -297,7 +297,7 @@ static void testDebugInfoAttributes(MlirContext ctx) { 1, 0, 8, di_type)); // CHECK: #llvm.di_derived_type<{{.*}}> mlirAttributeDump( - mlirLLVMDIDerivedTypeAttrGet(ctx, 0, bar, di_type, 64, 8, 0)); + mlirLLVMDIDerivedTypeAttrGet(ctx, 0, bar, di_type, 64, 8, 0, di_type)); // CHECK: #llvm.di_composite_type<{{.*}}> mlirAttributeDump(mlirLLVMDICompositeTypeAttrGet( diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir index cef2ced391d6..4c2de0aa4c22 100644 --- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir +++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir @@ -24,10 +24,11 @@ sizeInBits = 32, encoding = DW_ATE_signed > -// CHECK-DAG: #[[PTR0:.*]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, baseType = #[[INT0]], sizeInBits = 64, alignInBits = 32, offsetInBits = 4> +// CHECK-DAG: #[[PTR0:.*]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, baseType = #[[INT0]], sizeInBits = 64, alignInBits = 32, offsetInBits = 4, extraData = #[[INT1]]> #ptr0 = #llvm.di_derived_type< tag = DW_TAG_pointer_type, baseType = #int0, - sizeInBits = 64, alignInBits = 32, offsetInBits = 4 + sizeInBits = 64, alignInBits = 32, offsetInBits = 4, + extraData = #int1 > // CHECK-DAG: #[[PTR1:.*]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, name = "ptr1"> diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll index 9af40d8c8d3e..a7947eb0d444 100644 --- a/mlir/test/Target/LLVMIR/Import/debug-info.ll +++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll @@ -136,7 +136,7 @@ define void @basic_type() !dbg !3 { ; CHECK: #[[INT:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int"> ; CHECK: #[[PTR1:.+]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, baseType = #[[INT]]> -; CHECK: #[[PTR2:.+]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, name = "mypointer", baseType = #[[INT]], sizeInBits = 64, alignInBits = 32, offsetInBits = 4> +; CHECK: #[[PTR2:.+]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, name = "mypointer", baseType = #[[INT]], sizeInBits = 64, alignInBits = 32, offsetInBits = 4, extraData = #[[INT]]> ; CHECK: #llvm.di_subroutine_type<types = #[[PTR1]], #[[PTR2]]> define void @derived_type() !dbg !3 { @@ -153,7 +153,7 @@ define void @derived_type() !dbg !3 { !5 = !{!7, !8} !6 = !DIBasicType(name: "int") !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6) -!8 = !DIDerivedType(name: "mypointer", tag: DW_TAG_pointer_type, baseType: !6, size: 64, align: 32, offset: 4) +!8 = !DIDerivedType(name: "mypointer", tag: DW_TAG_pointer_type, baseType: !6, size: 64, align: 32, offset: 4, extraData: !6) ; // ----- diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir index c042628334d4..c34f9187d4df 100644 --- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir @@ -28,7 +28,8 @@ llvm.func @func_no_debug() { > #ptr = #llvm.di_derived_type< tag = DW_TAG_pointer_type, baseType = #si32, - sizeInBits = 64, alignInBits = 32, offsetInBits = 8 + sizeInBits = 64, alignInBits = 32, offsetInBits = 8, + extraData = #si32 > #named = #llvm.di_derived_type< // Specify the name parameter. @@ -135,7 +136,7 @@ llvm.func @empty_types() { // CHECK: ![[FUNC_TYPE]] = !DISubroutineType(cc: DW_CC_normal, types: ![[FUNC_ARGS:.*]]) // CHECK: ![[FUNC_ARGS]] = !{null, ![[ARG_TYPE:.*]], ![[PTR_TYPE:.*]], ![[NAMED_TYPE:.*]], ![[COMPOSITE_TYPE:.*]], ![[VECTOR_TYPE:.*]]} // CHECK: ![[ARG_TYPE]] = !DIBasicType(name: "si64") -// CHECK: ![[PTR_TYPE]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[BASE_TYPE:.*]], size: 64, align: 32, offset: 8) +// CHECK: ![[PTR_TYPE]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[BASE_TYPE:.*]], size: 64, align: 32, offset: 8, extraData: ![[BASE_TYPE]]) // CHECK: ![[BASE_TYPE]] = !DIBasicType(name: "si32", size: 32, encoding: DW_ATE_signed) // CHECK: ![[NAMED_TYPE]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "named", baseType: ![[BASE_TYPE:.*]]) // CHECK: ![[COMPOSITE_TYPE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "composite", file: ![[CU_FILE_LOC]], line: 42, size: 64, align: 32, elements: ![[COMPOSITE_ELEMENTS:.*]]) -- GitLab From aa8cffb9583afb583b7a329a56cbd1c7b743f6a3 Mon Sep 17 00:00:00 2001 From: ChiaHungDuan <chiahungduan@google.com> Date: Wed, 20 Mar 2024 08:15:47 -0700 Subject: [PATCH 260/307] [scudo] Fix type mismatch on DefaultMaxEntrySize (#85897) --- .../lib/scudo/standalone/allocator_config.def | 2 +- .../scudo/standalone/allocator_config_wrapper.h | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/scudo/standalone/allocator_config.def b/compiler-rt/lib/scudo/standalone/allocator_config.def index 92f4e39872d4..c50aadad2d63 100644 --- a/compiler-rt/lib/scudo/standalone/allocator_config.def +++ b/compiler-rt/lib/scudo/standalone/allocator_config.def @@ -110,7 +110,7 @@ SECONDARY_REQUIRED_TEMPLATE_TYPE(CacheT) SECONDARY_CACHE_OPTIONAL(const u32, EntriesArraySize, 0) SECONDARY_CACHE_OPTIONAL(const u32, QuarantineSize, 0) SECONDARY_CACHE_OPTIONAL(const u32, DefaultMaxEntriesCount, 0) -SECONDARY_CACHE_OPTIONAL(const u32, DefaultMaxEntrySize, 0) +SECONDARY_CACHE_OPTIONAL(const uptr, DefaultMaxEntrySize, 0) SECONDARY_CACHE_OPTIONAL(const s32, MinReleaseToOsIntervalMs, INT32_MIN) SECONDARY_CACHE_OPTIONAL(const s32, MaxReleaseToOsIntervalMs, INT32_MAX) diff --git a/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h b/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h index a51d770b4664..5477236ac1f3 100644 --- a/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h +++ b/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h @@ -27,6 +27,19 @@ template <typename T> struct voidAdaptor { using type = void; }; +// This is used for detecting the case that defines the flag with wrong type and +// it'll be viewed as undefined optional flag. +template <typename L, typename R> struct assertSameType { + template <typename, typename> struct isSame { + static constexpr bool value = false; + }; + template <typename T> struct isSame<T, T> { + static constexpr bool value = true; + }; + static_assert(isSame<L, R>::value, "Flag type mismatches"); + using type = R; +}; + } // namespace namespace scudo { @@ -36,7 +49,8 @@ namespace scudo { static constexpr removeConst<TYPE>::type getValue() { return DEFAULT; } \ }; \ template <typename Config> \ - struct NAME##State<Config, decltype(Config::MEMBER)> { \ + struct NAME##State< \ + Config, typename assertSameType<decltype(Config::MEMBER), TYPE>::type> { \ static constexpr removeConst<TYPE>::type getValue() { \ return Config::MEMBER; \ } \ -- GitLab From 48a1a9b26048d2a88eaf5b09de0525ab557615de Mon Sep 17 00:00:00 2001 From: Chris B <chris.bieneman@me.com> Date: Wed, 20 Mar 2024 10:16:17 -0500 Subject: [PATCH 261/307] [HLSL][docs] Document hlsl.h in the HLSL docs (#84081) This adds a brief blurb about hlsl.h in the HLSLSupport documentation where a high level view of the architecture is explained. --- clang/docs/HLSL/HLSLSupport.rst | 50 ++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/clang/docs/HLSL/HLSLSupport.rst b/clang/docs/HLSL/HLSLSupport.rst index b091c17fd2a7..2d309ddff2f3 100644 --- a/clang/docs/HLSL/HLSLSupport.rst +++ b/clang/docs/HLSL/HLSLSupport.rst @@ -91,7 +91,7 @@ performance win for HLSL. If precompiled headers are used when compiling HLSL, the ``ExternalSemaSource`` will be a ``MultiplexExternalSemaSource`` which includes both the ``ASTReader`` -and ``HLSLExternalSemaSource``. For Built-in declarations that are already +and -. For Built-in declarations that are already completed in the serialized AST, the ``HLSLExternalSemaSource`` will reuse the existing declarations and not introduce new declarations. If the built-in types are not completed in the serialized AST, the ``HLSLExternalSemaSource`` will @@ -114,6 +114,54 @@ not re-targetable, we want to share the Clang CodeGen implementation for HLSL with other GPU graphics targets like SPIR-V and possibly other GPU and even CPU targets. +hlsl.h +------ + +HLSL has a library of standalone functions. This is similar to OpenCL and CUDA, +and is analogous to C's standard library. The implementation approach for the +HLSL library functionality draws from patterns in use by OpenCL and other Clang +resource headers. All of the clang resource headers are part of the +``ClangHeaders`` component found in the source tree under +`clang/lib/Headers <https://github.com/llvm/llvm-project/tree/main/clang/lib/Headers>`_. + +.. note:: + + HLSL's complex data types are not defined in HLSL's header because many of + the semantics of those data types cannot be expressed in HLSL due to missing + language features. Data types that can't be expressed in HLSL are defined in + code in the ``HLSLExternalSemaSource``. + +Similar to OpenCL, the HLSL library functionality is implicitly declared in +translation units without needing to include a header to provide declarations. +In Clang this is handled by making ``hlsl.h`` an implicitly included header +distributed as part of the Clang resource directory. + +Similar to OpenCL, HLSL's implicit header will explicitly declare all overloads, +and each overload will map to a corresponding ``__builtin*`` compiler intrinsic +that is handled in ClangCodeGen. CUDA uses a similar pattern although many CUDA +functions have full definitions in the included headers which in turn call +corresponding ``__builtin*`` compiler intrinsics. By not having bodies HLSL +avoids the need for the inliner to clean up and inline large numbers of small +library functions. + +HLSL's implicit headers also define some of HLSL's typedefs. This is consistent +with how the AVX vector header is implemented. + +Concerns have been expressed that this approach may result in slower compile +times than the approach DXC uses where library functions are treated more like +Clang ``__builtin*`` intrinsics. No real world use cases have been identified +where parsing is a significant compile-time overhead, but the HLSL implicit +headers can be compiled into a module for performance if needed. + +Further, by treating these as functions rather than ``__builtin*`` compiler +intrinsics, the language behaviors are more consistent and aligned with user +expectation because normal overload resolution rules and implicit conversions +apply as expected. + +It is a feature of this design that clangd-powered "go to declaration" for +library functions will jump to a valid header declaration and all overloads will +be user readable. + HLSL Language ============= -- GitLab From 927308a52bc51ae786db1bd645ad5ef5889fdb2a Mon Sep 17 00:00:00 2001 From: Gheorghe-Teodor Bercea <doru.bercea@amd.com> Date: Wed, 20 Mar 2024 11:22:01 -0400 Subject: [PATCH 262/307] [libomptarget][nextgen-plugin] Use SCRELEASE/SCACQUIRE in packet headers (#85678) This patch updates the construction of packet headers to replace the usage of ACQUIRE/RELEASE with SCACQUIRE/SCRELEASE which is now recommended. The patch also ensures consistency across kernel dispatches. --- libc/utils/gpu/loader/amdgpu/Loader.cpp | 3 ++- .../plugins-nextgen/amdgpu/src/rtl.cpp | 23 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/libc/utils/gpu/loader/amdgpu/Loader.cpp b/libc/utils/gpu/loader/amdgpu/Loader.cpp index e3911eda2bd8..7fd45acfd47e 100644 --- a/libc/utils/gpu/loader/amdgpu/Loader.cpp +++ b/libc/utils/gpu/loader/amdgpu/Loader.cpp @@ -276,7 +276,8 @@ hsa_status_t launch_kernel(hsa_agent_t dev_agent, hsa_executable_t executable, (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE) | (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE); uint32_t header_word = header | (setup << 16u); - __atomic_store_n((uint32_t *)&packet->header, header_word, __ATOMIC_RELEASE); + __atomic_store_n(reinterpret_cast<uint32_t *>(packet), header_word, + __ATOMIC_RELEASE); hsa_signal_store_relaxed(queue->doorbell_signal, packet_id); // Wait until the kernel has completed execution on the device. Periodically diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp b/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp index fce7454bf280..c147cefe58e9 100644 --- a/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp +++ b/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp @@ -826,15 +826,15 @@ private: /// Assumes the queue lock is acquired. void publishKernelPacket(uint64_t PacketId, uint16_t Setup, hsa_kernel_dispatch_packet_t *Packet) { - uint32_t *PacketPtr = reinterpret_cast<uint32_t *>(Packet); - - uint16_t Header = HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE; - Header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE; - Header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE; + uint16_t Header = + (HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE) | + (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE) | + (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE); // Publish the packet. Do not modify the package after this point. uint32_t HeaderWord = Header | (Setup << 16u); - __atomic_store_n(PacketPtr, HeaderWord, __ATOMIC_RELEASE); + __atomic_store_n(reinterpret_cast<uint32_t *>(Packet), HeaderWord, + __ATOMIC_RELEASE); // Signal the doorbell about the published packet. hsa_signal_store_relaxed(Queue->doorbell_signal, PacketId); @@ -845,15 +845,16 @@ private: /// barrier dependencies (signals) are satisfied. Assumes the queue is locked void publishBarrierPacket(uint64_t PacketId, hsa_barrier_and_packet_t *Packet) { - uint32_t *PacketPtr = reinterpret_cast<uint32_t *>(Packet); uint16_t Setup = 0; - uint16_t Header = HSA_PACKET_TYPE_BARRIER_AND << HSA_PACKET_HEADER_TYPE; - Header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE; - Header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE; + uint16_t Header = + (HSA_PACKET_TYPE_BARRIER_AND << HSA_PACKET_HEADER_TYPE) | + (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE) | + (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE); // Publish the packet. Do not modify the package after this point. uint32_t HeaderWord = Header | (Setup << 16u); - __atomic_store_n(PacketPtr, HeaderWord, __ATOMIC_RELEASE); + __atomic_store_n(reinterpret_cast<uint32_t *>(Packet), HeaderWord, + __ATOMIC_RELEASE); // Signal the doorbell about the published packet. hsa_signal_store_relaxed(Queue->doorbell_signal, PacketId); -- GitLab From 04f7cd7f4545f3368ccda625cadbe3265c3566c9 Mon Sep 17 00:00:00 2001 From: Alexey Bataev <a.bataev@outlook.com> Date: Wed, 20 Mar 2024 08:28:40 -0700 Subject: [PATCH 263/307] [SLP][NFC]Make findBestRootPair() member function constant. --- llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 5d59f35f3081..a52064e5417b 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -2239,7 +2239,7 @@ public: /// of the cost, considered to be good enough score. std::optional<int> findBestRootPair(ArrayRef<std::pair<Value *, Value *>> Candidates, - int Limit = LookAheadHeuristics::ScoreFail) { + int Limit = LookAheadHeuristics::ScoreFail) const { LookAheadHeuristics LookAhead(*TLI, *DL, *SE, *this, /*NumLanes=*/2, RootLookAheadMaxDepth); int BestScore = Limit; -- GitLab From c25e77436ea44b4c980f4974dee8984298d13a08 Mon Sep 17 00:00:00 2001 From: Gheorghe-Teodor Bercea <doru.bercea@amd.com> Date: Wed, 20 Mar 2024 11:40:12 -0400 Subject: [PATCH 264/307] Revert "[libomptarget][nextgen-plugin] Use SCRELEASE/SCACQUIRE in packet headers" (#85950) Reverts llvm/llvm-project#85678 --- libc/utils/gpu/loader/amdgpu/Loader.cpp | 3 +-- .../plugins-nextgen/amdgpu/src/rtl.cpp | 23 +++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/libc/utils/gpu/loader/amdgpu/Loader.cpp b/libc/utils/gpu/loader/amdgpu/Loader.cpp index 7fd45acfd47e..e3911eda2bd8 100644 --- a/libc/utils/gpu/loader/amdgpu/Loader.cpp +++ b/libc/utils/gpu/loader/amdgpu/Loader.cpp @@ -276,8 +276,7 @@ hsa_status_t launch_kernel(hsa_agent_t dev_agent, hsa_executable_t executable, (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE) | (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE); uint32_t header_word = header | (setup << 16u); - __atomic_store_n(reinterpret_cast<uint32_t *>(packet), header_word, - __ATOMIC_RELEASE); + __atomic_store_n((uint32_t *)&packet->header, header_word, __ATOMIC_RELEASE); hsa_signal_store_relaxed(queue->doorbell_signal, packet_id); // Wait until the kernel has completed execution on the device. Periodically diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp b/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp index c147cefe58e9..fce7454bf280 100644 --- a/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp +++ b/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp @@ -826,15 +826,15 @@ private: /// Assumes the queue lock is acquired. void publishKernelPacket(uint64_t PacketId, uint16_t Setup, hsa_kernel_dispatch_packet_t *Packet) { - uint16_t Header = - (HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE) | - (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE) | - (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE); + uint32_t *PacketPtr = reinterpret_cast<uint32_t *>(Packet); + + uint16_t Header = HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE; + Header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE; + Header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE; // Publish the packet. Do not modify the package after this point. uint32_t HeaderWord = Header | (Setup << 16u); - __atomic_store_n(reinterpret_cast<uint32_t *>(Packet), HeaderWord, - __ATOMIC_RELEASE); + __atomic_store_n(PacketPtr, HeaderWord, __ATOMIC_RELEASE); // Signal the doorbell about the published packet. hsa_signal_store_relaxed(Queue->doorbell_signal, PacketId); @@ -845,16 +845,15 @@ private: /// barrier dependencies (signals) are satisfied. Assumes the queue is locked void publishBarrierPacket(uint64_t PacketId, hsa_barrier_and_packet_t *Packet) { + uint32_t *PacketPtr = reinterpret_cast<uint32_t *>(Packet); uint16_t Setup = 0; - uint16_t Header = - (HSA_PACKET_TYPE_BARRIER_AND << HSA_PACKET_HEADER_TYPE) | - (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE) | - (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE); + uint16_t Header = HSA_PACKET_TYPE_BARRIER_AND << HSA_PACKET_HEADER_TYPE; + Header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE; + Header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE; // Publish the packet. Do not modify the package after this point. uint32_t HeaderWord = Header | (Setup << 16u); - __atomic_store_n(reinterpret_cast<uint32_t *>(Packet), HeaderWord, - __ATOMIC_RELEASE); + __atomic_store_n(PacketPtr, HeaderWord, __ATOMIC_RELEASE); // Signal the doorbell about the published packet. hsa_signal_store_relaxed(Queue->doorbell_signal, PacketId); -- GitLab From 767e0c8bcef9cfcc57e76e66e23489ba60042762 Mon Sep 17 00:00:00 2001 From: Thomas Lively <tlively@google.com> Date: Wed, 20 Mar 2024 08:42:42 -0700 Subject: [PATCH 265/307] [WebAssembly] Select BUILD_VECTOR with large unsigned lane values (#85880) Previously we expected lane constants to be in the range of signed values for each lane size, but the included test case produced large unsigned values that fall outside that range. Allow instruction selection to proceed in this case rather than failing. Fixes #63817. --- .../Target/WebAssembly/WebAssemblyInstrSIMD.td | 6 ++++-- llvm/test/CodeGen/WebAssembly/pr63817.ll | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/WebAssembly/pr63817.ll diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index 8cd41d7017a0..af95dfa25a18 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -46,10 +46,12 @@ defm "" : ARGUMENT<V128, v2i64>; defm "" : ARGUMENT<V128, v4f32>; defm "" : ARGUMENT<V128, v2f64>; -// Constrained immediate argument types +// Constrained immediate argument types. Allow any value from the minimum signed +// value to the maximum unsigned value for the lane size. foreach SIZE = [8, 16] in def ImmI#SIZE : ImmLeaf<i32, - "return -(1 << ("#SIZE#" - 1)) <= Imm && Imm < (1 << ("#SIZE#" - 1));" + // -2^(n-1) <= Imm < 2^n + "return -(1 << ("#SIZE#" - 1)) <= Imm && Imm < (1 << "#SIZE#");" >; foreach SIZE = [2, 4, 8, 16, 32] in def LaneIdx#SIZE : ImmLeaf<i32, "return 0 <= Imm && Imm < "#SIZE#";">; diff --git a/llvm/test/CodeGen/WebAssembly/pr63817.ll b/llvm/test/CodeGen/WebAssembly/pr63817.ll new file mode 100644 index 000000000000..252768d43f18 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/pr63817.ll @@ -0,0 +1,15 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=wasm32 -mattr=+simd128 | FileCheck %s + +;; Regression test for a bug in which BUILD_VECTOR nodes with large unsigned +;; lane constants were not properly selected. +define <4 x i8> @test(<4 x i8> %0) { +; CHECK-LABEL: test: +; CHECK: .functype test (v128) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: v128.const 255, 17, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +; CHECK-NEXT: # fallthrough-return + %V1 = or <4 x i8> <i8 255, i8 255, i8 255, i8 255>, %0 + %V2 = insertelement <4 x i8> %V1, i8 17, i32 1 + ret <4 x i8> %V2 +} -- GitLab From 576d81baa5cf1801bae0fd05892be34acde33c6a Mon Sep 17 00:00:00 2001 From: Craig Topper <craig.topper@sifive.com> Date: Wed, 20 Mar 2024 08:44:24 -0700 Subject: [PATCH 266/307] [RISCV] Use REG_SEQUENCE/EXTRACT_SUBREG to move between individual GPRs and GPRPair. (#85887) Previously we used memory like we do to move between GPRs and FPR64 with the D extension on RV32. We can instead use REG_SEQUENCE/EXTRACT_SUBREG to inform register allocation how to do the copy without memory. --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 37 ++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 17 +- llvm/lib/Target/RISCV/RISCVInstrInfoD.td | 14 - .../test/CodeGen/RISCV/double-arith-strict.ll | 174 -------- llvm/test/CodeGen/RISCV/double-arith.ll | 358 --------------- .../RISCV/double-bitmanip-dagcombines.ll | 14 - llvm/test/CodeGen/RISCV/double-br-fcmp.ll | 210 ++------- .../test/CodeGen/RISCV/double-calling-conv.ll | 45 +- .../CodeGen/RISCV/double-convert-strict.ll | 78 ---- llvm/test/CodeGen/RISCV/double-convert.ll | 243 ++--------- llvm/test/CodeGen/RISCV/double-fcmp-strict.ll | 400 +++-------------- llvm/test/CodeGen/RISCV/double-fcmp.ll | 140 ------ llvm/test/CodeGen/RISCV/double-imm.ll | 32 +- .../CodeGen/RISCV/double-intrinsics-strict.ll | 72 +--- llvm/test/CodeGen/RISCV/double-intrinsics.ll | 127 +----- llvm/test/CodeGen/RISCV/double-isnan.ll | 12 - .../CodeGen/RISCV/double-maximum-minimum.ll | 136 ++---- llvm/test/CodeGen/RISCV/double-mem.ll | 86 +--- .../CodeGen/RISCV/double-previous-failure.ll | 4 - .../CodeGen/RISCV/double-round-conv-sat.ll | 408 ++++++------------ llvm/test/CodeGen/RISCV/double-round-conv.ll | 210 --------- llvm/test/CodeGen/RISCV/double-select-fcmp.ll | 237 ---------- llvm/test/CodeGen/RISCV/double-select-icmp.ll | 224 +++------- .../RISCV/double-stack-spill-restore.ll | 40 +- .../CodeGen/RISCV/fastcc-without-f-reg.ll | 32 +- .../test/CodeGen/RISCV/half-convert-strict.ll | 24 -- llvm/test/CodeGen/RISCV/half-convert.ll | 50 +-- llvm/test/CodeGen/RISCV/pr64645.ll | 26 -- .../CodeGen/RISCV/zdinx-asm-constraint.ll | 16 +- .../CodeGen/RISCV/zdinx-boundary-check.ll | 38 +- 30 files changed, 469 insertions(+), 3035 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 1b8c1434c9f2..55ba4949b3ea 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -1007,7 +1007,44 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { ReplaceNode(Node, Res); return; } + case RISCVISD::BuildPairF64: { + if (!Subtarget->hasStdExtZdinx()) + break; + + assert(!Subtarget->is64Bit() && "Unexpected subtarget"); + + SDValue Ops[] = { + CurDAG->getTargetConstant(RISCV::GPRPairRegClassID, DL, MVT::i32), + Node->getOperand(0), + CurDAG->getTargetConstant(RISCV::sub_gpr_even, DL, MVT::i32), + Node->getOperand(1), + CurDAG->getTargetConstant(RISCV::sub_gpr_odd, DL, MVT::i32)}; + + SDNode *N = + CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, MVT::f64, Ops); + ReplaceNode(Node, N); + return; + } case RISCVISD::SplitF64: { + if (Subtarget->hasStdExtZdinx()) { + assert(!Subtarget->is64Bit() && "Unexpected subtarget"); + + if (!SDValue(Node, 0).use_empty()) { + SDValue Lo = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_even, DL, VT, + Node->getOperand(0)); + ReplaceUses(SDValue(Node, 0), Lo); + } + + if (!SDValue(Node, 1).use_empty()) { + SDValue Hi = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_odd, DL, VT, + Node->getOperand(0)); + ReplaceUses(SDValue(Node, 1), Hi); + } + + CurDAG->RemoveDeadNode(Node); + return; + } + if (!Subtarget->hasStdExtZfa()) break; assert(Subtarget->hasStdExtD() && !Subtarget->is64Bit() && diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 4bfd4d0386a8..25f035e6dd9d 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -17142,9 +17142,7 @@ static MachineBasicBlock *emitReadCounterWidePseudo(MachineInstr &MI, static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI, MachineBasicBlock *BB, const RISCVSubtarget &Subtarget) { - assert((MI.getOpcode() == RISCV::SplitF64Pseudo || - MI.getOpcode() == RISCV::SplitF64Pseudo_INX) && - "Unexpected instruction"); + assert(MI.getOpcode() == RISCV::SplitF64Pseudo && "Unexpected instruction"); MachineFunction &MF = *BB->getParent(); DebugLoc DL = MI.getDebugLoc(); @@ -17154,9 +17152,7 @@ static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI, Register HiReg = MI.getOperand(1).getReg(); Register SrcReg = MI.getOperand(2).getReg(); - const TargetRegisterClass *SrcRC = MI.getOpcode() == RISCV::SplitF64Pseudo_INX - ? &RISCV::GPRPairRegClass - : &RISCV::FPR64RegClass; + const TargetRegisterClass *SrcRC = &RISCV::FPR64RegClass; int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex(MF); TII.storeRegToStackSlot(*BB, MI, SrcReg, MI.getOperand(2).isKill(), FI, SrcRC, @@ -17181,8 +17177,7 @@ static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI, static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI, MachineBasicBlock *BB, const RISCVSubtarget &Subtarget) { - assert((MI.getOpcode() == RISCV::BuildPairF64Pseudo || - MI.getOpcode() == RISCV::BuildPairF64Pseudo_INX) && + assert(MI.getOpcode() == RISCV::BuildPairF64Pseudo && "Unexpected instruction"); MachineFunction &MF = *BB->getParent(); @@ -17193,9 +17188,7 @@ static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI, Register LoReg = MI.getOperand(1).getReg(); Register HiReg = MI.getOperand(2).getReg(); - const TargetRegisterClass *DstRC = - MI.getOpcode() == RISCV::BuildPairF64Pseudo_INX ? &RISCV::GPRPairRegClass - : &RISCV::FPR64RegClass; + const TargetRegisterClass *DstRC = &RISCV::FPR64RegClass; int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex(MF); MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(MF, FI); @@ -17716,10 +17709,8 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, case RISCV::Select_FPR64IN32X_Using_CC_GPR: return emitSelectPseudo(MI, BB, Subtarget); case RISCV::BuildPairF64Pseudo: - case RISCV::BuildPairF64Pseudo_INX: return emitBuildPairF64Pseudo(MI, BB, Subtarget); case RISCV::SplitF64Pseudo: - case RISCV::SplitF64Pseudo_INX: return emitSplitF64Pseudo(MI, BB, Subtarget); case RISCV::PseudoQuietFLE_H: return emitQuietFCMP(MI, BB, RISCV::FLE_H, RISCV::FEQ_H, Subtarget); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td index 9b4f93d55e33..8efefee383a6 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td @@ -524,20 +524,6 @@ let isCall = 0, mayLoad = 0, mayStore = 1, Size = 8, isCodeGenOnly = 1 in def PseudoRV32ZdinxSD : Pseudo<(outs), (ins GPRPair:$rs2, GPRNoX0:$rs1, simm12:$imm12), []>; def : Pat<(store (f64 GPRPair:$rs2), (AddrRegImmINX (XLenVT GPR:$rs1), simm12:$imm12)), (PseudoRV32ZdinxSD GPRPair:$rs2, GPR:$rs1, simm12:$imm12)>; - -/// Pseudo-instructions needed for the soft-float ABI with RV32D - -// Moves two GPRs to an FPR. -let usesCustomInserter = 1 in -def BuildPairF64Pseudo_INX - : Pseudo<(outs FPR64IN32X:$dst), (ins GPR:$src1, GPR:$src2), - [(set FPR64IN32X:$dst, (RISCVBuildPairF64 GPR:$src1, GPR:$src2))]>; - -// Moves an FPR to two GPRs. -let usesCustomInserter = 1 in -def SplitF64Pseudo_INX - : Pseudo<(outs GPR:$dst1, GPR:$dst2), (ins FPR64IN32X:$src), - [(set GPR:$dst1, GPR:$dst2, (RISCVSplitF64 FPR64IN32X:$src))]>; } // Predicates = [HasStdExtZdinx, IsRV32] let Predicates = [HasStdExtD] in { diff --git a/llvm/test/CodeGen/RISCV/double-arith-strict.ll b/llvm/test/CodeGen/RISCV/double-arith-strict.ll index 186175537772..23336933abff 100644 --- a/llvm/test/CodeGen/RISCV/double-arith-strict.ll +++ b/llvm/test/CodeGen/RISCV/double-arith-strict.ll @@ -24,21 +24,7 @@ define double @fadd_d(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fadd_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fadd_d: @@ -76,21 +62,7 @@ define double @fsub_d(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fsub_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fsub.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fsub_d: @@ -128,21 +100,7 @@ define double @fmul_d(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fmul_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmul.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmul_d: @@ -180,21 +138,7 @@ define double @fdiv_d(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fdiv_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fdiv.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fdiv_d: @@ -232,17 +176,7 @@ define double @fsqrt_d(double %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fsqrt_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fsqrt.d a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fsqrt_d: @@ -398,25 +332,7 @@ define double @fmadd_d(double %a, double %b, double %c) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fmadd_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmadd_d: @@ -463,27 +379,9 @@ define double @fmsub_d(double %a, double %b, double %c) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fmsub_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 ; RV32IZFINXZDINX-NEXT: fmsub.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmsub_d: @@ -572,28 +470,10 @@ define double @fnmadd_d(double %a, double %b, double %c) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fnmadd_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6 ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 ; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmadd_d: @@ -701,28 +581,10 @@ define double @fnmadd_d_2(double %a, double %b, double %c) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fnmadd_d_2: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6 ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 ; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a2, a0, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmadd_d_2: @@ -829,27 +691,9 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fnmsub_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6 ; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmsub_d: @@ -932,27 +776,9 @@ define double @fnmsub_d_2(double %a, double %b, double %c) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fnmsub_d_2: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6 ; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a2, a0, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmsub_d_2: diff --git a/llvm/test/CodeGen/RISCV/double-arith.ll b/llvm/test/CodeGen/RISCV/double-arith.ll index 82ddf06187d3..a2093f5b5e43 100644 --- a/llvm/test/CodeGen/RISCV/double-arith.ll +++ b/llvm/test/CodeGen/RISCV/double-arith.ll @@ -25,21 +25,7 @@ define double @fadd_d(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fadd_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fadd_d: @@ -76,21 +62,7 @@ define double @fsub_d(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fsub_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fsub.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fsub_d: @@ -127,21 +99,7 @@ define double @fmul_d(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmul_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmul.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmul_d: @@ -178,21 +136,7 @@ define double @fdiv_d(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fdiv_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fdiv.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fdiv_d: @@ -231,17 +175,7 @@ define double @fsqrt_d(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fsqrt_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fsqrt.d a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fsqrt_d: @@ -280,21 +214,7 @@ define double @fsgnj_d(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fsgnj_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fsgnj.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fsgnj_d: @@ -335,15 +255,9 @@ define i32 @fneg_d(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fneg_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: fneg.d a2, a0 ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fneg_d: @@ -401,21 +315,7 @@ define double @fsgnjn_d(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fsgnjn_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fsgnjn.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fsgnjn_d: @@ -464,23 +364,9 @@ define double @fabs_d(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fabs_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: fabs.d a2, a0 ; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fabs_d: @@ -532,21 +418,7 @@ define double @fmin_d(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmin_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmin_d: @@ -585,21 +457,7 @@ define double @fmax_d(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmax_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmax_d: @@ -638,25 +496,7 @@ define double @fmadd_d(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmadd_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmadd_d: @@ -702,27 +542,9 @@ define double @fmsub_d(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmsub_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 ; RV32IZFINXZDINX-NEXT: fmsub.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmsub_d: @@ -811,28 +633,10 @@ define double @fnmadd_d(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fnmadd_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6 ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 ; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmadd_d: @@ -940,28 +744,10 @@ define double @fnmadd_d_2(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fnmadd_d_2: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6 ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 ; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a2, a0, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmadd_d_2: @@ -1060,27 +846,9 @@ define double @fnmadd_d_3(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fnmadd_d_3: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) ; RV32IZFINXZDINX-NEXT: lui a2, 524288 ; RV32IZFINXZDINX-NEXT: xor a1, a1, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmadd_d_3: @@ -1127,27 +895,9 @@ define double @fnmadd_nsz(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fnmadd_nsz: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) ; RV32IZFINXZDINX-NEXT: lui a2, 524288 ; RV32IZFINXZDINX-NEXT: xor a1, a1, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmadd_nsz: @@ -1202,27 +952,9 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fnmsub_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6 ; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmsub_d: @@ -1305,27 +1037,9 @@ define double @fnmsub_d_2(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fnmsub_d_2: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6 ; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a2, a0, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmsub_d_2: @@ -1403,25 +1117,7 @@ define double @fmadd_d_contract(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmadd_d_contract: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmadd_d_contract: @@ -1482,27 +1178,9 @@ define double @fmsub_d_contract(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmsub_d_contract: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 ; RV32IZFINXZDINX-NEXT: fmsub.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmsub_d_contract: @@ -1601,29 +1279,11 @@ define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fnmadd_d_contract: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6 ; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6 ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6 ; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmadd_d_contract: @@ -1749,28 +1409,10 @@ define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fnmsub_d_contract: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6 ; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6 ; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fnmsub_d_contract: diff --git a/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll b/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll index 55bf95a126ac..99835ff59493 100644 --- a/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll +++ b/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll @@ -141,21 +141,7 @@ define double @fcopysign_fneg(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcopysign_fneg: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fsgnjn.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64I-LABEL: fcopysign_fneg: diff --git a/llvm/test/CodeGen/RISCV/double-br-fcmp.ll b/llvm/test/CodeGen/RISCV/double-br-fcmp.ll index 2c5505edb1fa..035228e73c70 100644 --- a/llvm/test/CodeGen/RISCV/double-br-fcmp.ll +++ b/llvm/test/CodeGen/RISCV/double-br-fcmp.ll @@ -89,23 +89,13 @@ define void @br_fcmp_oeq(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_oeq: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: bnez a0, .LBB1_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB1_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_oeq: @@ -155,23 +145,13 @@ define void @br_fcmp_oeq_alt(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_oeq_alt: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: bnez a0, .LBB2_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB2_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_oeq_alt: @@ -218,23 +198,13 @@ define void @br_fcmp_ogt(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_ogt: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) ; RV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 ; RV32IZFINXZDINX-NEXT: bnez a0, .LBB3_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB3_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_ogt: @@ -281,23 +251,13 @@ define void @br_fcmp_oge(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_oge: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) ; RV32IZFINXZDINX-NEXT: fle.d a0, a2, a0 ; RV32IZFINXZDINX-NEXT: bnez a0, .LBB4_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB4_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_oge: @@ -344,23 +304,13 @@ define void @br_fcmp_olt(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_olt: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: flt.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: bnez a0, .LBB5_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB5_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_olt: @@ -407,23 +357,13 @@ define void @br_fcmp_ole(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_ole: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: fle.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: bnez a0, .LBB6_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB6_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_ole: @@ -474,25 +414,15 @@ define void @br_fcmp_one(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_one: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: flt.d a4, a0, a2 ; RV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 ; RV32IZFINXZDINX-NEXT: or a0, a0, a4 ; RV32IZFINXZDINX-NEXT: bnez a0, .LBB7_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB7_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_one: @@ -545,25 +475,15 @@ define void @br_fcmp_ord(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_ord: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) ; RV32IZFINXZDINX-NEXT: feq.d a2, a2, a2 ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 ; RV32IZFINXZDINX-NEXT: bnez a0, .LBB8_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB8_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_ord: @@ -616,25 +536,15 @@ define void @br_fcmp_ueq(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_ueq: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: flt.d a4, a0, a2 ; RV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 ; RV32IZFINXZDINX-NEXT: or a0, a0, a4 ; RV32IZFINXZDINX-NEXT: beqz a0, .LBB9_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB9_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_ueq: @@ -683,23 +593,13 @@ define void @br_fcmp_ugt(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_ugt: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: fle.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: beqz a0, .LBB10_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB10_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_ugt: @@ -746,23 +646,13 @@ define void @br_fcmp_uge(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_uge: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: flt.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: beqz a0, .LBB11_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB11_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_uge: @@ -809,23 +699,13 @@ define void @br_fcmp_ult(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_ult: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) ; RV32IZFINXZDINX-NEXT: fle.d a0, a2, a0 ; RV32IZFINXZDINX-NEXT: beqz a0, .LBB12_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB12_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_ult: @@ -872,23 +752,13 @@ define void @br_fcmp_ule(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_ule: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) ; RV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 ; RV32IZFINXZDINX-NEXT: beqz a0, .LBB13_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB13_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_ule: @@ -935,23 +805,13 @@ define void @br_fcmp_une(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_une: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: beqz a0, .LBB14_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB14_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_une: @@ -1002,25 +862,15 @@ define void @br_fcmp_uno(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: br_fcmp_uno: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) ; RV32IZFINXZDINX-NEXT: feq.d a2, a2, a2 ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 ; RV32IZFINXZDINX-NEXT: beqz a0, .LBB15_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else -; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB15_2: # %if.then +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call abort ; ; RV64IZFINXZDINX-LABEL: br_fcmp_uno: diff --git a/llvm/test/CodeGen/RISCV/double-calling-conv.ll b/llvm/test/CodeGen/RISCV/double-calling-conv.ll index d46256b12052..57aaa4c9f74e 100644 --- a/llvm/test/CodeGen/RISCV/double-calling-conv.ll +++ b/llvm/test/CodeGen/RISCV/double-calling-conv.ll @@ -28,21 +28,7 @@ define double @callee_double_inreg(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: callee_double_inreg: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret %1 = fadd double %a, %b ret double %1 @@ -106,22 +92,11 @@ define double @callee_double_split_reg_stack(i32 %a, i64 %b, i64 %c, double %d, ; ; RV32IZFINXZDINX-LABEL: callee_double_split_reg_stack: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: lw a0, 16(sp) -; RV32IZFINXZDINX-NEXT: sw a7, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a6, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) +; RV32IZFINXZDINX-NEXT: mv a0, a7 +; RV32IZFINXZDINX-NEXT: lw a1, 0(sp) +; RV32IZFINXZDINX-NEXT: mv a3, a6 +; RV32IZFINXZDINX-NEXT: mv a2, a5 ; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret %1 = fadd double %d, %e ret double %1 @@ -190,17 +165,11 @@ define double @callee_double_stack(i64 %a, i64 %b, i64 %c, i64 %d, double %e, do ; ; RV32IZFINXZDINX-LABEL: callee_double_stack: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: lw a0, 24(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 28(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 16(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 20(sp) -; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) +; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) +; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0 ; RV32IZFINXZDINX-NEXT: ret %1 = fadd double %e, %f ret double %1 diff --git a/llvm/test/CodeGen/RISCV/double-convert-strict.ll b/llvm/test/CodeGen/RISCV/double-convert-strict.ll index 967b119581af..13bcafb5ebd1 100644 --- a/llvm/test/CodeGen/RISCV/double-convert-strict.ll +++ b/llvm/test/CodeGen/RISCV/double-convert-strict.ll @@ -28,13 +28,7 @@ define float @fcvt_s_d(double %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_s_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.s.d a0, a0 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_s_d: @@ -72,13 +66,7 @@ define double @fcvt_d_s(float %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_s: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.s a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_s: @@ -116,13 +104,7 @@ define i32 @fcvt_w_d(double %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_w_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_w_d: @@ -162,13 +144,7 @@ define i32 @fcvt_wu_d(double %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_wu_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_wu_d: @@ -210,15 +186,9 @@ define i32 @fcvt_wu_d_multiple_use(double %x, ptr %y) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_wu_d_multiple_use: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rtz ; RV32IZFINXZDINX-NEXT: seqz a1, a0 ; RV32IZFINXZDINX-NEXT: add a0, a0, a1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_wu_d_multiple_use: @@ -263,13 +233,7 @@ define double @fcvt_d_w(i32 %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_w: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_w: @@ -309,14 +273,8 @@ define double @fcvt_d_w_load(ptr %p) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_w_load: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: lw a0, 0(a0) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_w_load: @@ -357,13 +315,7 @@ define double @fcvt_d_wu(i32 %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_wu: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.wu a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_wu: @@ -409,14 +361,8 @@ define double @fcvt_d_wu_load(ptr %p) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_wu_load: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: lw a0, 0(a0) ; RV32IZFINXZDINX-NEXT: fcvt.d.wu a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_wu_load: @@ -661,13 +607,7 @@ define double @fcvt_d_w_i8(i8 signext %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_w_i8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_w_i8: @@ -705,13 +645,7 @@ define double @fcvt_d_wu_i8(i8 zeroext %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_wu_i8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.wu a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_wu_i8: @@ -749,13 +683,7 @@ define double @fcvt_d_w_i16(i16 signext %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_w_i16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_w_i16: @@ -793,13 +721,7 @@ define double @fcvt_d_wu_i16(i16 zeroext %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_wu_i16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.wu a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_wu_i16: diff --git a/llvm/test/CodeGen/RISCV/double-convert.ll b/llvm/test/CodeGen/RISCV/double-convert.ll index 3700a18bafc6..7a9439e5b322 100644 --- a/llvm/test/CodeGen/RISCV/double-convert.ll +++ b/llvm/test/CodeGen/RISCV/double-convert.ll @@ -20,13 +20,7 @@ define float @fcvt_s_d(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_s_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.s.d a0, a0 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_s_d: @@ -63,13 +57,7 @@ define double @fcvt_d_s(float %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_s: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.s a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_s: @@ -106,13 +94,7 @@ define i32 @fcvt_w_d(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_w_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_w_d: @@ -153,17 +135,11 @@ define i32 @fcvt_w_d_sat(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_w_d_sat: ; RV32IZFINXZDINX: # %bb.0: # %start -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a2, a0, rtz ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_w_d_sat: @@ -287,13 +263,7 @@ define i32 @fcvt_wu_d(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_wu_d: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_wu_d: @@ -334,15 +304,9 @@ define i32 @fcvt_wu_d_multiple_use(double %x, ptr %y) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_wu_d_multiple_use: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rtz ; RV32IZFINXZDINX-NEXT: seqz a1, a0 ; RV32IZFINXZDINX-NEXT: add a0, a0, a1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_wu_d_multiple_use: @@ -402,17 +366,11 @@ define i32 @fcvt_wu_d_sat(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_wu_d_sat: ; RV32IZFINXZDINX: # %bb.0: # %start -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a2, a0, rtz ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_wu_d_sat: @@ -512,13 +470,7 @@ define double @fcvt_d_w(i32 %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_w: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_w: @@ -557,14 +509,8 @@ define double @fcvt_d_w_load(ptr %p) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_w_load: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: lw a0, 0(a0) ; RV32IZFINXZDINX-NEXT: fcvt.d.w a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_w_load: @@ -605,13 +551,7 @@ define double @fcvt_d_wu(i32 %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_wu: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.wu a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_wu: @@ -656,14 +596,8 @@ define double @fcvt_d_wu_load(ptr %p) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_wu_load: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: lw a0, 0(a0) ; RV32IZFINXZDINX-NEXT: fcvt.d.wu a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_wu_load: @@ -809,13 +743,11 @@ define i64 @fcvt_l_d_sat(double %a) nounwind { ; RV32IZFINXZDINX-NEXT: sw s1, 20(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: sw s3, 12(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI12_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI12_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI12_0)(a2) +; RV32IZFINXZDINX-NEXT: mv s1, a1 +; RV32IZFINXZDINX-NEXT: mv s0, a0 ; RV32IZFINXZDINX-NEXT: fle.d s2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg s3, s2 ; RV32IZFINXZDINX-NEXT: call __fixdfdi @@ -1057,18 +989,17 @@ define i64 @fcvt_lu_d_sat(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_lu_d_sat: ; RV32IZFINXZDINX: # %bb.0: # %start -; RV32IZFINXZDINX-NEXT: addi sp, sp, -32 -; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 12(sp) +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s1, 4(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s2, 0(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: mv s1, a1 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a2, zero -; RV32IZFINXZDINX-NEXT: fle.d a2, a2, s0 -; RV32IZFINXZDINX-NEXT: neg s2, a2 +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: fle.d a0, a2, s0 +; RV32IZFINXZDINX-NEXT: neg s2, a0 +; RV32IZFINXZDINX-NEXT: mv a0, s0 ; RV32IZFINXZDINX-NEXT: call __fixunsdfdi ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI14_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI14_0+4)(a2) @@ -1079,11 +1010,11 @@ define i64 @fcvt_lu_d_sat(double %a) nounwind { ; RV32IZFINXZDINX-NEXT: or a0, a2, a0 ; RV32IZFINXZDINX-NEXT: and a1, s2, a1 ; RV32IZFINXZDINX-NEXT: or a1, a2, a1 -; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s2, 16(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 32 +; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s2, 0(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_lu_d_sat: @@ -1186,14 +1117,6 @@ define i64 @fmv_x_d(double %a, double %b) nounwind { ; RV32IZFINXZDINX-LABEL: fmv_x_d: ; RV32IZFINXZDINX: # %bb.0: ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 4(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) @@ -1353,21 +1276,17 @@ define double @fmv_d_x(i64 %a, i64 %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmv_d_x: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -32 -; RV32IZFINXZDINX-NEXT: sw a3, 20(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 16(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 28(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 24(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 16(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 20(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 24(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 28(sp) -; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw a3, 4(sp) +; RV32IZFINXZDINX-NEXT: sw a2, 0(sp) ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 32 +; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) +; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) +; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) +; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) +; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) +; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0 +; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmv_d_x: @@ -1406,13 +1325,7 @@ define double @fcvt_d_w_i8(i8 signext %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_w_i8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_w_i8: @@ -1449,13 +1362,7 @@ define double @fcvt_d_wu_i8(i8 zeroext %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_wu_i8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.wu a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_wu_i8: @@ -1492,13 +1399,7 @@ define double @fcvt_d_w_i16(i16 signext %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_w_i16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_w_i16: @@ -1535,13 +1436,7 @@ define double @fcvt_d_wu_i16(i16 zeroext %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_d_wu_i16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: fcvt.d.wu a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_d_wu_i16: @@ -1731,13 +1626,7 @@ define signext i16 @fcvt_w_s_i16(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_w_s_i16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_w_s_i16: @@ -1797,24 +1686,18 @@ define signext i16 @fcvt_w_s_sat_i16(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_w_s_sat_i16: ; RV32IZFINXZDINX: # %bb.0: # %start -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI26_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI26_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI26_0)(a2) ; RV32IZFINXZDINX-NEXT: lui a4, %hi(.LCPI26_1) ; RV32IZFINXZDINX-NEXT: lw a5, %lo(.LCPI26_1+4)(a4) ; RV32IZFINXZDINX-NEXT: lw a4, %lo(.LCPI26_1)(a4) -; RV32IZFINXZDINX-NEXT: fmax.d a2, a0, a2 -; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 -; RV32IZFINXZDINX-NEXT: neg a0, a0 -; RV32IZFINXZDINX-NEXT: fmin.d a2, a2, a4 -; RV32IZFINXZDINX-NEXT: fcvt.w.d a1, a2, rtz -; RV32IZFINXZDINX-NEXT: and a0, a0, a1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: feq.d a6, a0, a0 +; RV32IZFINXZDINX-NEXT: neg a6, a6 +; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a2 +; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a4 +; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rtz +; RV32IZFINXZDINX-NEXT: and a0, a6, a0 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_w_s_sat_i16: @@ -1948,13 +1831,7 @@ define zeroext i16 @fcvt_wu_s_i16(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_wu_s_i16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_wu_s_i16: @@ -2006,11 +1883,6 @@ define zeroext i16 @fcvt_wu_s_sat_i16(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_wu_s_sat_i16: ; RV32IZFINXZDINX: # %bb.0: # %start -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI28_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI28_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI28_0)(a2) @@ -2018,7 +1890,6 @@ define zeroext i16 @fcvt_wu_s_sat_i16(double %a) nounwind { ; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a4 ; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_wu_s_sat_i16: @@ -2130,13 +2001,7 @@ define signext i8 @fcvt_w_s_i8(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_w_s_i8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_w_s_i8: @@ -2196,24 +2061,18 @@ define signext i8 @fcvt_w_s_sat_i8(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_w_s_sat_i8: ; RV32IZFINXZDINX: # %bb.0: # %start -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI30_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI30_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI30_0)(a2) ; RV32IZFINXZDINX-NEXT: lui a4, %hi(.LCPI30_1) ; RV32IZFINXZDINX-NEXT: lw a5, %lo(.LCPI30_1+4)(a4) ; RV32IZFINXZDINX-NEXT: lw a4, %lo(.LCPI30_1)(a4) -; RV32IZFINXZDINX-NEXT: fmax.d a2, a0, a2 -; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 -; RV32IZFINXZDINX-NEXT: neg a0, a0 -; RV32IZFINXZDINX-NEXT: fmin.d a2, a2, a4 -; RV32IZFINXZDINX-NEXT: fcvt.w.d a1, a2, rtz -; RV32IZFINXZDINX-NEXT: and a0, a0, a1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: feq.d a6, a0, a0 +; RV32IZFINXZDINX-NEXT: neg a6, a6 +; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a2 +; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a4 +; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rtz +; RV32IZFINXZDINX-NEXT: and a0, a6, a0 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_w_s_sat_i8: @@ -2344,13 +2203,7 @@ define zeroext i8 @fcvt_wu_s_i8(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_wu_s_i8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_wu_s_i8: @@ -2404,11 +2257,6 @@ define zeroext i8 @fcvt_wu_s_sat_i8(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_wu_s_sat_i8: ; RV32IZFINXZDINX: # %bb.0: # %start -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI32_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI32_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI32_0)(a2) @@ -2416,7 +2264,6 @@ define zeroext i8 @fcvt_wu_s_sat_i8(double %a) nounwind { ; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a4 ; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_wu_s_sat_i8: @@ -2532,17 +2379,11 @@ define zeroext i32 @fcvt_wu_d_sat_zext(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_wu_d_sat_zext: ; RV32IZFINXZDINX: # %bb.0: # %start -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a2, a0, rtz ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_wu_d_sat_zext: @@ -2647,17 +2488,11 @@ define signext i32 @fcvt_w_d_sat_sext(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fcvt_w_d_sat_sext: ; RV32IZFINXZDINX: # %bb.0: # %start -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a2, a0, rtz ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcvt_w_d_sat_sext: diff --git a/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll b/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll index 3ae2e997019c..e864d8fb0edd 100644 --- a/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll +++ b/llvm/test/CodeGen/RISCV/double-fcmp-strict.ll @@ -24,17 +24,7 @@ define i32 @fcmp_oeq(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_oeq: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_oeq: @@ -78,20 +68,11 @@ define i32 @fcmp_ogt(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_ogt: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: csrr a1, fflags -; RV32IZFINXZDINX-NEXT: flt.d a0, a2, a4 -; RV32IZFINXZDINX-NEXT: csrw fflags, a1 -; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a4 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: csrr a5, fflags +; RV32IZFINXZDINX-NEXT: flt.d a4, a2, a0 +; RV32IZFINXZDINX-NEXT: csrw fflags, a5 +; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a0 +; RV32IZFINXZDINX-NEXT: mv a0, a4 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_ogt: @@ -138,20 +119,11 @@ define i32 @fcmp_oge(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_oge: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: csrr a1, fflags -; RV32IZFINXZDINX-NEXT: fle.d a0, a2, a4 -; RV32IZFINXZDINX-NEXT: csrw fflags, a1 -; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a4 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: csrr a5, fflags +; RV32IZFINXZDINX-NEXT: fle.d a4, a2, a0 +; RV32IZFINXZDINX-NEXT: csrw fflags, a5 +; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a0 +; RV32IZFINXZDINX-NEXT: mv a0, a4 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_oge: @@ -200,20 +172,11 @@ define i32 @fcmp_olt(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_olt: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: csrr a1, fflags -; RV32IZFINXZDINX-NEXT: flt.d a0, a4, a2 -; RV32IZFINXZDINX-NEXT: csrw fflags, a1 -; RV32IZFINXZDINX-NEXT: feq.d zero, a4, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: csrr a5, fflags +; RV32IZFINXZDINX-NEXT: flt.d a4, a0, a2 +; RV32IZFINXZDINX-NEXT: csrw fflags, a5 +; RV32IZFINXZDINX-NEXT: feq.d zero, a0, a2 +; RV32IZFINXZDINX-NEXT: mv a0, a4 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_olt: @@ -260,20 +223,11 @@ define i32 @fcmp_ole(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_ole: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: csrr a1, fflags -; RV32IZFINXZDINX-NEXT: fle.d a0, a4, a2 -; RV32IZFINXZDINX-NEXT: csrw fflags, a1 -; RV32IZFINXZDINX-NEXT: feq.d zero, a4, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: csrr a5, fflags +; RV32IZFINXZDINX-NEXT: fle.d a4, a0, a2 +; RV32IZFINXZDINX-NEXT: csrw fflags, a5 +; RV32IZFINXZDINX-NEXT: feq.d zero, a0, a2 +; RV32IZFINXZDINX-NEXT: mv a0, a4 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_ole: @@ -327,25 +281,16 @@ define i32 @fcmp_one(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_one: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: csrr a0, fflags -; RV32IZFINXZDINX-NEXT: flt.d a1, a4, a2 -; RV32IZFINXZDINX-NEXT: csrw fflags, a0 -; RV32IZFINXZDINX-NEXT: feq.d zero, a4, a2 -; RV32IZFINXZDINX-NEXT: csrr a0, fflags -; RV32IZFINXZDINX-NEXT: flt.d a6, a2, a4 -; RV32IZFINXZDINX-NEXT: csrw fflags, a0 -; RV32IZFINXZDINX-NEXT: or a0, a6, a1 -; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a4 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: csrr a4, fflags +; RV32IZFINXZDINX-NEXT: flt.d a5, a0, a2 +; RV32IZFINXZDINX-NEXT: csrw fflags, a4 +; RV32IZFINXZDINX-NEXT: feq.d zero, a0, a2 +; RV32IZFINXZDINX-NEXT: csrr a4, fflags +; RV32IZFINXZDINX-NEXT: flt.d a6, a2, a0 +; RV32IZFINXZDINX-NEXT: csrw fflags, a4 +; RV32IZFINXZDINX-NEXT: or a4, a6, a5 +; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a0 +; RV32IZFINXZDINX-NEXT: mv a0, a4 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_one: @@ -430,19 +375,9 @@ define i32 @fcmp_ord(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_ord: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: feq.d a2, a2, a2 ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_ord: @@ -495,26 +430,17 @@ define i32 @fcmp_ueq(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_ueq: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: csrr a0, fflags -; RV32IZFINXZDINX-NEXT: flt.d a1, a4, a2 -; RV32IZFINXZDINX-NEXT: csrw fflags, a0 -; RV32IZFINXZDINX-NEXT: feq.d zero, a4, a2 -; RV32IZFINXZDINX-NEXT: csrr a0, fflags -; RV32IZFINXZDINX-NEXT: flt.d a6, a2, a4 -; RV32IZFINXZDINX-NEXT: csrw fflags, a0 -; RV32IZFINXZDINX-NEXT: or a0, a6, a1 -; RV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a4 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: csrr a4, fflags +; RV32IZFINXZDINX-NEXT: flt.d a5, a0, a2 +; RV32IZFINXZDINX-NEXT: csrw fflags, a4 +; RV32IZFINXZDINX-NEXT: feq.d zero, a0, a2 +; RV32IZFINXZDINX-NEXT: csrr a4, fflags +; RV32IZFINXZDINX-NEXT: flt.d a6, a2, a0 +; RV32IZFINXZDINX-NEXT: csrw fflags, a4 +; RV32IZFINXZDINX-NEXT: or a4, a6, a5 +; RV32IZFINXZDINX-NEXT: xori a4, a4, 1 +; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a0 +; RV32IZFINXZDINX-NEXT: mv a0, a4 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_ueq: @@ -602,21 +528,12 @@ define i32 @fcmp_ugt(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_ugt: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: csrr a0, fflags -; RV32IZFINXZDINX-NEXT: fle.d a1, a4, a2 -; RV32IZFINXZDINX-NEXT: csrw fflags, a0 -; RV32IZFINXZDINX-NEXT: xori a0, a1, 1 -; RV32IZFINXZDINX-NEXT: feq.d zero, a4, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: csrr a4, fflags +; RV32IZFINXZDINX-NEXT: fle.d a5, a0, a2 +; RV32IZFINXZDINX-NEXT: csrw fflags, a4 +; RV32IZFINXZDINX-NEXT: xori a4, a5, 1 +; RV32IZFINXZDINX-NEXT: feq.d zero, a0, a2 +; RV32IZFINXZDINX-NEXT: mv a0, a4 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_ugt: @@ -665,21 +582,12 @@ define i32 @fcmp_uge(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_uge: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: csrr a0, fflags -; RV32IZFINXZDINX-NEXT: flt.d a1, a4, a2 -; RV32IZFINXZDINX-NEXT: csrw fflags, a0 -; RV32IZFINXZDINX-NEXT: xori a0, a1, 1 -; RV32IZFINXZDINX-NEXT: feq.d zero, a4, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: csrr a4, fflags +; RV32IZFINXZDINX-NEXT: flt.d a5, a0, a2 +; RV32IZFINXZDINX-NEXT: csrw fflags, a4 +; RV32IZFINXZDINX-NEXT: xori a4, a5, 1 +; RV32IZFINXZDINX-NEXT: feq.d zero, a0, a2 +; RV32IZFINXZDINX-NEXT: mv a0, a4 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_uge: @@ -730,21 +638,12 @@ define i32 @fcmp_ult(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_ult: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: csrr a0, fflags -; RV32IZFINXZDINX-NEXT: fle.d a1, a2, a4 -; RV32IZFINXZDINX-NEXT: csrw fflags, a0 -; RV32IZFINXZDINX-NEXT: xori a0, a1, 1 -; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a4 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: csrr a4, fflags +; RV32IZFINXZDINX-NEXT: fle.d a5, a2, a0 +; RV32IZFINXZDINX-NEXT: csrw fflags, a4 +; RV32IZFINXZDINX-NEXT: xori a4, a5, 1 +; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a0 +; RV32IZFINXZDINX-NEXT: mv a0, a4 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_ult: @@ -793,21 +692,12 @@ define i32 @fcmp_ule(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_ule: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: csrr a0, fflags -; RV32IZFINXZDINX-NEXT: flt.d a1, a2, a4 -; RV32IZFINXZDINX-NEXT: csrw fflags, a0 -; RV32IZFINXZDINX-NEXT: xori a0, a1, 1 -; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a4 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 +; RV32IZFINXZDINX-NEXT: csrr a4, fflags +; RV32IZFINXZDINX-NEXT: flt.d a5, a2, a0 +; RV32IZFINXZDINX-NEXT: csrw fflags, a4 +; RV32IZFINXZDINX-NEXT: xori a4, a5, 1 +; RV32IZFINXZDINX-NEXT: feq.d zero, a2, a0 +; RV32IZFINXZDINX-NEXT: mv a0, a4 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_ule: @@ -853,18 +743,8 @@ define i32 @fcmp_une(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_une: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_une: @@ -908,20 +788,10 @@ define i32 @fcmp_uno(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmp_uno: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: feq.d a2, a2, a2 ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 ; RV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmp_uno: @@ -966,19 +836,9 @@ define i32 @fcmps_oeq(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_oeq: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: fle.d a4, a2, a0 ; RV32IZFINXZDINX-NEXT: fle.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: and a0, a0, a4 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_oeq: @@ -1021,17 +881,7 @@ define i32 @fcmps_ogt(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_ogt: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_ogt: @@ -1071,17 +921,7 @@ define i32 @fcmps_oge(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_oge: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: fle.d a0, a2, a0 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_oge: @@ -1123,17 +963,7 @@ define i32 @fcmps_olt(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_olt: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: flt.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_olt: @@ -1173,17 +1003,7 @@ define i32 @fcmps_ole(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_ole: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fle.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_ole: @@ -1225,19 +1045,9 @@ define i32 @fcmps_one(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_one: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: flt.d a4, a0, a2 ; RV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 ; RV32IZFINXZDINX-NEXT: or a0, a0, a4 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_one: @@ -1315,19 +1125,9 @@ define i32 @fcmps_ord(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_ord: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: fle.d a2, a2, a2 ; RV32IZFINXZDINX-NEXT: fle.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_ord: @@ -1372,20 +1172,10 @@ define i32 @fcmps_ueq(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_ueq: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: flt.d a4, a0, a2 ; RV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 ; RV32IZFINXZDINX-NEXT: or a0, a0, a4 ; RV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_ueq: @@ -1463,18 +1253,8 @@ define i32 @fcmps_ugt(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_ugt: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fle.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_ugt: @@ -1516,18 +1296,8 @@ define i32 @fcmps_uge(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_uge: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: flt.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_uge: @@ -1571,18 +1341,8 @@ define i32 @fcmps_ult(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_ult: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: fle.d a0, a2, a0 ; RV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_ult: @@ -1624,18 +1384,8 @@ define i32 @fcmps_ule(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_ule: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 ; RV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_ule: @@ -1679,20 +1429,10 @@ define i32 @fcmps_une(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_une: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: fle.d a4, a2, a0 ; RV32IZFINXZDINX-NEXT: fle.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: and a0, a0, a4 ; RV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_une: @@ -1738,20 +1478,10 @@ define i32 @fcmps_uno(double %a, double %b) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fcmps_uno: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; RV32IZFINXZDINX-NEXT: fle.d a2, a2, a2 ; RV32IZFINXZDINX-NEXT: fle.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 ; RV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fcmps_uno: diff --git a/llvm/test/CodeGen/RISCV/double-fcmp.ll b/llvm/test/CodeGen/RISCV/double-fcmp.ll index 64a154f450f1..1e609f8081eb 100644 --- a/llvm/test/CodeGen/RISCV/double-fcmp.ll +++ b/llvm/test/CodeGen/RISCV/double-fcmp.ll @@ -45,17 +45,7 @@ define i32 @fcmp_oeq(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_oeq: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: feq.d a0, a0, a2 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_oeq: @@ -95,17 +85,7 @@ define i32 @fcmp_ogt(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_ogt: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_ogt: @@ -145,17 +125,7 @@ define i32 @fcmp_oge(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_oge: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: fle.d a0, a2, a0 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_oge: @@ -197,17 +167,7 @@ define i32 @fcmp_olt(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_olt: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: flt.d a0, a0, a2 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_olt: @@ -247,17 +207,7 @@ define i32 @fcmp_ole(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_ole: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: fle.d a0, a0, a2 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_ole: @@ -299,19 +249,9 @@ define i32 @fcmp_one(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_one: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: flt.d a4, a0, a2 ; CHECKRV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 ; CHECKRV32IZFINXZDINX-NEXT: or a0, a0, a4 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_one: @@ -389,19 +329,9 @@ define i32 @fcmp_ord(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_ord: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: feq.d a2, a2, a2 ; CHECKRV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; CHECKRV32IZFINXZDINX-NEXT: and a0, a0, a2 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_ord: @@ -446,20 +376,10 @@ define i32 @fcmp_ueq(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_ueq: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: flt.d a4, a0, a2 ; CHECKRV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 ; CHECKRV32IZFINXZDINX-NEXT: or a0, a0, a4 ; CHECKRV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_ueq: @@ -537,18 +457,8 @@ define i32 @fcmp_ugt(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_ugt: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: fle.d a0, a0, a2 ; CHECKRV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_ugt: @@ -590,18 +500,8 @@ define i32 @fcmp_uge(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_uge: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: flt.d a0, a0, a2 ; CHECKRV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_uge: @@ -645,18 +545,8 @@ define i32 @fcmp_ult(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_ult: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: fle.d a0, a2, a0 ; CHECKRV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_ult: @@ -698,18 +588,8 @@ define i32 @fcmp_ule(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_ule: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: flt.d a0, a2, a0 ; CHECKRV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_ule: @@ -751,18 +631,8 @@ define i32 @fcmp_une(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_une: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: feq.d a0, a0, a2 ; CHECKRV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_une: @@ -806,20 +676,10 @@ define i32 @fcmp_uno(double %a, double %b) nounwind { ; ; CHECKRV32IZFINXZDINX-LABEL: fcmp_uno: ; CHECKRV32IZFINXZDINX: # %bb.0: -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32IZFINXZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32IZFINXZDINX-NEXT: feq.d a2, a2, a2 ; CHECKRV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; CHECKRV32IZFINXZDINX-NEXT: and a0, a0, a2 ; CHECKRV32IZFINXZDINX-NEXT: xori a0, a0, 1 -; CHECKRV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32IZFINXZDINX-NEXT: ret ; ; CHECKRV64IZFINXZDINX-LABEL: fcmp_uno: diff --git a/llvm/test/CodeGen/RISCV/double-imm.ll b/llvm/test/CodeGen/RISCV/double-imm.ll index 9254369baf19..74d4acc4f23f 100644 --- a/llvm/test/CodeGen/RISCV/double-imm.ll +++ b/llvm/test/CodeGen/RISCV/double-imm.ll @@ -54,20 +54,10 @@ define double @double_imm_op(double %a) nounwind { ; ; CHECKRV32ZDINX-LABEL: double_imm_op: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: lui a2, %hi(.LCPI1_0) ; CHECKRV32ZDINX-NEXT: lw a3, %lo(.LCPI1_0+4)(a2) ; CHECKRV32ZDINX-NEXT: lw a2, %lo(.LCPI1_0)(a2) ; CHECKRV32ZDINX-NEXT: fadd.d a0, a0, a2 -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: double_imm_op: @@ -153,24 +143,18 @@ define dso_local double @negzero_sel(i16 noundef %a, double noundef %d) nounwind ; ; CHECKRV32ZDINX-LABEL: negzero_sel: ; CHECKRV32ZDINX: # %bb.0: # %entry -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a1, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a2, 12(sp) -; CHECKRV32ZDINX-NEXT: slli a2, a0, 16 -; CHECKRV32ZDINX-NEXT: fcvt.d.w a0, zero -; CHECKRV32ZDINX-NEXT: beqz a2, .LBB4_2 +; CHECKRV32ZDINX-NEXT: slli a0, a0, 16 +; CHECKRV32ZDINX-NEXT: fcvt.d.w a4, zero +; CHECKRV32ZDINX-NEXT: beqz a0, .LBB4_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: # %entry -; CHECKRV32ZDINX-NEXT: fneg.d a0, a0 +; CHECKRV32ZDINX-NEXT: fneg.d a2, a4 ; CHECKRV32ZDINX-NEXT: j .LBB4_3 ; CHECKRV32ZDINX-NEXT: .LBB4_2: -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) +; CHECKRV32ZDINX-NEXT: mv a3, a2 +; CHECKRV32ZDINX-NEXT: mv a2, a1 ; CHECKRV32ZDINX-NEXT: .LBB4_3: # %entry -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 +; CHECKRV32ZDINX-NEXT: mv a0, a2 +; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: negzero_sel: diff --git a/llvm/test/CodeGen/RISCV/double-intrinsics-strict.ll b/llvm/test/CodeGen/RISCV/double-intrinsics-strict.ll index c574f64150a2..38215860193e 100644 --- a/llvm/test/CodeGen/RISCV/double-intrinsics-strict.ll +++ b/llvm/test/CodeGen/RISCV/double-intrinsics-strict.ll @@ -28,17 +28,7 @@ define double @sqrt_f64(double %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: sqrt_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fsqrt.d a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: sqrt_f64: @@ -299,22 +289,12 @@ define double @sincos_f64(double %a) nounwind strictfp { ; RV32IZFINXZDINX-NEXT: mv s0, a1 ; RV32IZFINXZDINX-NEXT: mv s1, a0 ; RV32IZFINXZDINX-NEXT: call sin -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw s2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw s3, 4(sp) +; RV32IZFINXZDINX-NEXT: mv s2, a0 +; RV32IZFINXZDINX-NEXT: mv s3, a1 ; RV32IZFINXZDINX-NEXT: mv a0, s1 ; RV32IZFINXZDINX-NEXT: mv a1, s0 ; RV32IZFINXZDINX-NEXT: call cos -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, s2, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload ; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload ; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload @@ -765,25 +745,7 @@ define double @fma_f64(double %a, double %b, double %c) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fma_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fma_f64: @@ -822,25 +784,7 @@ define double @fmuladd_f64(double %a, double %b, double %c) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: fmuladd_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmuladd_f64: @@ -1455,13 +1399,7 @@ define iXLen @lrint_f64(double %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: lrint_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: lrint_f64: @@ -1505,13 +1443,7 @@ define iXLen @lround_f64(double %a) nounwind strictfp { ; ; RV32IZFINXZDINX-LABEL: lround_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rmm -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: lround_f64: diff --git a/llvm/test/CodeGen/RISCV/double-intrinsics.ll b/llvm/test/CodeGen/RISCV/double-intrinsics.ll index f290cf0f7736..52c49cfbfb30 100644 --- a/llvm/test/CodeGen/RISCV/double-intrinsics.ll +++ b/llvm/test/CodeGen/RISCV/double-intrinsics.ll @@ -26,17 +26,7 @@ define double @sqrt_f64(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: sqrt_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fsqrt.d a0, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: sqrt_f64: @@ -254,22 +244,12 @@ define double @sincos_f64(double %a) nounwind { ; RV32IZFINXZDINX-NEXT: mv s0, a1 ; RV32IZFINXZDINX-NEXT: mv s1, a0 ; RV32IZFINXZDINX-NEXT: call sin -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw s2, 0(sp) -; RV32IZFINXZDINX-NEXT: lw s3, 4(sp) +; RV32IZFINXZDINX-NEXT: mv s2, a0 +; RV32IZFINXZDINX-NEXT: mv s3, a1 ; RV32IZFINXZDINX-NEXT: mv a0, s1 ; RV32IZFINXZDINX-NEXT: mv a1, s0 ; RV32IZFINXZDINX-NEXT: call cos -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, s2, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload ; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload ; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload @@ -606,25 +586,7 @@ define double @fma_f64(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fma_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fma_f64: @@ -663,25 +625,7 @@ define double @fmuladd_f64(double %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmuladd_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmuladd_f64: @@ -769,21 +713,7 @@ define double @minnum_f64(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: minnum_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: minnum_f64: @@ -822,21 +752,7 @@ define double @maxnum_f64(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: maxnum_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: maxnum_f64: @@ -892,21 +808,7 @@ define double @copysign_f64(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: copysign_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fsgnj.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: copysign_f64: @@ -1381,13 +1283,7 @@ define iXLen @lrint_f64(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: lrint_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: lrint_f64: @@ -1432,13 +1328,7 @@ define iXLen @lround_f64(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: lround_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rmm -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: lround_f64: @@ -1475,13 +1365,7 @@ define i32 @lround_i32_f64(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: lround_i32_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rmm -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: lround_i32_f64: @@ -1625,16 +1509,9 @@ define i1 @isnan_d_fpclass(double %x) { ; ; RV32IZFINXZDINX-LABEL: isnan_d_fpclass: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fclass.d a0, a0 ; RV32IZFINXZDINX-NEXT: andi a0, a0, 768 ; RV32IZFINXZDINX-NEXT: snez a0, a0 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: isnan_d_fpclass: diff --git a/llvm/test/CodeGen/RISCV/double-isnan.ll b/llvm/test/CodeGen/RISCV/double-isnan.ll index 4d0b8151f3c4..6a3779dc2d36 100644 --- a/llvm/test/CodeGen/RISCV/double-isnan.ll +++ b/llvm/test/CodeGen/RISCV/double-isnan.ll @@ -17,14 +17,8 @@ define zeroext i1 @double_is_nan(double %a) nounwind { ; ; CHECKRV32ZDINX-LABEL: double_is_nan: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: feq.d a0, a0, a0 ; CHECKRV32ZDINX-NEXT: xori a0, a0, 1 -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: double_is_nan: @@ -44,13 +38,7 @@ define zeroext i1 @double_not_nan(double %a) nounwind { ; ; CHECKRV32ZDINX-LABEL: double_not_nan: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: feq.d a0, a0, a0 -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: double_not_nan: diff --git a/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll b/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll index 0ca20783591a..5229117caa2c 100644 --- a/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll +++ b/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll @@ -36,35 +36,25 @@ define double @fminimum_f64(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fminimum_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: feq.d a6, a0, a0 ; RV32IZFINXZDINX-NEXT: mv a4, a2 ; RV32IZFINXZDINX-NEXT: mv a5, a3 -; RV32IZFINXZDINX-NEXT: bnez a6, .LBB0_2 +; RV32IZFINXZDINX-NEXT: beqz a6, .LBB0_3 ; RV32IZFINXZDINX-NEXT: # %bb.1: +; RV32IZFINXZDINX-NEXT: feq.d a6, a2, a2 +; RV32IZFINXZDINX-NEXT: beqz a6, .LBB0_4 +; RV32IZFINXZDINX-NEXT: .LBB0_2: +; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a4 +; RV32IZFINXZDINX-NEXT: ret +; RV32IZFINXZDINX-NEXT: .LBB0_3: ; RV32IZFINXZDINX-NEXT: mv a4, a0 ; RV32IZFINXZDINX-NEXT: mv a5, a1 -; RV32IZFINXZDINX-NEXT: .LBB0_2: ; RV32IZFINXZDINX-NEXT: feq.d a6, a2, a2 -; RV32IZFINXZDINX-NEXT: bnez a6, .LBB0_4 -; RV32IZFINXZDINX-NEXT: # %bb.3: +; RV32IZFINXZDINX-NEXT: bnez a6, .LBB0_2 +; RV32IZFINXZDINX-NEXT: .LBB0_4: ; RV32IZFINXZDINX-NEXT: mv a0, a2 ; RV32IZFINXZDINX-NEXT: mv a1, a3 -; RV32IZFINXZDINX-NEXT: .LBB0_4: ; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fminimum_f64: @@ -113,35 +103,25 @@ define double @fmaximum_f64(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmaximum_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: feq.d a6, a0, a0 ; RV32IZFINXZDINX-NEXT: mv a4, a2 ; RV32IZFINXZDINX-NEXT: mv a5, a3 -; RV32IZFINXZDINX-NEXT: bnez a6, .LBB1_2 +; RV32IZFINXZDINX-NEXT: beqz a6, .LBB1_3 ; RV32IZFINXZDINX-NEXT: # %bb.1: +; RV32IZFINXZDINX-NEXT: feq.d a6, a2, a2 +; RV32IZFINXZDINX-NEXT: beqz a6, .LBB1_4 +; RV32IZFINXZDINX-NEXT: .LBB1_2: +; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a4 +; RV32IZFINXZDINX-NEXT: ret +; RV32IZFINXZDINX-NEXT: .LBB1_3: ; RV32IZFINXZDINX-NEXT: mv a4, a0 ; RV32IZFINXZDINX-NEXT: mv a5, a1 -; RV32IZFINXZDINX-NEXT: .LBB1_2: ; RV32IZFINXZDINX-NEXT: feq.d a6, a2, a2 -; RV32IZFINXZDINX-NEXT: bnez a6, .LBB1_4 -; RV32IZFINXZDINX-NEXT: # %bb.3: +; RV32IZFINXZDINX-NEXT: bnez a6, .LBB1_2 +; RV32IZFINXZDINX-NEXT: .LBB1_4: ; RV32IZFINXZDINX-NEXT: mv a0, a2 ; RV32IZFINXZDINX-NEXT: mv a1, a3 -; RV32IZFINXZDINX-NEXT: .LBB1_4: ; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmaximum_f64: @@ -174,21 +154,7 @@ define double @fminimum_nnan_f64(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fminimum_nnan_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fminimum_nnan_f64: @@ -221,35 +187,25 @@ define double @fmaximum_nnan_f64(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmaximum_nnan_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: feq.d a6, a0, a0 ; RV32IZFINXZDINX-NEXT: mv a4, a2 ; RV32IZFINXZDINX-NEXT: mv a5, a3 -; RV32IZFINXZDINX-NEXT: bnez a6, .LBB3_2 +; RV32IZFINXZDINX-NEXT: beqz a6, .LBB3_3 ; RV32IZFINXZDINX-NEXT: # %bb.1: +; RV32IZFINXZDINX-NEXT: feq.d a6, a2, a2 +; RV32IZFINXZDINX-NEXT: beqz a6, .LBB3_4 +; RV32IZFINXZDINX-NEXT: .LBB3_2: +; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a4 +; RV32IZFINXZDINX-NEXT: ret +; RV32IZFINXZDINX-NEXT: .LBB3_3: ; RV32IZFINXZDINX-NEXT: mv a4, a0 ; RV32IZFINXZDINX-NEXT: mv a5, a1 -; RV32IZFINXZDINX-NEXT: .LBB3_2: ; RV32IZFINXZDINX-NEXT: feq.d a6, a2, a2 -; RV32IZFINXZDINX-NEXT: bnez a6, .LBB3_4 -; RV32IZFINXZDINX-NEXT: # %bb.3: +; RV32IZFINXZDINX-NEXT: bnez a6, .LBB3_2 +; RV32IZFINXZDINX-NEXT: .LBB3_4: ; RV32IZFINXZDINX-NEXT: mv a0, a2 ; RV32IZFINXZDINX-NEXT: mv a1, a3 -; RV32IZFINXZDINX-NEXT: .LBB3_4: ; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a4 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmaximum_nnan_f64: @@ -289,30 +245,14 @@ define double @fminimum_nnan_op_f64(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fminimum_nnan_op_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: feq.d a0, a2, a2 -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: bnez a0, .LBB4_2 +; RV32IZFINXZDINX-NEXT: feq.d a4, a2, a2 +; RV32IZFINXZDINX-NEXT: bnez a4, .LBB4_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: -; RV32IZFINXZDINX-NEXT: mv a0, a2 -; RV32IZFINXZDINX-NEXT: mv a1, a3 -; RV32IZFINXZDINX-NEXT: j .LBB4_3 +; RV32IZFINXZDINX-NEXT: fmin.d a0, a2, a2 +; RV32IZFINXZDINX-NEXT: ret ; RV32IZFINXZDINX-NEXT: .LBB4_2: -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a0 -; RV32IZFINXZDINX-NEXT: .LBB4_3: ; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fminimum_nnan_op_f64: @@ -341,23 +281,9 @@ define double @fmaximum_nnan_op_f64(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fmaximum_nnan_op_f64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a4, a0, a2 ; RV32IZFINXZDINX-NEXT: fsub.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: fmax.d a0, a4, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fmaximum_nnan_op_f64: diff --git a/llvm/test/CodeGen/RISCV/double-mem.ll b/llvm/test/CodeGen/RISCV/double-mem.ll index 6c6f70d6e2ed..38cb52b6f4b3 100644 --- a/llvm/test/CodeGen/RISCV/double-mem.ll +++ b/llvm/test/CodeGen/RISCV/double-mem.ll @@ -18,17 +18,11 @@ define dso_local double @fld(ptr %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fld: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 ; RV32IZFINXZDINX-NEXT: lw a2, 0(a0) ; RV32IZFINXZDINX-NEXT: lw a3, 4(a0) ; RV32IZFINXZDINX-NEXT: lw a1, 28(a0) ; RV32IZFINXZDINX-NEXT: lw a0, 24(a0) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fld: @@ -56,21 +50,15 @@ define dso_local void @fsd(ptr %a, double %b, double %c) nounwind { ; ; RV32IZFINXZDINX-LABEL: fsd: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a3, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a4, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a4, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a5, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a4 +; RV32IZFINXZDINX-NEXT: mv a5, a4 +; RV32IZFINXZDINX-NEXT: mv a7, a2 +; RV32IZFINXZDINX-NEXT: mv a4, a3 +; RV32IZFINXZDINX-NEXT: mv a6, a1 +; RV32IZFINXZDINX-NEXT: fadd.d a2, a6, a4 ; RV32IZFINXZDINX-NEXT: sw a2, 0(a0) ; RV32IZFINXZDINX-NEXT: sw a3, 4(a0) ; RV32IZFINXZDINX-NEXT: sw a2, 64(a0) ; RV32IZFINXZDINX-NEXT: sw a3, 68(a0) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fsd: @@ -105,15 +93,6 @@ define dso_local double @fld_fsd_global(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fld_fsd_global: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2 ; RV32IZFINXZDINX-NEXT: lui a2, %hi(G) ; RV32IZFINXZDINX-NEXT: lw a4, %lo(G)(a2) @@ -125,11 +104,6 @@ define dso_local double @fld_fsd_global(double %a, double %b) nounwind { ; RV32IZFINXZDINX-NEXT: lw a5, 76(a3) ; RV32IZFINXZDINX-NEXT: sw a0, 72(a3) ; RV32IZFINXZDINX-NEXT: sw a1, 76(a3) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fld_fsd_global: @@ -174,22 +148,12 @@ define dso_local double @fld_fsd_constant(double %a) nounwind { ; ; RV32IZFINXZDINX-LABEL: fld_fsd_constant: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: lui a2, 912092 ; RV32IZFINXZDINX-NEXT: lw a4, -273(a2) ; RV32IZFINXZDINX-NEXT: lw a5, -269(a2) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a4 ; RV32IZFINXZDINX-NEXT: sw a0, -273(a2) ; RV32IZFINXZDINX-NEXT: sw a1, -269(a2) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fld_fsd_constant: @@ -246,19 +210,13 @@ define dso_local double @fld_stack(double %a) nounwind { ; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: sw s0, 24(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) +; RV32IZFINXZDINX-NEXT: mv s1, a1 +; RV32IZFINXZDINX-NEXT: mv s0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, sp, 8 ; RV32IZFINXZDINX-NEXT: call notdead ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, s0 -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload ; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload ; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload @@ -313,23 +271,15 @@ define dso_local void @fsd_stack(double %a, double %b) nounwind { ; ; RV32IZFINXZDINX-LABEL: fsd_stack: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -32 -; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2 -; RV32IZFINXZDINX-NEXT: sw a0, 16(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 20(sp) -; RV32IZFINXZDINX-NEXT: addi a0, sp, 16 +; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) +; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) +; RV32IZFINXZDINX-NEXT: mv a0, sp ; RV32IZFINXZDINX-NEXT: call notdead -; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 32 +; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fsd_stack: @@ -360,14 +310,10 @@ define dso_local void @fsd_trunc(ptr %a, double %b) nounwind noinline optnone { ; ; RV32IZFINXZDINX-LABEL: fsd_trunc: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: sw a1, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a2, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a2, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a3, 12(sp) +; RV32IZFINXZDINX-NEXT: mv a3, a2 +; RV32IZFINXZDINX-NEXT: mv a2, a1 ; RV32IZFINXZDINX-NEXT: fcvt.s.d a1, a2 ; RV32IZFINXZDINX-NEXT: sw a1, 0(a0) -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: fsd_trunc: diff --git a/llvm/test/CodeGen/RISCV/double-previous-failure.ll b/llvm/test/CodeGen/RISCV/double-previous-failure.ll index 8b8f538886ed..c169b1099b27 100644 --- a/llvm/test/CodeGen/RISCV/double-previous-failure.ll +++ b/llvm/test/CodeGen/RISCV/double-previous-failure.ll @@ -50,10 +50,6 @@ define i32 @main() nounwind { ; RV32IZFINXZDINX-NEXT: lui a1, 262144 ; RV32IZFINXZDINX-NEXT: li a0, 0 ; RV32IZFINXZDINX-NEXT: call test -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 4(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI1_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI1_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI1_0)(a2) diff --git a/llvm/test/CodeGen/RISCV/double-round-conv-sat.ll b/llvm/test/CodeGen/RISCV/double-round-conv-sat.ll index 7cdf18e2fea9..29a9e5070950 100644 --- a/llvm/test/CodeGen/RISCV/double-round-conv-sat.ll +++ b/llvm/test/CodeGen/RISCV/double-round-conv-sat.ll @@ -20,18 +20,11 @@ define signext i32 @test_floor_si32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_floor_si32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a2, a0, rdn ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_floor_si32: @@ -112,13 +105,11 @@ define i64 @test_floor_si64(double %x) nounwind { ; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: sw s3, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call floor -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI1_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI1_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI1_0)(a2) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 ; RV32IZFINXZDINX-NEXT: fle.d s2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg s3, s2 ; RV32IZFINXZDINX-NEXT: call __fixdfdi @@ -177,18 +168,11 @@ define signext i32 @test_floor_ui32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_floor_ui32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a2, a0, rdn ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_floor_ui32: @@ -241,38 +225,30 @@ define i64 @test_floor_ui64(double %x) nounwind { ; ; RV32IZFINXZDINX-LABEL: test_floor_ui64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -32 -; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call floor -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 +; RV32IZFINXZDINX-NEXT: call __fixunsdfdi ; RV32IZFINXZDINX-NEXT: fcvt.d.w a2, zero +; RV32IZFINXZDINX-NEXT: lui a4, %hi(.LCPI3_0) +; RV32IZFINXZDINX-NEXT: lw a5, %lo(.LCPI3_0+4)(a4) +; RV32IZFINXZDINX-NEXT: lw a4, %lo(.LCPI3_0)(a4) ; RV32IZFINXZDINX-NEXT: fle.d a2, a2, s0 -; RV32IZFINXZDINX-NEXT: neg s2, a2 -; RV32IZFINXZDINX-NEXT: call __fixunsdfdi -; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI3_0) -; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI3_0+4)(a2) -; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI3_0)(a2) -; RV32IZFINXZDINX-NEXT: and a0, s2, a0 -; RV32IZFINXZDINX-NEXT: flt.d a2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg a2, a2 -; RV32IZFINXZDINX-NEXT: or a0, a2, a0 -; RV32IZFINXZDINX-NEXT: and a1, s2, a1 -; RV32IZFINXZDINX-NEXT: or a1, a2, a1 -; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s2, 16(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 32 +; RV32IZFINXZDINX-NEXT: and a0, a2, a0 +; RV32IZFINXZDINX-NEXT: flt.d a3, a4, s0 +; RV32IZFINXZDINX-NEXT: neg a3, a3 +; RV32IZFINXZDINX-NEXT: or a0, a3, a0 +; RV32IZFINXZDINX-NEXT: and a1, a2, a1 +; RV32IZFINXZDINX-NEXT: or a1, a3, a1 +; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_floor_ui64: @@ -300,18 +276,11 @@ define signext i32 @test_ceil_si32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_ceil_si32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a2, a0, rup ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_ceil_si32: @@ -392,13 +361,11 @@ define i64 @test_ceil_si64(double %x) nounwind { ; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: sw s3, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call ceil -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI5_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI5_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI5_0)(a2) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 ; RV32IZFINXZDINX-NEXT: fle.d s2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg s3, s2 ; RV32IZFINXZDINX-NEXT: call __fixdfdi @@ -457,18 +424,11 @@ define signext i32 @test_ceil_ui32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_ceil_ui32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a2, a0, rup ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_ceil_ui32: @@ -521,38 +481,30 @@ define i64 @test_ceil_ui64(double %x) nounwind { ; ; RV32IZFINXZDINX-LABEL: test_ceil_ui64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -32 -; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call ceil -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 +; RV32IZFINXZDINX-NEXT: call __fixunsdfdi ; RV32IZFINXZDINX-NEXT: fcvt.d.w a2, zero +; RV32IZFINXZDINX-NEXT: lui a4, %hi(.LCPI7_0) +; RV32IZFINXZDINX-NEXT: lw a5, %lo(.LCPI7_0+4)(a4) +; RV32IZFINXZDINX-NEXT: lw a4, %lo(.LCPI7_0)(a4) ; RV32IZFINXZDINX-NEXT: fle.d a2, a2, s0 -; RV32IZFINXZDINX-NEXT: neg s2, a2 -; RV32IZFINXZDINX-NEXT: call __fixunsdfdi -; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI7_0) -; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI7_0+4)(a2) -; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI7_0)(a2) -; RV32IZFINXZDINX-NEXT: and a0, s2, a0 -; RV32IZFINXZDINX-NEXT: flt.d a2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg a2, a2 -; RV32IZFINXZDINX-NEXT: or a0, a2, a0 -; RV32IZFINXZDINX-NEXT: and a1, s2, a1 -; RV32IZFINXZDINX-NEXT: or a1, a2, a1 -; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s2, 16(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 32 +; RV32IZFINXZDINX-NEXT: and a0, a2, a0 +; RV32IZFINXZDINX-NEXT: flt.d a3, a4, s0 +; RV32IZFINXZDINX-NEXT: neg a3, a3 +; RV32IZFINXZDINX-NEXT: or a0, a3, a0 +; RV32IZFINXZDINX-NEXT: and a1, a2, a1 +; RV32IZFINXZDINX-NEXT: or a1, a3, a1 +; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_ceil_ui64: @@ -580,18 +532,11 @@ define signext i32 @test_trunc_si32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_trunc_si32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a2, a0, rtz ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_trunc_si32: @@ -672,13 +617,11 @@ define i64 @test_trunc_si64(double %x) nounwind { ; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: sw s3, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call trunc -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI9_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI9_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI9_0)(a2) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 ; RV32IZFINXZDINX-NEXT: fle.d s2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg s3, s2 ; RV32IZFINXZDINX-NEXT: call __fixdfdi @@ -737,18 +680,11 @@ define signext i32 @test_trunc_ui32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_trunc_ui32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a2, a0, rtz ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_trunc_ui32: @@ -801,38 +737,30 @@ define i64 @test_trunc_ui64(double %x) nounwind { ; ; RV32IZFINXZDINX-LABEL: test_trunc_ui64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -32 -; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call trunc -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 +; RV32IZFINXZDINX-NEXT: call __fixunsdfdi ; RV32IZFINXZDINX-NEXT: fcvt.d.w a2, zero +; RV32IZFINXZDINX-NEXT: lui a4, %hi(.LCPI11_0) +; RV32IZFINXZDINX-NEXT: lw a5, %lo(.LCPI11_0+4)(a4) +; RV32IZFINXZDINX-NEXT: lw a4, %lo(.LCPI11_0)(a4) ; RV32IZFINXZDINX-NEXT: fle.d a2, a2, s0 -; RV32IZFINXZDINX-NEXT: neg s2, a2 -; RV32IZFINXZDINX-NEXT: call __fixunsdfdi -; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI11_0) -; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI11_0+4)(a2) -; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI11_0)(a2) -; RV32IZFINXZDINX-NEXT: and a0, s2, a0 -; RV32IZFINXZDINX-NEXT: flt.d a2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg a2, a2 -; RV32IZFINXZDINX-NEXT: or a0, a2, a0 -; RV32IZFINXZDINX-NEXT: and a1, s2, a1 -; RV32IZFINXZDINX-NEXT: or a1, a2, a1 -; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s2, 16(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 32 +; RV32IZFINXZDINX-NEXT: and a0, a2, a0 +; RV32IZFINXZDINX-NEXT: flt.d a3, a4, s0 +; RV32IZFINXZDINX-NEXT: neg a3, a3 +; RV32IZFINXZDINX-NEXT: or a0, a3, a0 +; RV32IZFINXZDINX-NEXT: and a1, a2, a1 +; RV32IZFINXZDINX-NEXT: or a1, a3, a1 +; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_trunc_ui64: @@ -860,18 +788,11 @@ define signext i32 @test_round_si32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_round_si32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a2, a0, rmm ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_round_si32: @@ -952,13 +873,11 @@ define i64 @test_round_si64(double %x) nounwind { ; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: sw s3, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call round -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI13_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI13_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI13_0)(a2) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 ; RV32IZFINXZDINX-NEXT: fle.d s2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg s3, s2 ; RV32IZFINXZDINX-NEXT: call __fixdfdi @@ -1017,18 +936,11 @@ define signext i32 @test_round_ui32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_round_ui32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a2, a0, rmm ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_round_ui32: @@ -1081,38 +993,30 @@ define i64 @test_round_ui64(double %x) nounwind { ; ; RV32IZFINXZDINX-LABEL: test_round_ui64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -32 -; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call round -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 +; RV32IZFINXZDINX-NEXT: call __fixunsdfdi ; RV32IZFINXZDINX-NEXT: fcvt.d.w a2, zero +; RV32IZFINXZDINX-NEXT: lui a4, %hi(.LCPI15_0) +; RV32IZFINXZDINX-NEXT: lw a5, %lo(.LCPI15_0+4)(a4) +; RV32IZFINXZDINX-NEXT: lw a4, %lo(.LCPI15_0)(a4) ; RV32IZFINXZDINX-NEXT: fle.d a2, a2, s0 -; RV32IZFINXZDINX-NEXT: neg s2, a2 -; RV32IZFINXZDINX-NEXT: call __fixunsdfdi -; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI15_0) -; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI15_0+4)(a2) -; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI15_0)(a2) -; RV32IZFINXZDINX-NEXT: and a0, s2, a0 -; RV32IZFINXZDINX-NEXT: flt.d a2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg a2, a2 -; RV32IZFINXZDINX-NEXT: or a0, a2, a0 -; RV32IZFINXZDINX-NEXT: and a1, s2, a1 -; RV32IZFINXZDINX-NEXT: or a1, a2, a1 -; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s2, 16(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 32 +; RV32IZFINXZDINX-NEXT: and a0, a2, a0 +; RV32IZFINXZDINX-NEXT: flt.d a3, a4, s0 +; RV32IZFINXZDINX-NEXT: neg a3, a3 +; RV32IZFINXZDINX-NEXT: or a0, a3, a0 +; RV32IZFINXZDINX-NEXT: and a1, a2, a1 +; RV32IZFINXZDINX-NEXT: or a1, a3, a1 +; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_round_ui64: @@ -1140,18 +1044,11 @@ define signext i32 @test_roundeven_si32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_roundeven_si32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a2, a0, rne ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_roundeven_si32: @@ -1232,13 +1129,11 @@ define i64 @test_roundeven_si64(double %x) nounwind { ; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: sw s3, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call roundeven -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI17_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI17_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI17_0)(a2) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 ; RV32IZFINXZDINX-NEXT: fle.d s2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg s3, s2 ; RV32IZFINXZDINX-NEXT: call __fixdfdi @@ -1297,18 +1192,11 @@ define signext i32 @test_roundeven_ui32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_roundeven_ui32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a2, a0, rne ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_roundeven_ui32: @@ -1361,38 +1249,30 @@ define i64 @test_roundeven_ui64(double %x) nounwind { ; ; RV32IZFINXZDINX-LABEL: test_roundeven_ui64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -32 -; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call roundeven -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 +; RV32IZFINXZDINX-NEXT: call __fixunsdfdi ; RV32IZFINXZDINX-NEXT: fcvt.d.w a2, zero +; RV32IZFINXZDINX-NEXT: lui a4, %hi(.LCPI19_0) +; RV32IZFINXZDINX-NEXT: lw a5, %lo(.LCPI19_0+4)(a4) +; RV32IZFINXZDINX-NEXT: lw a4, %lo(.LCPI19_0)(a4) ; RV32IZFINXZDINX-NEXT: fle.d a2, a2, s0 -; RV32IZFINXZDINX-NEXT: neg s2, a2 -; RV32IZFINXZDINX-NEXT: call __fixunsdfdi -; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI19_0) -; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI19_0+4)(a2) -; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI19_0)(a2) -; RV32IZFINXZDINX-NEXT: and a0, s2, a0 -; RV32IZFINXZDINX-NEXT: flt.d a2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg a2, a2 -; RV32IZFINXZDINX-NEXT: or a0, a2, a0 -; RV32IZFINXZDINX-NEXT: and a1, s2, a1 -; RV32IZFINXZDINX-NEXT: or a1, a2, a1 -; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s2, 16(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 32 +; RV32IZFINXZDINX-NEXT: and a0, a2, a0 +; RV32IZFINXZDINX-NEXT: flt.d a3, a4, s0 +; RV32IZFINXZDINX-NEXT: neg a3, a3 +; RV32IZFINXZDINX-NEXT: or a0, a3, a0 +; RV32IZFINXZDINX-NEXT: and a1, a2, a1 +; RV32IZFINXZDINX-NEXT: or a1, a3, a1 +; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_roundeven_ui64: @@ -1420,18 +1300,11 @@ define signext i32 @test_rint_si32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_rint_si32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a2, a0 ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_rint_si32: @@ -1512,13 +1385,11 @@ define i64 @test_rint_si64(double %x) nounwind { ; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: sw s3, 12(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call rint -; RV32IZFINXZDINX-NEXT: sw a0, 0(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 4(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 0(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) ; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI21_0) ; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI21_0+4)(a2) ; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI21_0)(a2) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 ; RV32IZFINXZDINX-NEXT: fle.d s2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg s3, s2 ; RV32IZFINXZDINX-NEXT: call __fixdfdi @@ -1577,18 +1448,11 @@ define signext i32 @test_rint_ui32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_rint_ui32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a2, a0 ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0 ; RV32IZFINXZDINX-NEXT: seqz a0, a0 ; RV32IZFINXZDINX-NEXT: addi a0, a0, -1 ; RV32IZFINXZDINX-NEXT: and a0, a0, a2 -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_rint_ui32: @@ -1641,38 +1505,30 @@ define i64 @test_rint_ui64(double %x) nounwind { ; ; RV32IZFINXZDINX-LABEL: test_rint_ui64: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -32 -; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32IZFINXZDINX-NEXT: call rint -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) +; RV32IZFINXZDINX-NEXT: mv s0, a0 +; RV32IZFINXZDINX-NEXT: mv s1, a1 +; RV32IZFINXZDINX-NEXT: call __fixunsdfdi ; RV32IZFINXZDINX-NEXT: fcvt.d.w a2, zero +; RV32IZFINXZDINX-NEXT: lui a4, %hi(.LCPI23_0) +; RV32IZFINXZDINX-NEXT: lw a5, %lo(.LCPI23_0+4)(a4) +; RV32IZFINXZDINX-NEXT: lw a4, %lo(.LCPI23_0)(a4) ; RV32IZFINXZDINX-NEXT: fle.d a2, a2, s0 -; RV32IZFINXZDINX-NEXT: neg s2, a2 -; RV32IZFINXZDINX-NEXT: call __fixunsdfdi -; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI23_0) -; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI23_0+4)(a2) -; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI23_0)(a2) -; RV32IZFINXZDINX-NEXT: and a0, s2, a0 -; RV32IZFINXZDINX-NEXT: flt.d a2, a2, s0 ; RV32IZFINXZDINX-NEXT: neg a2, a2 -; RV32IZFINXZDINX-NEXT: or a0, a2, a0 -; RV32IZFINXZDINX-NEXT: and a1, s2, a1 -; RV32IZFINXZDINX-NEXT: or a1, a2, a1 -; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s2, 16(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 32 +; RV32IZFINXZDINX-NEXT: and a0, a2, a0 +; RV32IZFINXZDINX-NEXT: flt.d a3, a4, s0 +; RV32IZFINXZDINX-NEXT: neg a3, a3 +; RV32IZFINXZDINX-NEXT: or a0, a3, a0 +; RV32IZFINXZDINX-NEXT: and a1, a2, a1 +; RV32IZFINXZDINX-NEXT: or a1, a3, a1 +; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_rint_ui64: diff --git a/llvm/test/CodeGen/RISCV/double-round-conv.ll b/llvm/test/CodeGen/RISCV/double-round-conv.ll index 094a4105de71..d84d80a4a10e 100644 --- a/llvm/test/CodeGen/RISCV/double-round-conv.ll +++ b/llvm/test/CodeGen/RISCV/double-round-conv.ll @@ -21,14 +21,7 @@ define signext i8 @test_floor_si8(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_floor_si8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rdn -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_floor_si8: @@ -53,14 +46,7 @@ define signext i16 @test_floor_si16(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_floor_si16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rdn -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_floor_si16: @@ -80,14 +66,7 @@ define signext i32 @test_floor_si32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_floor_si32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rdn -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_floor_si32: @@ -151,14 +130,7 @@ define zeroext i8 @test_floor_ui8(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_floor_ui8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rdn -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_floor_ui8: @@ -183,14 +155,7 @@ define zeroext i16 @test_floor_ui16(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_floor_ui16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rdn -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_floor_ui16: @@ -210,14 +175,7 @@ define signext i32 @test_floor_ui32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_floor_ui32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rdn -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_floor_ui32: @@ -281,14 +239,7 @@ define signext i8 @test_ceil_si8(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_ceil_si8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rup -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_ceil_si8: @@ -313,14 +264,7 @@ define signext i16 @test_ceil_si16(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_ceil_si16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rup -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_ceil_si16: @@ -340,14 +284,7 @@ define signext i32 @test_ceil_si32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_ceil_si32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rup -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_ceil_si32: @@ -411,14 +348,7 @@ define zeroext i8 @test_ceil_ui8(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_ceil_ui8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rup -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_ceil_ui8: @@ -443,14 +373,7 @@ define zeroext i16 @test_ceil_ui16(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_ceil_ui16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rup -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_ceil_ui16: @@ -470,14 +393,7 @@ define signext i32 @test_ceil_ui32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_ceil_ui32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rup -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_ceil_ui32: @@ -541,14 +457,7 @@ define signext i8 @test_trunc_si8(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_trunc_si8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_trunc_si8: @@ -573,14 +482,7 @@ define signext i16 @test_trunc_si16(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_trunc_si16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_trunc_si16: @@ -600,14 +502,7 @@ define signext i32 @test_trunc_si32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_trunc_si32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_trunc_si32: @@ -671,14 +566,7 @@ define zeroext i8 @test_trunc_ui8(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_trunc_ui8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_trunc_ui8: @@ -703,14 +591,7 @@ define zeroext i16 @test_trunc_ui16(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_trunc_ui16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_trunc_ui16: @@ -730,14 +611,7 @@ define signext i32 @test_trunc_ui32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_trunc_ui32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rtz -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_trunc_ui32: @@ -801,14 +675,7 @@ define signext i8 @test_round_si8(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_round_si8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rmm -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_round_si8: @@ -833,14 +700,7 @@ define signext i16 @test_round_si16(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_round_si16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rmm -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_round_si16: @@ -860,14 +720,7 @@ define signext i32 @test_round_si32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_round_si32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rmm -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_round_si32: @@ -931,14 +784,7 @@ define zeroext i8 @test_round_ui8(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_round_ui8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rmm -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_round_ui8: @@ -963,14 +809,7 @@ define zeroext i16 @test_round_ui16(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_round_ui16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rmm -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_round_ui16: @@ -990,14 +829,7 @@ define signext i32 @test_round_ui32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_round_ui32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rmm -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_round_ui32: @@ -1061,14 +893,7 @@ define signext i8 @test_roundeven_si8(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_roundeven_si8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rne -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_roundeven_si8: @@ -1093,14 +918,7 @@ define signext i16 @test_roundeven_si16(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_roundeven_si16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rne -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_roundeven_si16: @@ -1120,14 +938,7 @@ define signext i32 @test_roundeven_si32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_roundeven_si32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.w.d a0, a0, rne -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_roundeven_si32: @@ -1191,14 +1002,7 @@ define zeroext i8 @test_roundeven_ui8(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_roundeven_ui8: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rne -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_roundeven_ui8: @@ -1223,14 +1027,7 @@ define zeroext i16 @test_roundeven_ui16(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_roundeven_ui16: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rne -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_roundeven_ui16: @@ -1250,14 +1047,7 @@ define signext i32 @test_roundeven_ui32(double %x) { ; ; RV32IZFINXZDINX-LABEL: test_roundeven_ui32: ; RV32IZFINXZDINX: # %bb.0: -; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 -; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fcvt.wu.d a0, a0, rne -; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: test_roundeven_ui32: diff --git a/llvm/test/CodeGen/RISCV/double-select-fcmp.ll b/llvm/test/CodeGen/RISCV/double-select-fcmp.ll index 766da3680ffc..654a4609caa2 100644 --- a/llvm/test/CodeGen/RISCV/double-select-fcmp.ll +++ b/llvm/test/CodeGen/RISCV/double-select-fcmp.ll @@ -41,26 +41,12 @@ define double @select_fcmp_oeq(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_oeq: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: feq.d a4, a0, a2 ; CHECKRV32ZDINX-NEXT: bnez a4, .LBB1_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB1_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_oeq: @@ -88,26 +74,12 @@ define double @select_fcmp_ogt(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_ogt: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32ZDINX-NEXT: flt.d a4, a2, a0 ; CHECKRV32ZDINX-NEXT: bnez a4, .LBB2_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB2_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_ogt: @@ -135,26 +107,12 @@ define double @select_fcmp_oge(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_oge: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32ZDINX-NEXT: fle.d a4, a2, a0 ; CHECKRV32ZDINX-NEXT: bnez a4, .LBB3_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB3_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_oge: @@ -182,26 +140,12 @@ define double @select_fcmp_olt(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_olt: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: flt.d a4, a0, a2 ; CHECKRV32ZDINX-NEXT: bnez a4, .LBB4_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB4_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_olt: @@ -229,26 +173,12 @@ define double @select_fcmp_ole(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_ole: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: fle.d a4, a0, a2 ; CHECKRV32ZDINX-NEXT: bnez a4, .LBB5_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB5_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_ole: @@ -278,15 +208,6 @@ define double @select_fcmp_one(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_one: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: flt.d a4, a0, a2 ; CHECKRV32ZDINX-NEXT: flt.d a5, a2, a0 ; CHECKRV32ZDINX-NEXT: or a4, a5, a4 @@ -295,11 +216,6 @@ define double @select_fcmp_one(double %a, double %b) nounwind { ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB6_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_one: @@ -331,15 +247,6 @@ define double @select_fcmp_ord(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_ord: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32ZDINX-NEXT: feq.d a4, a2, a2 ; CHECKRV32ZDINX-NEXT: feq.d a5, a0, a0 ; CHECKRV32ZDINX-NEXT: and a4, a5, a4 @@ -348,11 +255,6 @@ define double @select_fcmp_ord(double %a, double %b) nounwind { ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB7_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_ord: @@ -384,15 +286,6 @@ define double @select_fcmp_ueq(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_ueq: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: flt.d a4, a0, a2 ; CHECKRV32ZDINX-NEXT: flt.d a5, a2, a0 ; CHECKRV32ZDINX-NEXT: or a4, a5, a4 @@ -401,11 +294,6 @@ define double @select_fcmp_ueq(double %a, double %b) nounwind { ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB8_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_ueq: @@ -435,26 +323,12 @@ define double @select_fcmp_ugt(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_ugt: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: fle.d a4, a0, a2 ; CHECKRV32ZDINX-NEXT: beqz a4, .LBB9_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB9_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_ugt: @@ -482,26 +356,12 @@ define double @select_fcmp_uge(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_uge: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: flt.d a4, a0, a2 ; CHECKRV32ZDINX-NEXT: beqz a4, .LBB10_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB10_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_uge: @@ -529,26 +389,12 @@ define double @select_fcmp_ult(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_ult: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32ZDINX-NEXT: fle.d a4, a2, a0 ; CHECKRV32ZDINX-NEXT: beqz a4, .LBB11_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB11_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_ult: @@ -576,26 +422,12 @@ define double @select_fcmp_ule(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_ule: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32ZDINX-NEXT: flt.d a4, a2, a0 ; CHECKRV32ZDINX-NEXT: beqz a4, .LBB12_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB12_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_ule: @@ -623,26 +455,12 @@ define double @select_fcmp_une(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_une: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: feq.d a4, a0, a2 ; CHECKRV32ZDINX-NEXT: beqz a4, .LBB13_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB13_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_une: @@ -672,15 +490,6 @@ define double @select_fcmp_uno(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_uno: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) ; CHECKRV32ZDINX-NEXT: feq.d a4, a2, a2 ; CHECKRV32ZDINX-NEXT: feq.d a5, a0, a0 ; CHECKRV32ZDINX-NEXT: and a4, a5, a4 @@ -689,11 +498,6 @@ define double @select_fcmp_uno(double %a, double %b) nounwind { ; CHECKRV32ZDINX-NEXT: mv a0, a2 ; CHECKRV32ZDINX-NEXT: mv a1, a3 ; CHECKRV32ZDINX-NEXT: .LBB14_2: -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_uno: @@ -741,22 +545,12 @@ define i32 @i32_select_fcmp_oeq(double %a, double %b, i32 %c, i32 %d) nounwind { ; ; CHECKRV32ZDINX-LABEL: i32_select_fcmp_oeq: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: feq.d a1, a0, a2 ; CHECKRV32ZDINX-NEXT: mv a0, a4 ; CHECKRV32ZDINX-NEXT: bnez a1, .LBB16_2 ; CHECKRV32ZDINX-NEXT: # %bb.1: ; CHECKRV32ZDINX-NEXT: mv a0, a5 ; CHECKRV32ZDINX-NEXT: .LBB16_2: -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: i32_select_fcmp_oeq: @@ -783,20 +577,9 @@ define i32 @select_fcmp_oeq_1_2(double %a, double %b) { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_oeq_1_2: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: feq.d a0, a0, a2 ; CHECKRV32ZDINX-NEXT: li a1, 2 ; CHECKRV32ZDINX-NEXT: sub a0, a1, a0 -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_oeq_1_2: @@ -819,18 +602,8 @@ define signext i32 @select_fcmp_uge_negone_zero(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_uge_negone_zero: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: fle.d a0, a0, a2 ; CHECKRV32ZDINX-NEXT: addi a0, a0, -1 -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_uge_negone_zero: @@ -852,18 +625,8 @@ define signext i32 @select_fcmp_uge_1_2(double %a, double %b) nounwind { ; ; CHECKRV32ZDINX-LABEL: select_fcmp_uge_1_2: ; CHECKRV32ZDINX: # %bb.0: -; CHECKRV32ZDINX-NEXT: addi sp, sp, -16 -; CHECKRV32ZDINX-NEXT: sw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a2, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a3, 12(sp) -; CHECKRV32ZDINX-NEXT: sw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: sw a1, 12(sp) -; CHECKRV32ZDINX-NEXT: lw a0, 8(sp) -; CHECKRV32ZDINX-NEXT: lw a1, 12(sp) ; CHECKRV32ZDINX-NEXT: fle.d a0, a0, a2 ; CHECKRV32ZDINX-NEXT: addi a0, a0, 1 -; CHECKRV32ZDINX-NEXT: addi sp, sp, 16 ; CHECKRV32ZDINX-NEXT: ret ; ; CHECKRV64ZDINX-LABEL: select_fcmp_uge_1_2: diff --git a/llvm/test/CodeGen/RISCV/double-select-icmp.ll b/llvm/test/CodeGen/RISCV/double-select-icmp.ll index d864ff51b466..929ffc578f5b 100644 --- a/llvm/test/CodeGen/RISCV/double-select-icmp.ll +++ b/llvm/test/CodeGen/RISCV/double-select-icmp.ll @@ -20,24 +20,13 @@ define double @select_icmp_eq(i32 signext %a, i32 signext %b, double %c, double ; ; RV32ZDINX-LABEL: select_icmp_eq: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) -; RV32ZDINX-NEXT: sw a2, 8(sp) -; RV32ZDINX-NEXT: sw a3, 12(sp) -; RV32ZDINX-NEXT: bne a0, a1, .LBB0_2 +; RV32ZDINX-NEXT: beq a0, a1, .LBB0_2 ; RV32ZDINX-NEXT: # %bb.1: -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) +; RV32ZDINX-NEXT: mv a2, a4 +; RV32ZDINX-NEXT: mv a3, a5 ; RV32ZDINX-NEXT: .LBB0_2: -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 +; RV32ZDINX-NEXT: mv a0, a2 +; RV32ZDINX-NEXT: mv a1, a3 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_eq: @@ -64,24 +53,13 @@ define double @select_icmp_ne(i32 signext %a, i32 signext %b, double %c, double ; ; RV32ZDINX-LABEL: select_icmp_ne: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) -; RV32ZDINX-NEXT: sw a2, 8(sp) -; RV32ZDINX-NEXT: sw a3, 12(sp) -; RV32ZDINX-NEXT: beq a0, a1, .LBB1_2 +; RV32ZDINX-NEXT: bne a0, a1, .LBB1_2 ; RV32ZDINX-NEXT: # %bb.1: -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) +; RV32ZDINX-NEXT: mv a2, a4 +; RV32ZDINX-NEXT: mv a3, a5 ; RV32ZDINX-NEXT: .LBB1_2: -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 +; RV32ZDINX-NEXT: mv a0, a2 +; RV32ZDINX-NEXT: mv a1, a3 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_ne: @@ -108,24 +86,13 @@ define double @select_icmp_ugt(i32 signext %a, i32 signext %b, double %c, double ; ; RV32ZDINX-LABEL: select_icmp_ugt: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) -; RV32ZDINX-NEXT: sw a2, 8(sp) -; RV32ZDINX-NEXT: sw a3, 12(sp) -; RV32ZDINX-NEXT: bgeu a1, a0, .LBB2_2 +; RV32ZDINX-NEXT: bltu a1, a0, .LBB2_2 ; RV32ZDINX-NEXT: # %bb.1: -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) +; RV32ZDINX-NEXT: mv a2, a4 +; RV32ZDINX-NEXT: mv a3, a5 ; RV32ZDINX-NEXT: .LBB2_2: -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 +; RV32ZDINX-NEXT: mv a0, a2 +; RV32ZDINX-NEXT: mv a1, a3 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_ugt: @@ -152,24 +119,13 @@ define double @select_icmp_uge(i32 signext %a, i32 signext %b, double %c, double ; ; RV32ZDINX-LABEL: select_icmp_uge: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) -; RV32ZDINX-NEXT: sw a2, 8(sp) -; RV32ZDINX-NEXT: sw a3, 12(sp) -; RV32ZDINX-NEXT: bltu a0, a1, .LBB3_2 +; RV32ZDINX-NEXT: bgeu a0, a1, .LBB3_2 ; RV32ZDINX-NEXT: # %bb.1: -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) +; RV32ZDINX-NEXT: mv a2, a4 +; RV32ZDINX-NEXT: mv a3, a5 ; RV32ZDINX-NEXT: .LBB3_2: -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 +; RV32ZDINX-NEXT: mv a0, a2 +; RV32ZDINX-NEXT: mv a1, a3 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_uge: @@ -196,24 +152,13 @@ define double @select_icmp_ult(i32 signext %a, i32 signext %b, double %c, double ; ; RV32ZDINX-LABEL: select_icmp_ult: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) -; RV32ZDINX-NEXT: sw a2, 8(sp) -; RV32ZDINX-NEXT: sw a3, 12(sp) -; RV32ZDINX-NEXT: bgeu a0, a1, .LBB4_2 +; RV32ZDINX-NEXT: bltu a0, a1, .LBB4_2 ; RV32ZDINX-NEXT: # %bb.1: -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) +; RV32ZDINX-NEXT: mv a2, a4 +; RV32ZDINX-NEXT: mv a3, a5 ; RV32ZDINX-NEXT: .LBB4_2: -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 +; RV32ZDINX-NEXT: mv a0, a2 +; RV32ZDINX-NEXT: mv a1, a3 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_ult: @@ -240,24 +185,13 @@ define double @select_icmp_ule(i32 signext %a, i32 signext %b, double %c, double ; ; RV32ZDINX-LABEL: select_icmp_ule: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) -; RV32ZDINX-NEXT: sw a2, 8(sp) -; RV32ZDINX-NEXT: sw a3, 12(sp) -; RV32ZDINX-NEXT: bltu a1, a0, .LBB5_2 +; RV32ZDINX-NEXT: bgeu a1, a0, .LBB5_2 ; RV32ZDINX-NEXT: # %bb.1: -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) +; RV32ZDINX-NEXT: mv a2, a4 +; RV32ZDINX-NEXT: mv a3, a5 ; RV32ZDINX-NEXT: .LBB5_2: -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 +; RV32ZDINX-NEXT: mv a0, a2 +; RV32ZDINX-NEXT: mv a1, a3 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_ule: @@ -284,24 +218,13 @@ define double @select_icmp_sgt(i32 signext %a, i32 signext %b, double %c, double ; ; RV32ZDINX-LABEL: select_icmp_sgt: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) -; RV32ZDINX-NEXT: sw a2, 8(sp) -; RV32ZDINX-NEXT: sw a3, 12(sp) -; RV32ZDINX-NEXT: bge a1, a0, .LBB6_2 +; RV32ZDINX-NEXT: blt a1, a0, .LBB6_2 ; RV32ZDINX-NEXT: # %bb.1: -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) +; RV32ZDINX-NEXT: mv a2, a4 +; RV32ZDINX-NEXT: mv a3, a5 ; RV32ZDINX-NEXT: .LBB6_2: -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 +; RV32ZDINX-NEXT: mv a0, a2 +; RV32ZDINX-NEXT: mv a1, a3 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_sgt: @@ -328,24 +251,13 @@ define double @select_icmp_sge(i32 signext %a, i32 signext %b, double %c, double ; ; RV32ZDINX-LABEL: select_icmp_sge: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) -; RV32ZDINX-NEXT: sw a2, 8(sp) -; RV32ZDINX-NEXT: sw a3, 12(sp) -; RV32ZDINX-NEXT: blt a0, a1, .LBB7_2 +; RV32ZDINX-NEXT: bge a0, a1, .LBB7_2 ; RV32ZDINX-NEXT: # %bb.1: -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) +; RV32ZDINX-NEXT: mv a2, a4 +; RV32ZDINX-NEXT: mv a3, a5 ; RV32ZDINX-NEXT: .LBB7_2: -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 +; RV32ZDINX-NEXT: mv a0, a2 +; RV32ZDINX-NEXT: mv a1, a3 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_sge: @@ -372,24 +284,13 @@ define double @select_icmp_slt(i32 signext %a, i32 signext %b, double %c, double ; ; RV32ZDINX-LABEL: select_icmp_slt: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) -; RV32ZDINX-NEXT: sw a2, 8(sp) -; RV32ZDINX-NEXT: sw a3, 12(sp) -; RV32ZDINX-NEXT: bge a0, a1, .LBB8_2 +; RV32ZDINX-NEXT: blt a0, a1, .LBB8_2 ; RV32ZDINX-NEXT: # %bb.1: -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) +; RV32ZDINX-NEXT: mv a2, a4 +; RV32ZDINX-NEXT: mv a3, a5 ; RV32ZDINX-NEXT: .LBB8_2: -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 +; RV32ZDINX-NEXT: mv a0, a2 +; RV32ZDINX-NEXT: mv a1, a3 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_slt: @@ -416,24 +317,13 @@ define double @select_icmp_sle(i32 signext %a, i32 signext %b, double %c, double ; ; RV32ZDINX-LABEL: select_icmp_sle: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) -; RV32ZDINX-NEXT: sw a2, 8(sp) -; RV32ZDINX-NEXT: sw a3, 12(sp) -; RV32ZDINX-NEXT: blt a1, a0, .LBB9_2 +; RV32ZDINX-NEXT: bge a1, a0, .LBB9_2 ; RV32ZDINX-NEXT: # %bb.1: -; RV32ZDINX-NEXT: lw a4, 8(sp) -; RV32ZDINX-NEXT: lw a5, 12(sp) +; RV32ZDINX-NEXT: mv a2, a4 +; RV32ZDINX-NEXT: mv a3, a5 ; RV32ZDINX-NEXT: .LBB9_2: -; RV32ZDINX-NEXT: sw a4, 8(sp) -; RV32ZDINX-NEXT: sw a5, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 +; RV32ZDINX-NEXT: mv a0, a2 +; RV32ZDINX-NEXT: mv a1, a3 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_sle: @@ -458,15 +348,8 @@ define double @select_icmp_slt_one(i32 signext %a) { ; ; RV32ZDINX-LABEL: select_icmp_slt_one: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 ; RV32ZDINX-NEXT: slti a0, a0, 1 ; RV32ZDINX-NEXT: fcvt.d.w a0, a0 -; RV32ZDINX-NEXT: sw a0, 8(sp) -; RV32ZDINX-NEXT: sw a1, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_slt_one: @@ -488,15 +371,8 @@ define double @select_icmp_sgt_zero(i32 signext %a) { ; ; RV32ZDINX-LABEL: select_icmp_sgt_zero: ; RV32ZDINX: # %bb.0: -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: .cfi_def_cfa_offset 16 ; RV32ZDINX-NEXT: slti a0, a0, 1 ; RV32ZDINX-NEXT: fcvt.d.w a0, a0 -; RV32ZDINX-NEXT: sw a0, 8(sp) -; RV32ZDINX-NEXT: sw a1, 12(sp) -; RV32ZDINX-NEXT: lw a0, 8(sp) -; RV32ZDINX-NEXT: lw a1, 12(sp) -; RV32ZDINX-NEXT: addi sp, sp, 16 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: select_icmp_sgt_zero: diff --git a/llvm/test/CodeGen/RISCV/double-stack-spill-restore.ll b/llvm/test/CodeGen/RISCV/double-stack-spill-restore.ll index aa88a365431a..4ae912a34d33 100644 --- a/llvm/test/CodeGen/RISCV/double-stack-spill-restore.ll +++ b/llvm/test/CodeGen/RISCV/double-stack-spill-restore.ll @@ -62,40 +62,28 @@ define double @func(double %d, i32 %n) nounwind { ; ; RV32IZFINXZDINX-LABEL: func: ; RV32IZFINXZDINX: # %bb.0: # %entry -; RV32IZFINXZDINX-NEXT: addi sp, sp, -32 -; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw s1, 12(sp) +; RV32IZFINXZDINX-NEXT: addi sp, sp, -16 +; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: sw s1, 4(sp) # 4-byte Folded Spill +; RV32IZFINXZDINX-NEXT: mv s1, a1 +; RV32IZFINXZDINX-NEXT: mv s0, a0 ; RV32IZFINXZDINX-NEXT: beqz a2, .LBB0_2 ; RV32IZFINXZDINX-NEXT: # %bb.1: # %if.else ; RV32IZFINXZDINX-NEXT: addi a2, a2, -1 -; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw s1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) +; RV32IZFINXZDINX-NEXT: mv a0, s0 +; RV32IZFINXZDINX-NEXT: mv a1, s1 ; RV32IZFINXZDINX-NEXT: call func -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, s0 -; RV32IZFINXZDINX-NEXT: sw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw a1, 12(sp) ; RV32IZFINXZDINX-NEXT: j .LBB0_3 ; RV32IZFINXZDINX-NEXT: .LBB0_2: # %return -; RV32IZFINXZDINX-NEXT: sw s0, 8(sp) -; RV32IZFINXZDINX-NEXT: sw s1, 12(sp) +; RV32IZFINXZDINX-NEXT: mv a0, s0 +; RV32IZFINXZDINX-NEXT: mv a1, s1 ; RV32IZFINXZDINX-NEXT: .LBB0_3: # %return -; RV32IZFINXZDINX-NEXT: lw a0, 8(sp) -; RV32IZFINXZDINX-NEXT: lw a1, 12(sp) -; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32IZFINXZDINX-NEXT: addi sp, sp, 32 +; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32IZFINXZDINX-NEXT: addi sp, sp, 16 ; RV32IZFINXZDINX-NEXT: ret ; ; RV64IZFINXZDINX-LABEL: func: diff --git a/llvm/test/CodeGen/RISCV/fastcc-without-f-reg.ll b/llvm/test/CodeGen/RISCV/fastcc-without-f-reg.ll index fb0b34cf796b..a44d31dff09c 100644 --- a/llvm/test/CodeGen/RISCV/fastcc-without-f-reg.ll +++ b/llvm/test/CodeGen/RISCV/fastcc-without-f-reg.ll @@ -160,17 +160,13 @@ define double @caller_double(double %x) nounwind { ; ; ZDINX32-LABEL: caller_double: ; ZDINX32: # %bb.0: # %entry -; ZDINX32-NEXT: addi sp, sp, -32 -; ZDINX32-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; ZDINX32-NEXT: sw a0, 16(sp) -; ZDINX32-NEXT: sw a1, 20(sp) -; ZDINX32-NEXT: lw a0, 16(sp) -; ZDINX32-NEXT: lw a1, 20(sp) +; ZDINX32-NEXT: addi sp, sp, -16 +; ZDINX32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill ; ZDINX32-NEXT: sw a0, 0(sp) ; ZDINX32-NEXT: sw a1, 4(sp) ; ZDINX32-NEXT: call d -; ZDINX32-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; ZDINX32-NEXT: addi sp, sp, 32 +; ZDINX32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; ZDINX32-NEXT: addi sp, sp, 16 ; ZDINX32-NEXT: ret ; ; ZDINX64-LABEL: caller_double: @@ -200,14 +196,8 @@ define internal fastcc double @d(double %x) nounwind { ; ; ZDINX32-LABEL: d: ; ZDINX32: # %bb.0: # %entry -; ZDINX32-NEXT: addi sp, sp, -16 -; ZDINX32-NEXT: lw a0, 16(sp) -; ZDINX32-NEXT: lw a1, 20(sp) -; ZDINX32-NEXT: sw a0, 8(sp) -; ZDINX32-NEXT: sw a1, 12(sp) -; ZDINX32-NEXT: lw a0, 8(sp) -; ZDINX32-NEXT: lw a1, 12(sp) -; ZDINX32-NEXT: addi sp, sp, 16 +; ZDINX32-NEXT: lw a0, 0(sp) +; ZDINX32-NEXT: lw a1, 4(sp) ; ZDINX32-NEXT: ret ; ; ZDINX64-LABEL: d: @@ -1360,14 +1350,8 @@ define fastcc double @callee_double_32(<32 x double> %A) nounwind { ; ; ZDINX32-LABEL: callee_double_32: ; ZDINX32: # %bb.0: -; ZDINX32-NEXT: addi sp, sp, -16 -; ZDINX32-NEXT: lw a0, 16(sp) -; ZDINX32-NEXT: lw a1, 20(sp) -; ZDINX32-NEXT: sw a0, 8(sp) -; ZDINX32-NEXT: sw a1, 12(sp) -; ZDINX32-NEXT: lw a0, 8(sp) -; ZDINX32-NEXT: lw a1, 12(sp) -; ZDINX32-NEXT: addi sp, sp, 16 +; ZDINX32-NEXT: lw a0, 0(sp) +; ZDINX32-NEXT: lw a1, 4(sp) ; ZDINX32-NEXT: ret ; ; ZDINX64-LABEL: callee_double_32: diff --git a/llvm/test/CodeGen/RISCV/half-convert-strict.ll b/llvm/test/CodeGen/RISCV/half-convert-strict.ll index f03a020762bb..677aa9263ea6 100644 --- a/llvm/test/CodeGen/RISCV/half-convert-strict.ll +++ b/llvm/test/CodeGen/RISCV/half-convert-strict.ll @@ -1745,13 +1745,7 @@ define half @fcvt_h_d(double %a) nounwind strictfp { ; ; RV32IZDINXZHINX-LABEL: fcvt_h_d: ; RV32IZDINXZHINX: # %bb.0: -; RV32IZDINXZHINX-NEXT: addi sp, sp, -16 -; RV32IZDINXZHINX-NEXT: sw a0, 8(sp) -; RV32IZDINXZHINX-NEXT: sw a1, 12(sp) -; RV32IZDINXZHINX-NEXT: lw a0, 8(sp) -; RV32IZDINXZHINX-NEXT: lw a1, 12(sp) ; RV32IZDINXZHINX-NEXT: fcvt.h.d a0, a0 -; RV32IZDINXZHINX-NEXT: addi sp, sp, 16 ; RV32IZDINXZHINX-NEXT: ret ; ; RV64IZDINXZHINX-LABEL: fcvt_h_d: @@ -1807,13 +1801,7 @@ define half @fcvt_h_d(double %a) nounwind strictfp { ; ; CHECK32-IZDINXZHINXMIN-LABEL: fcvt_h_d: ; CHECK32-IZDINXZHINXMIN: # %bb.0: -; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, -16 -; CHECK32-IZDINXZHINXMIN-NEXT: sw a0, 8(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: sw a1, 12(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: lw a0, 8(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: lw a1, 12(sp) ; CHECK32-IZDINXZHINXMIN-NEXT: fcvt.h.d a0, a0 -; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, 16 ; CHECK32-IZDINXZHINXMIN-NEXT: ret ; ; CHECK64-IZDINXZHINXMIN-LABEL: fcvt_h_d: @@ -1878,13 +1866,7 @@ define double @fcvt_d_h(half %a) nounwind strictfp { ; ; RV32IZDINXZHINX-LABEL: fcvt_d_h: ; RV32IZDINXZHINX: # %bb.0: -; RV32IZDINXZHINX-NEXT: addi sp, sp, -16 ; RV32IZDINXZHINX-NEXT: fcvt.d.h a0, a0 -; RV32IZDINXZHINX-NEXT: sw a0, 8(sp) -; RV32IZDINXZHINX-NEXT: sw a1, 12(sp) -; RV32IZDINXZHINX-NEXT: lw a0, 8(sp) -; RV32IZDINXZHINX-NEXT: lw a1, 12(sp) -; RV32IZDINXZHINX-NEXT: addi sp, sp, 16 ; RV32IZDINXZHINX-NEXT: ret ; ; RV64IZDINXZHINX-LABEL: fcvt_d_h: @@ -1944,13 +1926,7 @@ define double @fcvt_d_h(half %a) nounwind strictfp { ; ; CHECK32-IZDINXZHINXMIN-LABEL: fcvt_d_h: ; CHECK32-IZDINXZHINXMIN: # %bb.0: -; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, -16 ; CHECK32-IZDINXZHINXMIN-NEXT: fcvt.d.h a0, a0 -; CHECK32-IZDINXZHINXMIN-NEXT: sw a0, 8(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: sw a1, 12(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: lw a0, 8(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: lw a1, 12(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, 16 ; CHECK32-IZDINXZHINXMIN-NEXT: ret ; ; CHECK64-IZDINXZHINXMIN-LABEL: fcvt_d_h: diff --git a/llvm/test/CodeGen/RISCV/half-convert.ll b/llvm/test/CodeGen/RISCV/half-convert.ll index 28ac6e272e11..bc63b3961952 100644 --- a/llvm/test/CodeGen/RISCV/half-convert.ll +++ b/llvm/test/CodeGen/RISCV/half-convert.ll @@ -5275,21 +5275,10 @@ define half @fcvt_h_d(double %a) nounwind { ; RV64IZHINX-NEXT: addi sp, sp, 16 ; RV64IZHINX-NEXT: ret ; -; RV32IZDINXZHINX-LABEL: fcvt_h_d: -; RV32IZDINXZHINX: # %bb.0: -; RV32IZDINXZHINX-NEXT: addi sp, sp, -16 -; RV32IZDINXZHINX-NEXT: sw a0, 8(sp) -; RV32IZDINXZHINX-NEXT: sw a1, 12(sp) -; RV32IZDINXZHINX-NEXT: lw a0, 8(sp) -; RV32IZDINXZHINX-NEXT: lw a1, 12(sp) -; RV32IZDINXZHINX-NEXT: fcvt.h.d a0, a0 -; RV32IZDINXZHINX-NEXT: addi sp, sp, 16 -; RV32IZDINXZHINX-NEXT: ret -; -; RV64IZDINXZHINX-LABEL: fcvt_h_d: -; RV64IZDINXZHINX: # %bb.0: -; RV64IZDINXZHINX-NEXT: fcvt.h.d a0, a0 -; RV64IZDINXZHINX-NEXT: ret +; CHECKIZDINXZHINX-LABEL: fcvt_h_d: +; CHECKIZDINXZHINX: # %bb.0: +; CHECKIZDINXZHINX-NEXT: fcvt.h.d a0, a0 +; CHECKIZDINXZHINX-NEXT: ret ; ; RV32I-LABEL: fcvt_h_d: ; RV32I: # %bb.0: @@ -5405,13 +5394,7 @@ define half @fcvt_h_d(double %a) nounwind { ; ; CHECK32-IZDINXZHINXMIN-LABEL: fcvt_h_d: ; CHECK32-IZDINXZHINXMIN: # %bb.0: -; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, -16 -; CHECK32-IZDINXZHINXMIN-NEXT: sw a0, 8(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: sw a1, 12(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: lw a0, 8(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: lw a1, 12(sp) ; CHECK32-IZDINXZHINXMIN-NEXT: fcvt.h.d a0, a0 -; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, 16 ; CHECK32-IZDINXZHINXMIN-NEXT: ret ; ; CHECK64-IZDINXZHINXMIN-LABEL: fcvt_h_d: @@ -5473,21 +5456,10 @@ define double @fcvt_d_h(half %a) nounwind { ; RV64IZHINX-NEXT: addi sp, sp, 16 ; RV64IZHINX-NEXT: ret ; -; RV32IZDINXZHINX-LABEL: fcvt_d_h: -; RV32IZDINXZHINX: # %bb.0: -; RV32IZDINXZHINX-NEXT: addi sp, sp, -16 -; RV32IZDINXZHINX-NEXT: fcvt.d.h a0, a0 -; RV32IZDINXZHINX-NEXT: sw a0, 8(sp) -; RV32IZDINXZHINX-NEXT: sw a1, 12(sp) -; RV32IZDINXZHINX-NEXT: lw a0, 8(sp) -; RV32IZDINXZHINX-NEXT: lw a1, 12(sp) -; RV32IZDINXZHINX-NEXT: addi sp, sp, 16 -; RV32IZDINXZHINX-NEXT: ret -; -; RV64IZDINXZHINX-LABEL: fcvt_d_h: -; RV64IZDINXZHINX: # %bb.0: -; RV64IZDINXZHINX-NEXT: fcvt.d.h a0, a0 -; RV64IZDINXZHINX-NEXT: ret +; CHECKIZDINXZHINX-LABEL: fcvt_d_h: +; CHECKIZDINXZHINX: # %bb.0: +; CHECKIZDINXZHINX-NEXT: fcvt.d.h a0, a0 +; CHECKIZDINXZHINX-NEXT: ret ; ; RV32I-LABEL: fcvt_d_h: ; RV32I: # %bb.0: @@ -5607,13 +5579,7 @@ define double @fcvt_d_h(half %a) nounwind { ; ; CHECK32-IZDINXZHINXMIN-LABEL: fcvt_d_h: ; CHECK32-IZDINXZHINXMIN: # %bb.0: -; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, -16 ; CHECK32-IZDINXZHINXMIN-NEXT: fcvt.d.h a0, a0 -; CHECK32-IZDINXZHINXMIN-NEXT: sw a0, 8(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: sw a1, 12(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: lw a0, 8(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: lw a1, 12(sp) -; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, 16 ; CHECK32-IZDINXZHINXMIN-NEXT: ret ; ; CHECK64-IZDINXZHINXMIN-LABEL: fcvt_d_h: diff --git a/llvm/test/CodeGen/RISCV/pr64645.ll b/llvm/test/CodeGen/RISCV/pr64645.ll index 44dce5aabd22..f6d46516a3c0 100644 --- a/llvm/test/CodeGen/RISCV/pr64645.ll +++ b/llvm/test/CodeGen/RISCV/pr64645.ll @@ -5,34 +5,8 @@ define <2 x double> @v2f64(<2 x double> %x, <2 x double> %y) nounwind { ; CHECK-LABEL: v2f64: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: sw a4, 8(sp) -; CHECK-NEXT: sw a5, 12(sp) -; CHECK-NEXT: lw a4, 8(sp) -; CHECK-NEXT: lw a5, 12(sp) -; CHECK-NEXT: sw a0, 8(sp) -; CHECK-NEXT: sw a1, 12(sp) -; CHECK-NEXT: lw a0, 8(sp) -; CHECK-NEXT: lw a1, 12(sp) -; CHECK-NEXT: sw a6, 8(sp) -; CHECK-NEXT: sw a7, 12(sp) -; CHECK-NEXT: lw a6, 8(sp) -; CHECK-NEXT: lw a7, 12(sp) -; CHECK-NEXT: sw a2, 8(sp) -; CHECK-NEXT: sw a3, 12(sp) -; CHECK-NEXT: lw a2, 8(sp) -; CHECK-NEXT: lw a3, 12(sp) ; CHECK-NEXT: fadd.d a2, a2, a6 ; CHECK-NEXT: fadd.d a0, a0, a4 -; CHECK-NEXT: sw a0, 8(sp) -; CHECK-NEXT: sw a1, 12(sp) -; CHECK-NEXT: lw a0, 8(sp) -; CHECK-NEXT: lw a1, 12(sp) -; CHECK-NEXT: sw a2, 8(sp) -; CHECK-NEXT: sw a3, 12(sp) -; CHECK-NEXT: lw a2, 8(sp) -; CHECK-NEXT: lw a3, 12(sp) -; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret %1 = fadd <2 x double> %x, %y ret <2 x double> %1 diff --git a/llvm/test/CodeGen/RISCV/zdinx-asm-constraint.ll b/llvm/test/CodeGen/RISCV/zdinx-asm-constraint.ll index 63c46ca4eafc..95695aa69776 100644 --- a/llvm/test/CodeGen/RISCV/zdinx-asm-constraint.ll +++ b/llvm/test/CodeGen/RISCV/zdinx-asm-constraint.ll @@ -4,21 +4,15 @@ define dso_local void @zdinx_asm(ptr nocapture noundef writeonly %a, double noundef %b, double noundef %c) nounwind { ; CHECK-LABEL: zdinx_asm: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: sw a1, 8(sp) -; CHECK-NEXT: sw a2, 12(sp) -; CHECK-NEXT: lw a6, 8(sp) -; CHECK-NEXT: lw a7, 12(sp) -; CHECK-NEXT: sw a3, 8(sp) -; CHECK-NEXT: sw a4, 12(sp) -; CHECK-NEXT: lw a2, 8(sp) -; CHECK-NEXT: lw a3, 12(sp) +; CHECK-NEXT: mv a5, a4 +; CHECK-NEXT: mv a7, a2 +; CHECK-NEXT: mv a4, a3 +; CHECK-NEXT: mv a6, a1 ; CHECK-NEXT: #APP -; CHECK-NEXT: fsgnjx.d a2, a6, a2 +; CHECK-NEXT: fsgnjx.d a2, a6, a4 ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: sw a2, 8(a0) ; CHECK-NEXT: sw a3, 12(a0) -; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret entry: %arrayidx = getelementptr inbounds double, ptr %a, i32 1 diff --git a/llvm/test/CodeGen/RISCV/zdinx-boundary-check.ll b/llvm/test/CodeGen/RISCV/zdinx-boundary-check.ll index 3eeb704f80eb..f56d47716bd7 100644 --- a/llvm/test/CodeGen/RISCV/zdinx-boundary-check.ll +++ b/llvm/test/CodeGen/RISCV/zdinx-boundary-check.ll @@ -7,15 +7,11 @@ define void @foo(ptr nocapture %p, double %d) nounwind { ; RV32ZDINX-LABEL: foo: ; RV32ZDINX: # %bb.0: # %entry -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: sw a1, 8(sp) -; RV32ZDINX-NEXT: sw a2, 12(sp) -; RV32ZDINX-NEXT: lw a2, 8(sp) -; RV32ZDINX-NEXT: lw a3, 12(sp) +; RV32ZDINX-NEXT: mv a3, a2 ; RV32ZDINX-NEXT: addi a0, a0, 2047 +; RV32ZDINX-NEXT: mv a2, a1 ; RV32ZDINX-NEXT: sw a2, -3(a0) ; RV32ZDINX-NEXT: sw a3, 1(a0) -; RV32ZDINX-NEXT: addi sp, sp, 16 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: foo: @@ -31,16 +27,12 @@ entry: define void @foo2(ptr nocapture %p, double %d) nounwind { ; RV32ZDINX-LABEL: foo2: ; RV32ZDINX: # %bb.0: # %entry -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: sw a1, 8(sp) -; RV32ZDINX-NEXT: sw a2, 12(sp) -; RV32ZDINX-NEXT: lw a2, 8(sp) -; RV32ZDINX-NEXT: lw a3, 12(sp) +; RV32ZDINX-NEXT: mv a3, a2 +; RV32ZDINX-NEXT: mv a2, a1 ; RV32ZDINX-NEXT: fadd.d a2, a2, a2 ; RV32ZDINX-NEXT: addi a0, a0, 2047 ; RV32ZDINX-NEXT: sw a2, -3(a0) ; RV32ZDINX-NEXT: sw a3, 1(a0) -; RV32ZDINX-NEXT: addi sp, sp, 16 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: foo2: @@ -117,15 +109,11 @@ entry: define void @foo5(ptr nocapture %p, double %d) nounwind { ; RV32ZDINX-LABEL: foo5: ; RV32ZDINX: # %bb.0: # %entry -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: sw a1, 8(sp) -; RV32ZDINX-NEXT: sw a2, 12(sp) -; RV32ZDINX-NEXT: lw a2, 8(sp) -; RV32ZDINX-NEXT: lw a3, 12(sp) +; RV32ZDINX-NEXT: mv a3, a2 ; RV32ZDINX-NEXT: addi a0, a0, -2048 +; RV32ZDINX-NEXT: mv a2, a1 ; RV32ZDINX-NEXT: sw a2, -1(a0) ; RV32ZDINX-NEXT: sw a3, 3(a0) -; RV32ZDINX-NEXT: addi sp, sp, 16 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: foo5: @@ -142,19 +130,15 @@ entry: define void @foo6(ptr %p, double %d) nounwind { ; RV32ZDINX-LABEL: foo6: ; RV32ZDINX: # %bb.0: # %entry -; RV32ZDINX-NEXT: addi sp, sp, -16 -; RV32ZDINX-NEXT: sw a1, 8(sp) -; RV32ZDINX-NEXT: sw a2, 12(sp) -; RV32ZDINX-NEXT: lw a2, 8(sp) -; RV32ZDINX-NEXT: lw a3, 12(sp) -; RV32ZDINX-NEXT: lui a1, %hi(.LCPI5_0) -; RV32ZDINX-NEXT: lw a4, %lo(.LCPI5_0)(a1) -; RV32ZDINX-NEXT: lw a5, %lo(.LCPI5_0+4)(a1) +; RV32ZDINX-NEXT: lui a3, %hi(.LCPI5_0) +; RV32ZDINX-NEXT: lw a4, %lo(.LCPI5_0)(a3) +; RV32ZDINX-NEXT: lw a5, %lo(.LCPI5_0+4)(a3) +; RV32ZDINX-NEXT: mv a3, a2 +; RV32ZDINX-NEXT: mv a2, a1 ; RV32ZDINX-NEXT: fadd.d a2, a2, a4 ; RV32ZDINX-NEXT: addi a0, a0, 2047 ; RV32ZDINX-NEXT: sw a2, -3(a0) ; RV32ZDINX-NEXT: sw a3, 1(a0) -; RV32ZDINX-NEXT: addi sp, sp, 16 ; RV32ZDINX-NEXT: ret ; ; RV64ZDINX-LABEL: foo6: -- GitLab From 3deaa77f1a25f0cdfcf23c34fac0b51293f32f9c Mon Sep 17 00:00:00 2001 From: Tom Eccles <tom.eccles@arm.com> Date: Wed, 20 Mar 2024 15:47:00 +0000 Subject: [PATCH 267/307] [flang][OpenMP] simplify getReductionName (#85666) Re-use fir::getTypeAsString instead of creating something new here. This spells integer names like i32 instead of i_32 so there is a lot of test churn. --- flang/lib/Lower/OpenMP/ReductionProcessor.cpp | 75 ++++++------------- flang/lib/Lower/OpenMP/ReductionProcessor.h | 8 +- .../OpenMP/FIR/wsloop-reduction-add-byref.f90 | 22 +++--- .../Lower/OpenMP/FIR/wsloop-reduction-add.f90 | 28 +++---- .../FIR/wsloop-reduction-iand-byref.f90 | 4 +- .../FIR/wsloop-reduction-ieor-byref.f90 | 4 +- .../OpenMP/FIR/wsloop-reduction-ior-byref.f90 | 4 +- .../OpenMP/FIR/wsloop-reduction-max-byref.f90 | 8 +- .../OpenMP/FIR/wsloop-reduction-min-byref.f90 | 8 +- .../Lower/OpenMP/default-clause-byref.f90 | 2 +- flang/test/Lower/OpenMP/default-clause.f90 | 2 +- .../Lower/OpenMP/parallel-reduction-array.f90 | 4 +- .../OpenMP/parallel-reduction-array2.f90 | 4 +- .../OpenMP/parallel-reduction-rename.f90 | 4 +- .../parallel-wsloop-reduction-byref.f90 | 2 +- .../OpenMP/parallel-wsloop-reduction.f90 | 2 +- .../OpenMP/wsloop-reduction-add-byref.f90 | 22 +++--- .../wsloop-reduction-add-hlfir-byref.f90 | 6 +- .../OpenMP/wsloop-reduction-add-hlfir.f90 | 4 +- .../Lower/OpenMP/wsloop-reduction-add.f90 | 32 +++----- .../Lower/OpenMP/wsloop-reduction-array.f90 | 4 +- .../Lower/OpenMP/wsloop-reduction-array2.f90 | 4 +- .../OpenMP/wsloop-reduction-iand-byref.f90 | 4 +- .../Lower/OpenMP/wsloop-reduction-iand.f90 | 4 +- .../OpenMP/wsloop-reduction-ieor-byref.f90 | 4 +- .../OpenMP/wsloop-reduction-ior-byref.f90 | 6 +- .../Lower/OpenMP/wsloop-reduction-ior.f90 | 4 +- .../OpenMP/wsloop-reduction-max-2-byref.f90 | 2 +- .../Lower/OpenMP/wsloop-reduction-max-2.f90 | 2 +- .../OpenMP/wsloop-reduction-max-byref.f90 | 10 +-- .../wsloop-reduction-max-hlfir-byref.f90 | 4 +- .../OpenMP/wsloop-reduction-max-hlfir.f90 | 4 +- .../Lower/OpenMP/wsloop-reduction-max.f90 | 10 +-- .../OpenMP/wsloop-reduction-min-byref.f90 | 10 +-- .../Lower/OpenMP/wsloop-reduction-min.f90 | 10 +-- .../Lower/OpenMP/wsloop-reduction-min2.f90 | 4 +- .../OpenMP/wsloop-reduction-mul-byref.f90 | 22 +++--- .../Lower/OpenMP/wsloop-reduction-mul.f90 | 23 +++--- 38 files changed, 163 insertions(+), 213 deletions(-) diff --git a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp index d01c585e0ddb..2477f635792a 100644 --- a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp @@ -81,8 +81,10 @@ bool ReductionProcessor::supportedIntrinsicProcReduction( return redType; } -std::string ReductionProcessor::getReductionName(llvm::StringRef name, - mlir::Type ty, bool isByRef) { +std::string +ReductionProcessor::getReductionName(llvm::StringRef name, + const fir::KindMapping &kindMap, + mlir::Type ty, bool isByRef) { ty = fir::unwrapRefType(ty); // extra string to distinguish reduction functions for variables passed by @@ -91,47 +93,12 @@ std::string ReductionProcessor::getReductionName(llvm::StringRef name, if (isByRef) byrefAddition = "_byref"; - if (fir::isa_trivial(ty)) - return (llvm::Twine(name) + - (ty.isIntOrIndex() ? llvm::Twine("_i_") : llvm::Twine("_f_")) + - llvm::Twine(ty.getIntOrFloatBitWidth()) + byrefAddition) - .str(); - - // creates a name like reduction_i_64_box_ux4x3 - if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(ty)) { - // TODO: support for allocatable boxes: - // !fir.box<!fir.heap<!fir.array<...>>> - fir::SequenceType seqTy = fir::unwrapRefType(boxTy.getEleTy()) - .dyn_cast_or_null<fir::SequenceType>(); - if (!seqTy) - return {}; - - std::string prefix = getReductionName( - name, fir::unwrapSeqOrBoxedSeqType(ty), /*isByRef=*/false); - if (prefix.empty()) - return {}; - std::stringstream tyStr; - tyStr << prefix << "_box_"; - bool first = true; - for (std::int64_t extent : seqTy.getShape()) { - if (first) - first = false; - else - tyStr << "x"; - if (extent == seqTy.getUnknownExtent()) - tyStr << 'u'; // I'm not sure that '?' is safe in symbol names - else - tyStr << extent; - } - return (tyStr.str() + byrefAddition).str(); - } - - return {}; + return fir::getTypeAsString(ty, kindMap, (name + byrefAddition).str()); } std::string ReductionProcessor::getReductionName( - omp::clause::DefinedOperator::IntrinsicOperator intrinsicOp, mlir::Type ty, - bool isByRef) { + omp::clause::DefinedOperator::IntrinsicOperator intrinsicOp, + const fir::KindMapping &kindMap, mlir::Type ty, bool isByRef) { std::string reductionName; switch (intrinsicOp) { @@ -154,7 +121,7 @@ std::string ReductionProcessor::getReductionName( break; } - return getReductionName(reductionName, ty, isByRef); + return getReductionName(reductionName, kindMap, ty, isByRef); } mlir::Value @@ -162,9 +129,9 @@ ReductionProcessor::getReductionInitValue(mlir::Location loc, mlir::Type type, ReductionIdentifier redId, fir::FirOpBuilder &builder) { type = fir::unwrapRefType(type); - assert((fir::isa_integer(type) || fir::isa_real(type) || - type.isa<fir::LogicalType>()) && - "only integer, logical and real types are currently supported"); + if (!fir::isa_integer(type) && !fir::isa_real(type) && + !mlir::isa<fir::LogicalType>(type)) + TODO(loc, "Reduction of some types is not supported"); switch (redId) { case ReductionIdentifier::MAX: { if (auto ty = type.dyn_cast<mlir::FloatType>()) { @@ -463,8 +430,7 @@ mlir::omp::DeclareReductionOp ReductionProcessor::createDeclareReduction( mlir::OpBuilder::InsertionGuard guard(builder); mlir::ModuleOp module = builder.getModule(); - if (reductionOpName.empty()) - TODO(loc, "Reduction of some types is not supported"); + assert(!reductionOpName.empty()); auto decl = module.lookupSymbol<mlir::omp::DeclareReductionOp>(reductionOpName); @@ -601,15 +567,18 @@ void ReductionProcessor::addDeclareReduction( for (mlir::Value symVal : reductionVars) { auto redType = mlir::cast<fir::ReferenceType>(symVal.getType()); + const auto &kindMap = firOpBuilder.getKindMap(); if (redType.getEleTy().isa<fir::LogicalType>()) - decl = createDeclareReduction( - firOpBuilder, - getReductionName(intrinsicOp, firOpBuilder.getI1Type(), isByRef), - redId, redType, currentLocation, isByRef); + decl = createDeclareReduction(firOpBuilder, + getReductionName(intrinsicOp, kindMap, + firOpBuilder.getI1Type(), + isByRef), + redId, redType, currentLocation, isByRef); else decl = createDeclareReduction( - firOpBuilder, getReductionName(intrinsicOp, redType, isByRef), - redId, redType, currentLocation, isByRef); + firOpBuilder, + getReductionName(intrinsicOp, kindMap, redType, isByRef), redId, + redType, currentLocation, isByRef); reductionDeclSymbols.push_back(mlir::SymbolRefAttr::get( firOpBuilder.getContext(), decl.getSymName())); } @@ -631,7 +600,7 @@ void ReductionProcessor::addDeclareReduction( decl = createDeclareReduction( firOpBuilder, getReductionName(getRealName(*reductionIntrinsic).ToString(), - redType, isByRef), + firOpBuilder.getKindMap(), redType, isByRef), redId, redType, currentLocation, isByRef); reductionDeclSymbols.push_back(mlir::SymbolRefAttr::get( firOpBuilder.getContext(), decl.getSymName())); diff --git a/flang/lib/Lower/OpenMP/ReductionProcessor.h b/flang/lib/Lower/OpenMP/ReductionProcessor.h index 52b44e555bdb..ee2732547fc2 100644 --- a/flang/lib/Lower/OpenMP/ReductionProcessor.h +++ b/flang/lib/Lower/OpenMP/ReductionProcessor.h @@ -76,12 +76,14 @@ public: static bool doReductionByRef(const llvm::SmallVectorImpl<mlir::Value> &reductionVars); - static std::string getReductionName(llvm::StringRef name, mlir::Type ty, - bool isByRef); + static std::string getReductionName(llvm::StringRef name, + const fir::KindMapping &kindMap, + mlir::Type ty, bool isByRef); static std::string getReductionName(omp::clause::DefinedOperator::IntrinsicOperator intrinsicOp, - mlir::Type ty, bool isByRef); + const fir::KindMapping &kindMap, mlir::Type ty, + bool isByRef); /// This function returns the identity value of the operator \p /// reductionOpName. For example: diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add-byref.f90 index e9eadb4bc31a..08f5a0fcdbae 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add-byref.f90 @@ -2,7 +2,7 @@ ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.declare_reduction @add_reduction_f_64_byref : !fir.ref<f64> +! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_f64 : !fir.ref<f64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f64>): ! CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f64 @@ -19,7 +19,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f64>) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_64_byref : !fir.ref<i64> +! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_i64 : !fir.ref<i64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i64>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i64 @@ -36,7 +36,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<i64>) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_f_32_byref : !fir.ref<f32> +! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_f32 : !fir.ref<f32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f32 @@ -53,7 +53,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_i32 : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 @@ -80,7 +80,7 @@ ! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_5:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_byref %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<i32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_i32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<i32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { ! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32> ! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> @@ -116,7 +116,7 @@ end subroutine ! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_5:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_f_32_byref %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<f32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_f32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<f32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { ! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_7]] : !fir.ref<f32> ! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> @@ -152,7 +152,7 @@ end subroutine ! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_5:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_byref %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<i32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_i32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<i32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { ! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32> @@ -187,7 +187,7 @@ end subroutine ! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_5:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_f_32_byref %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<f32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_f32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<f32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { ! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> f32 @@ -229,7 +229,7 @@ end subroutine ! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_byref %[[VAL_1]] -> %[[VAL_11:.*]] : !fir.ref<i32>, @add_reduction_i_32_byref %[[VAL_2]] -> %[[VAL_12:.*]] : !fir.ref<i32>, @add_reduction_i_32_byref %[[VAL_3]] -> %[[VAL_13:.*]] : !fir.ref<i32>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_i32 %[[VAL_1]] -> %[[VAL_11:.*]] : !fir.ref<i32>, @add_reduction_byref_i32 %[[VAL_2]] -> %[[VAL_12:.*]] : !fir.ref<i32>, @add_reduction_byref_i32 %[[VAL_3]] -> %[[VAL_13:.*]] : !fir.ref<i32>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { ! CHECK: fir.store %[[VAL_14]] to %[[VAL_7]] : !fir.ref<i32> ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_11]] : !fir.ref<i32> ! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32> @@ -282,7 +282,7 @@ end subroutine ! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_f_32_byref %[[VAL_1]] -> %[[VAL_11:.*]] : !fir.ref<f32>, @add_reduction_f_32_byref %[[VAL_2]] -> %[[VAL_12:.*]] : !fir.ref<f32>, @add_reduction_f_32_byref %[[VAL_3]] -> %[[VAL_13:.*]] : !fir.ref<f32>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_f32 %[[VAL_1]] -> %[[VAL_11:.*]] : !fir.ref<f32>, @add_reduction_byref_f32 %[[VAL_2]] -> %[[VAL_12:.*]] : !fir.ref<f32>, @add_reduction_byref_f32 %[[VAL_3]] -> %[[VAL_13:.*]] : !fir.ref<f32>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { ! CHECK: fir.store %[[VAL_14]] to %[[VAL_7]] : !fir.ref<i32> ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_11]] : !fir.ref<f32> ! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32> @@ -341,7 +341,7 @@ end subroutine ! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_byref %[[VAL_2]] -> %[[VAL_13:.*]] : !fir.ref<i32>, @add_reduction_i_64_byref %[[VAL_3]] -> %[[VAL_14:.*]] : !fir.ref<i64>, @add_reduction_f_32_byref %[[VAL_4]] -> %[[VAL_15:.*]] : !fir.ref<f32>, @add_reduction_f_64_byref %[[VAL_1]] -> %[[VAL_16:.*]] : !fir.ref<f64>) for (%[[VAL_17:.*]]) : i32 = (%[[VAL_10]]) to (%[[VAL_11]]) inclusive step (%[[VAL_12]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_i32 %[[VAL_2]] -> %[[VAL_13:.*]] : !fir.ref<i32>, @add_reduction_byref_i64 %[[VAL_3]] -> %[[VAL_14:.*]] : !fir.ref<i64>, @add_reduction_byref_f32 %[[VAL_4]] -> %[[VAL_15:.*]] : !fir.ref<f32>, @add_reduction_byref_f64 %[[VAL_1]] -> %[[VAL_16:.*]] : !fir.ref<f64>) for (%[[VAL_17:.*]]) : i32 = (%[[VAL_10]]) to (%[[VAL_11]]) inclusive step (%[[VAL_12]]) { ! CHECK: fir.store %[[VAL_17]] to %[[VAL_9]] : !fir.ref<i32> ! CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_13]] : !fir.ref<i32> ! CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add.f90 index b53dc715e65b..dc96b875f745 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-add.f90 @@ -1,13 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s -! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! The script is designed to make adding checks to -! a test case fast, it is *not* designed to be authoritative -! about what constitutes a good test! The CHECK should be -! minimized and named to reflect the test intent. - -! CHECK-LABEL: omp.declare_reduction @add_reduction_f_64 : f64 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_f64 : f64 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f64): ! CHECK: %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f64 ! CHECK: omp.yield(%[[VAL_1]] : f64) @@ -18,7 +12,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f64) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_64 : i64 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i64 : i64 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i64): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i64 ! CHECK: omp.yield(%[[VAL_1]] : i64) @@ -29,7 +23,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : i64) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_f_32 : f32 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_f32 : f32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f32 ! CHECK: omp.yield(%[[VAL_1]] : f32) @@ -40,7 +34,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) @@ -61,7 +55,7 @@ ! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_5:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_i_32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<i32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { +! CHECK: omp.wsloop reduction(@add_reduction_i32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<i32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { ! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32> ! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> @@ -97,7 +91,7 @@ end subroutine ! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_5:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_f_32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<f32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { +! CHECK: omp.wsloop reduction(@add_reduction_f32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<f32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { ! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_7]] : !fir.ref<f32> ! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> @@ -133,7 +127,7 @@ end subroutine ! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_5:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_i_32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<i32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { +! CHECK: omp.wsloop reduction(@add_reduction_i32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<i32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { ! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32> @@ -168,7 +162,7 @@ end subroutine ! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_5:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_f_32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<f32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { +! CHECK: omp.wsloop reduction(@add_reduction_f32 %[[VAL_1]] -> %[[VAL_7:.*]] : !fir.ref<f32>) for (%[[VAL_8:.*]]) : i32 = (%[[VAL_4]]) to (%[[VAL_5]]) inclusive step (%[[VAL_6]]) { ! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> ! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> f32 @@ -210,7 +204,7 @@ end subroutine ! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_i_32 %[[VAL_1]] -> %[[VAL_11:.*]] : !fir.ref<i32>, @add_reduction_i_32 %[[VAL_2]] -> %[[VAL_12:.*]] : !fir.ref<i32>, @add_reduction_i_32 %[[VAL_3]] -> %[[VAL_13:.*]] : !fir.ref<i32>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { +! CHECK: omp.wsloop reduction(@add_reduction_i32 %[[VAL_1]] -> %[[VAL_11:.*]] : !fir.ref<i32>, @add_reduction_i32 %[[VAL_2]] -> %[[VAL_12:.*]] : !fir.ref<i32>, @add_reduction_i32 %[[VAL_3]] -> %[[VAL_13:.*]] : !fir.ref<i32>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { ! CHECK: fir.store %[[VAL_14]] to %[[VAL_7]] : !fir.ref<i32> ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_11]] : !fir.ref<i32> ! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32> @@ -263,7 +257,7 @@ end subroutine ! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_f_32 %[[VAL_1]] -> %[[VAL_11:.*]] : !fir.ref<f32>, @add_reduction_f_32 %[[VAL_2]] -> %[[VAL_12:.*]] : !fir.ref<f32>, @add_reduction_f_32 %[[VAL_3]] -> %[[VAL_13:.*]] : !fir.ref<f32>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { +! CHECK: omp.wsloop reduction(@add_reduction_f32 %[[VAL_1]] -> %[[VAL_11:.*]] : !fir.ref<f32>, @add_reduction_f32 %[[VAL_2]] -> %[[VAL_12:.*]] : !fir.ref<f32>, @add_reduction_f32 %[[VAL_3]] -> %[[VAL_13:.*]] : !fir.ref<f32>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { ! CHECK: fir.store %[[VAL_14]] to %[[VAL_7]] : !fir.ref<i32> ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_11]] : !fir.ref<f32> ! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_7]] : !fir.ref<i32> @@ -322,7 +316,7 @@ end subroutine ! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_i_32 %[[VAL_2]] -> %[[VAL_13:.*]] : !fir.ref<i32>, @add_reduction_i_64 %[[VAL_3]] -> %[[VAL_14:.*]] : !fir.ref<i64>, @add_reduction_f_32 %[[VAL_4]] -> %[[VAL_15:.*]] : !fir.ref<f32>, @add_reduction_f_64 %[[VAL_1]] -> %[[VAL_16:.*]] : !fir.ref<f64>) for (%[[VAL_17:.*]]) : i32 = (%[[VAL_10]]) to (%[[VAL_11]]) inclusive step (%[[VAL_12]]) { +! CHECK: omp.wsloop reduction(@add_reduction_i32 %[[VAL_2]] -> %[[VAL_13:.*]] : !fir.ref<i32>, @add_reduction_i64 %[[VAL_3]] -> %[[VAL_14:.*]] : !fir.ref<i64>, @add_reduction_f32 %[[VAL_4]] -> %[[VAL_15:.*]] : !fir.ref<f32>, @add_reduction_f64 %[[VAL_1]] -> %[[VAL_16:.*]] : !fir.ref<f64>) for (%[[VAL_17:.*]]) : i32 = (%[[VAL_10]]) to (%[[VAL_11]]) inclusive step (%[[VAL_12]]) { ! CHECK: fir.store %[[VAL_17]] to %[[VAL_9]] : !fir.ref<i32> ! CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_13]] : !fir.ref<i32> ! CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand-byref.f90 index 92e5e8a0abb5..6717597ff3b0 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s -!CHECK-LABEL: omp.declare_reduction @iand_i_32_byref : !fir.ref<i32> +!CHECK-LABEL: omp.declare_reduction @iand_byref_i32 : !fir.ref<i32> !CHECK-SAME: init { !CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): !CHECK: %[[C0_1:.*]] = arith.constant -1 : i32 @@ -23,7 +23,7 @@ !CHECK-SAME: %[[Y_BOX:.*]]: !fir.box<!fir.array<?xi32>> !CHECK: %[[X_REF:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFreduction_iandEx"} !CHECK: omp.parallel -!CHECK: omp.wsloop byref reduction(@iand_i_32_byref %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<i32>) for +!CHECK: omp.wsloop byref reduction(@iand_byref_i32 %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<i32>) for !CHECK: %[[LPRV:.+]] = fir.load %[[PRV]] : !fir.ref<i32> !CHECK: %[[Y_I_REF:.*]] = fir.coordinate_of %[[Y_BOX]] !CHECK: %[[Y_I:.*]] = fir.load %[[Y_I_REF]] : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor-byref.f90 index c55778903924..1baa59a510fa 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -mmlir --force-byref-reduction -fopenmp %s -o - | FileCheck %s -! CHECK-LABEL: omp.declare_reduction @ieor_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @ieor_byref_i32 : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 @@ -22,7 +22,7 @@ !CHECK-SAME: %[[Y_BOX:.*]]: !fir.box<!fir.array<?xi32>> !CHECK: %[[X_REF:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFreduction_ieorEx"} !CHECK: omp.parallel -!CHECK: omp.wsloop byref reduction(@ieor_i_32_byref %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<i32>) for +!CHECK: omp.wsloop byref reduction(@ieor_byref_i32 %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<i32>) for !CHECK: %[[LPRV:.+]] = fir.load %[[PRV]] : !fir.ref<i32> !CHECK: %[[Y_I_REF:.*]] = fir.coordinate_of %[[Y_BOX]] !CHECK: %[[Y_I:.*]] = fir.load %[[Y_I_REF]] : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior-byref.f90 index 57f393b9688e..5482ef33fc8a 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s -! CHECK-LABEL: omp.declare_reduction @ior_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @ior_byref_i32 : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 @@ -22,7 +22,7 @@ !CHECK-SAME: %[[Y_BOX:.*]]: !fir.box<!fir.array<?xi32>> !CHECK: %[[X_REF:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFreduction_iorEx"} !CHECK: omp.parallel -!CHECK: omp.wsloop byref reduction(@ior_i_32_byref %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<i32>) for +!CHECK: omp.wsloop byref reduction(@ior_byref_i32 %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<i32>) for !CHECK: %[[LPRV:.+]] = fir.load %[[PRV]] : !fir.ref<i32> !CHECK: %[[Y_I_REF:.*]] = fir.coordinate_of %[[Y_BOX]] !CHECK: %[[Y_I:.*]] = fir.load %[[Y_I_REF]] : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 index bc655b5e4295..f0979ab95f56 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp --force-byref-reduction -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp -mmlir --force-byref-reduction -o - %s 2>&1 | FileCheck %s -!CHECK: omp.declare_reduction @max_f_32_byref : !fir.ref<f32> +!CHECK: omp.declare_reduction @max_byref_f32 : !fir.ref<f32> !CHECK-SAME: init { !CHECK: %[[MINIMUM_VAL:.*]] = arith.constant -3.40282347E+38 : f32 !CHECK: %[[REF:.*]] = fir.alloca f32 @@ -15,7 +15,7 @@ !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32> !CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) -!CHECK-LABEL: omp.declare_reduction @max_i_32_byref : !fir.ref<i32> +!CHECK-LABEL: omp.declare_reduction @max_byref_i32 : !fir.ref<i32> !CHECK-SAME: init { !CHECK: %[[MINIMUM_VAL:.*]] = arith.constant -2147483648 : i32 !CHECK: fir.store %[[MINIMUM_VAL]] to %[[REF]] : !fir.ref<i32> @@ -32,7 +32,7 @@ !CHECK-SAME: %[[Y_BOX:.*]]: !fir.box<!fir.array<?xi32>> !CHECK: %[[X_REF:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFreduction_max_intEx"} !CHECK: omp.parallel -!CHECK: omp.wsloop byref reduction(@max_i_32_byref %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<i32>) for +!CHECK: omp.wsloop byref reduction(@max_byref_i32 %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<i32>) for !CHECK: %[[LPRV:.+]] = fir.load %[[PRV]] : !fir.ref<i32> !CHECK: %[[Y_I_REF:.*]] = fir.coordinate_of %[[Y_BOX]] !CHECK: %[[Y_I:.*]] = fir.load %[[Y_I_REF]] : !fir.ref<i32> @@ -45,7 +45,7 @@ !CHECK-SAME: %[[Y_BOX:.*]]: !fir.box<!fir.array<?xf32>> !CHECK: %[[X_REF:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFreduction_max_realEx"} !CHECK: omp.parallel -!CHECK: omp.wsloop byref reduction(@max_f_32_byref %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<f32>) for +!CHECK: omp.wsloop byref reduction(@max_byref_f32 %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<f32>) for !CHECK: %[[LPRV:.+]] = fir.load %[[PRV]] : !fir.ref<f32> !CHECK: %[[Y_I_REF:.*]] = fir.coordinate_of %[[Y_BOX]] !CHECK: %[[Y_I:.*]] = fir.load %[[Y_I_REF]] : !fir.ref<f32> diff --git a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 index ce928aa131b7..24aa8e46e5bb 100644 --- a/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 +++ b/flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-fir -hlfir=false -fopenmp --force-byref-reduction -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -mmlir --force-byref-reduction -fopenmp -o - %s 2>&1 | FileCheck %s -!CHECK: omp.declare_reduction @min_f_32_byref : !fir.ref<f32> +!CHECK: omp.declare_reduction @min_byref_f32 : !fir.ref<f32> !CHECK-SAME: init { !CHECK: %[[MAXIMUM_VAL:.*]] = arith.constant 3.40282347E+38 : f32 !CHECK: %[[REF:.*]] = fir.alloca f32 @@ -15,7 +15,7 @@ !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32> !CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) -!CHECK-LABEL: omp.declare_reduction @min_i_32_byref : !fir.ref<i32> +!CHECK-LABEL: omp.declare_reduction @min_byref_i32 : !fir.ref<i32> !CHECK-SAME: init { !CHECK: %[[MAXIMUM_VAL:.*]] = arith.constant 2147483647 : i32 !CHECK: fir.store %[[MAXIMUM_VAL]] to %[[REF]] : !fir.ref<i32> @@ -32,7 +32,7 @@ !CHECK-SAME: %[[Y_BOX:.*]]: !fir.box<!fir.array<?xi32>> !CHECK: %[[X_REF:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFreduction_min_intEx"} !CHECK: omp.parallel -!CHECK: omp.wsloop byref reduction(@min_i_32_byref %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<i32>) for +!CHECK: omp.wsloop byref reduction(@min_byref_i32 %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<i32>) for !CHECK: %[[LPRV:.+]] = fir.load %[[PRV]] : !fir.ref<i32> !CHECK: %[[Y_I_REF:.*]] = fir.coordinate_of %[[Y_BOX]] !CHECK: %[[Y_I:.*]] = fir.load %[[Y_I_REF]] : !fir.ref<i32> @@ -46,7 +46,7 @@ !CHECK-SAME: %[[Y_BOX:.*]]: !fir.box<!fir.array<?xf32>> !CHECK: %[[X_REF:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFreduction_min_realEx"} !CHECK: omp.parallel -!CHECK: omp.wsloop byref reduction(@min_f_32_byref %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<f32>) for +!CHECK: omp.wsloop byref reduction(@min_byref_f32 %[[X_REF]] -> %[[PRV:.+]] : !fir.ref<f32>) for !CHECK: %[[LPRV:.+]] = fir.load %[[PRV]] : !fir.ref<f32> !CHECK: %[[Y_I_REF:.*]] = fir.coordinate_of %[[Y_BOX]] !CHECK: %[[Y_I:.*]] = fir.load %[[Y_I_REF]] : !fir.ref<f32> diff --git a/flang/test/Lower/OpenMP/default-clause-byref.f90 b/flang/test/Lower/OpenMP/default-clause-byref.f90 index 5d9538e53069..1167ba7e6ae0 100644 --- a/flang/test/Lower/OpenMP/default-clause-byref.f90 +++ b/flang/test/Lower/OpenMP/default-clause-byref.f90 @@ -352,7 +352,7 @@ subroutine skipped_default_clause_checks() type(it)::iii !CHECK: omp.parallel { -!CHECK: omp.wsloop byref reduction(@min_i_32_byref %[[VAL_Z_DECLARE]]#0 -> %[[PRV:.+]] : !fir.ref<i32>) for (%[[ARG:.*]]) {{.*}} { +!CHECK: omp.wsloop byref reduction(@min_byref_i32 %[[VAL_Z_DECLARE]]#0 -> %[[PRV:.+]] : !fir.ref<i32>) for (%[[ARG:.*]]) {{.*}} { !CHECK: omp.yield !CHECK: } !CHECK: omp.terminator diff --git a/flang/test/Lower/OpenMP/default-clause.f90 b/flang/test/Lower/OpenMP/default-clause.f90 index 0e118742689d..f86b51aef4e0 100644 --- a/flang/test/Lower/OpenMP/default-clause.f90 +++ b/flang/test/Lower/OpenMP/default-clause.f90 @@ -352,7 +352,7 @@ subroutine skipped_default_clause_checks() type(it)::iii !CHECK: omp.parallel { -!CHECK: omp.wsloop reduction(@min_i_32 %[[VAL_Z_DECLARE]]#0 -> %[[PRV:.+]] : !fir.ref<i32>) for (%[[ARG:.*]]) {{.*}} { +!CHECK: omp.wsloop reduction(@min_i32 %[[VAL_Z_DECLARE]]#0 -> %[[PRV:.+]] : !fir.ref<i32>) for (%[[ARG:.*]]) {{.*}} { !CHECK: omp.yield !CHECK: } !CHECK: omp.terminator diff --git a/flang/test/Lower/OpenMP/parallel-reduction-array.f90 b/flang/test/Lower/OpenMP/parallel-reduction-array.f90 index 359dab35e8a6..735a99854308 100644 --- a/flang/test/Lower/OpenMP/parallel-reduction-array.f90 +++ b/flang/test/Lower/OpenMP/parallel-reduction-array.f90 @@ -13,7 +13,7 @@ i(3) = 3 print *,i end program -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_box_3xi32 : !fir.ref<!fir.box<!fir.array<3xi32>>> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>): ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<3xi32> {bindc_name = ".tmp"} ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 @@ -53,7 +53,7 @@ end program ! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1(%[[VAL_2]]) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>> ! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.box<!fir.array<3xi32>> ! CHECK: fir.store %[[VAL_4]] to %[[VAL_5]] : !fir.ref<!fir.box<!fir.array<3xi32>>> -! CHECK: omp.parallel byref reduction(@add_reduction_i_32_box_3_byref %[[VAL_5]] -> %[[VAL_6:.*]] : !fir.ref<!fir.box<!fir.array<3xi32>>>) { +! CHECK: omp.parallel byref reduction(@add_reduction_byref_box_3xi32 %[[VAL_5]] -> %[[VAL_6:.*]] : !fir.ref<!fir.box<!fir.array<3xi32>>>) { ! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]] {uniq_name = "_QFEi"} : (!fir.ref<!fir.box<!fir.array<3xi32>>>) -> (!fir.ref<!fir.box<!fir.array<3xi32>>>, !fir.ref<!fir.box<!fir.array<3xi32>>>) ! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<3xi32>>> diff --git a/flang/test/Lower/OpenMP/parallel-reduction-array2.f90 b/flang/test/Lower/OpenMP/parallel-reduction-array2.f90 index 5a31be8d206b..4834047a98a4 100644 --- a/flang/test/Lower/OpenMP/parallel-reduction-array2.f90 +++ b/flang/test/Lower/OpenMP/parallel-reduction-array2.f90 @@ -13,7 +13,7 @@ i(3) = i(3) + 3 print *,i end program -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_box_3xi32 : !fir.ref<!fir.box<!fir.array<3xi32>>> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>): ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<3xi32> {bindc_name = ".tmp"} ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 @@ -53,7 +53,7 @@ end program ! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1(%[[VAL_2]]) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>> ! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.box<!fir.array<3xi32>> ! CHECK: fir.store %[[VAL_4]] to %[[VAL_5]] : !fir.ref<!fir.box<!fir.array<3xi32>>> -! CHECK: omp.parallel byref reduction(@add_reduction_i_32_box_3_byref %[[VAL_5]] -> %[[VAL_6:.*]] : !fir.ref<!fir.box<!fir.array<3xi32>>>) { +! CHECK: omp.parallel byref reduction(@add_reduction_byref_box_3xi32 %[[VAL_5]] -> %[[VAL_6:.*]] : !fir.ref<!fir.box<!fir.array<3xi32>>>) { ! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]] {uniq_name = "_QFEi"} : (!fir.ref<!fir.box<!fir.array<3xi32>>>) -> (!fir.ref<!fir.box<!fir.array<3xi32>>>, !fir.ref<!fir.box<!fir.array<3xi32>>>) ! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<3xi32>>> ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : index diff --git a/flang/test/Lower/OpenMP/parallel-reduction-rename.f90 b/flang/test/Lower/OpenMP/parallel-reduction-rename.f90 index 7845f808e6c5..c06343e997bf 100644 --- a/flang/test/Lower/OpenMP/parallel-reduction-rename.f90 +++ b/flang/test/Lower/OpenMP/parallel-reduction-rename.f90 @@ -14,7 +14,7 @@ end program main ! test that we understood that this should be a max reduction -! CHECK-LABEL: omp.declare_reduction @max_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @max_i32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant -2147483648 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) @@ -30,7 +30,7 @@ end program main ! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 ! CHECK: hlfir.assign %[[VAL_2]] to %[[VAL_1]]#0 : i32, !fir.ref<i32> -! CHECK: omp.parallel reduction(@max_i_32 %[[VAL_1]]#0 -> %[[VAL_3:.*]] : !fir.ref<i32>) { +! CHECK: omp.parallel reduction(@max_i32 %[[VAL_1]]#0 -> %[[VAL_3:.*]] : !fir.ref<i32>) { ! ... ! CHECK: omp.terminator diff --git a/flang/test/Lower/OpenMP/parallel-wsloop-reduction-byref.f90 b/flang/test/Lower/OpenMP/parallel-wsloop-reduction-byref.f90 index 8492a69fed58..66c80c31917b 100644 --- a/flang/test/Lower/OpenMP/parallel-wsloop-reduction-byref.f90 +++ b/flang/test/Lower/OpenMP/parallel-wsloop-reduction-byref.f90 @@ -4,7 +4,7 @@ ! RUN: flang-new -fc1 -fopenmp -mmlir --force-byref-reduction -emit-hlfir %s -o - | FileCheck %s ! CHECK: omp.parallel { -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32 +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_i32 subroutine sb integer :: x x = 0 diff --git a/flang/test/Lower/OpenMP/parallel-wsloop-reduction.f90 b/flang/test/Lower/OpenMP/parallel-wsloop-reduction.f90 index c13ec2bc4aec..fdedbb061607 100644 --- a/flang/test/Lower/OpenMP/parallel-wsloop-reduction.f90 +++ b/flang/test/Lower/OpenMP/parallel-wsloop-reduction.f90 @@ -4,7 +4,7 @@ ! RUN: flang-new -fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s ! CHECK: omp.parallel { -! CHECK: omp.wsloop reduction(@add_reduction_i_32 +! CHECK: omp.wsloop reduction(@add_reduction_i32 subroutine sb integer :: x x = 0 diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-add-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-add-byref.f90 index caec65b6051c..e63db33bbe25 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-add-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-add-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s -! CHECK-LABEL: omp.declare_reduction @add_reduction_f_64_byref : !fir.ref<f64> +! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_f64 : !fir.ref<f64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f64>): ! CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f64 @@ -18,7 +18,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f64>) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_64_byref : !fir.ref<i64> +! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_i64 : !fir.ref<i64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i64>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i64 @@ -35,7 +35,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<i64>) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_f_32_byref : !fir.ref<f32> +! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_f32 : !fir.ref<f32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0.000000e+00 : f32 @@ -52,7 +52,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_i32 : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 @@ -82,7 +82,7 @@ ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_byref %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_i32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_int_reductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref<i32> @@ -122,7 +122,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_f_32_byref %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_f32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_real_reductionEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref<f32> @@ -163,7 +163,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_byref %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_i32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_int_reduction_switch_orderEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref<i32> @@ -202,7 +202,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_f_32_byref %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_f32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_real_reduction_switch_orderEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref<i32> @@ -250,7 +250,7 @@ end subroutine ! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_14:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_15:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_byref %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<i32>, @add_reduction_i_32_byref %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<i32>, @add_reduction_i_32_byref %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<i32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_i32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<i32>, @add_reduction_byref_i32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<i32>, @add_reduction_byref_i32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<i32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { ! CHECK: fir.store %[[VAL_19]] to %[[VAL_12]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_16]] {uniq_name = "_QFmultiple_int_reductions_same_typeEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_17]] {uniq_name = "_QFmultiple_int_reductions_same_typeEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) @@ -311,7 +311,7 @@ end subroutine ! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_14:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_15:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_f_32_byref %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<f32>, @add_reduction_f_32_byref %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<f32>, @add_reduction_f_32_byref %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<f32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_f32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<f32>, @add_reduction_byref_f32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<f32>, @add_reduction_byref_f32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<f32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { ! CHECK: fir.store %[[VAL_19]] to %[[VAL_12]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_16]] {uniq_name = "_QFmultiple_real_reductions_same_typeEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_17]] {uniq_name = "_QFmultiple_real_reductions_same_typeEy"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) @@ -379,7 +379,7 @@ end subroutine ! CHECK: %[[VAL_16:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_17:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_18:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_byref %[[VAL_5]]#0 -> %[[VAL_19:.*]] : !fir.ref<i32>, @add_reduction_i_64_byref %[[VAL_7]]#0 -> %[[VAL_20:.*]] : !fir.ref<i64>, @add_reduction_f_32_byref %[[VAL_9]]#0 -> %[[VAL_21:.*]] : !fir.ref<f32>, @add_reduction_f_64_byref %[[VAL_3]]#0 -> %[[VAL_22:.*]] : !fir.ref<f64>) for (%[[VAL_23:.*]]) : i32 = (%[[VAL_16]]) to (%[[VAL_17]]) inclusive step (%[[VAL_18]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_i32 %[[VAL_5]]#0 -> %[[VAL_19:.*]] : !fir.ref<i32>, @add_reduction_byref_i64 %[[VAL_7]]#0 -> %[[VAL_20:.*]] : !fir.ref<i64>, @add_reduction_byref_f32 %[[VAL_9]]#0 -> %[[VAL_21:.*]] : !fir.ref<f32>, @add_reduction_byref_f64 %[[VAL_3]]#0 -> %[[VAL_22:.*]] : !fir.ref<f64>) for (%[[VAL_23:.*]]) : i32 = (%[[VAL_16]]) to (%[[VAL_17]]) inclusive step (%[[VAL_18]]) { ! CHECK: fir.store %[[VAL_23]] to %[[VAL_15]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_24:.*]]:2 = hlfir.declare %[[VAL_19]] {uniq_name = "_QFmultiple_reductions_different_typeEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_25:.*]]:2 = hlfir.declare %[[VAL_20]] {uniq_name = "_QFmultiple_reductions_different_typeEy"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir-byref.f90 index 5e5df8c1365a..3b4d9666c693 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir-byref.f90 @@ -1,9 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s -! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py - -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_i32 : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 @@ -33,7 +31,7 @@ ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_byref %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_i32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_int_reductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir.f90 index d6006f21b3bd..7c9070592e46 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-add-hlfir.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) @@ -27,7 +27,7 @@ ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_i_32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) +! CHECK: omp.wsloop reduction(@add_reduction_i32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_int_reductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 index d6222a248b7f..11e1ffb79f8e 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-add.f90 @@ -1,17 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s - -! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py - -! The script is designed to make adding checks to -! a test case fast, it is *not* designed to be authoritative -! about what constitutes a good test! The CHECK should be -! minimized and named to reflect the test intent. - - - -! CHECK-LABEL: omp.declare_reduction @add_reduction_f_64 : f64 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_f64 : f64 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f64): ! CHECK: %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f64 ! CHECK: omp.yield(%[[VAL_1]] : f64) @@ -22,7 +12,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f64) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_64 : i64 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i64 : i64 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i64): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i64 ! CHECK: omp.yield(%[[VAL_1]] : i64) @@ -33,7 +23,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : i64) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_f_32 : f32 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_f32 : f32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f32 ! CHECK: omp.yield(%[[VAL_1]] : f32) @@ -44,7 +34,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @add_reduction_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @add_reduction_i32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) @@ -68,7 +58,7 @@ ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_i_32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop reduction(@add_reduction_i32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_int_reductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref<i32> @@ -108,7 +98,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_f_32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop reduction(@add_reduction_f32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_real_reductionEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref<f32> @@ -149,7 +139,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_i_32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop reduction(@add_reduction_i32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_int_reduction_switch_orderEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref<i32> @@ -188,7 +178,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_f_32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop reduction(@add_reduction_f32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_real_reduction_switch_orderEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref<i32> @@ -236,7 +226,7 @@ end subroutine ! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_14:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_15:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_i_32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<i32>, @add_reduction_i_32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<i32>, @add_reduction_i_32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<i32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { +! CHECK: omp.wsloop reduction(@add_reduction_i32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<i32>, @add_reduction_i32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<i32>, @add_reduction_i32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<i32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { ! CHECK: fir.store %[[VAL_19]] to %[[VAL_12]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_16]] {uniq_name = "_QFmultiple_int_reductions_same_typeEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_17]] {uniq_name = "_QFmultiple_int_reductions_same_typeEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) @@ -297,7 +287,7 @@ end subroutine ! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_14:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_15:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_f_32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<f32>, @add_reduction_f_32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<f32>, @add_reduction_f_32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<f32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { +! CHECK: omp.wsloop reduction(@add_reduction_f32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<f32>, @add_reduction_f32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<f32>, @add_reduction_f32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<f32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { ! CHECK: fir.store %[[VAL_19]] to %[[VAL_12]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_16]] {uniq_name = "_QFmultiple_real_reductions_same_typeEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_17]] {uniq_name = "_QFmultiple_real_reductions_same_typeEy"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) @@ -365,7 +355,7 @@ end subroutine ! CHECK: %[[VAL_16:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_17:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_18:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@add_reduction_i_32 %[[VAL_5]]#0 -> %[[VAL_19:.*]] : !fir.ref<i32>, @add_reduction_i_64 %[[VAL_7]]#0 -> %[[VAL_20:.*]] : !fir.ref<i64>, @add_reduction_f_32 %[[VAL_9]]#0 -> %[[VAL_21:.*]] : !fir.ref<f32>, @add_reduction_f_64 %[[VAL_3]]#0 -> %[[VAL_22:.*]] : !fir.ref<f64>) for (%[[VAL_23:.*]]) : i32 = (%[[VAL_16]]) to (%[[VAL_17]]) inclusive step (%[[VAL_18]]) { +! CHECK: omp.wsloop reduction(@add_reduction_i32 %[[VAL_5]]#0 -> %[[VAL_19:.*]] : !fir.ref<i32>, @add_reduction_i64 %[[VAL_7]]#0 -> %[[VAL_20:.*]] : !fir.ref<i64>, @add_reduction_f32 %[[VAL_9]]#0 -> %[[VAL_21:.*]] : !fir.ref<f32>, @add_reduction_f64 %[[VAL_3]]#0 -> %[[VAL_22:.*]] : !fir.ref<f64>) for (%[[VAL_23:.*]]) : i32 = (%[[VAL_16]]) to (%[[VAL_17]]) inclusive step (%[[VAL_18]]) { ! CHECK: fir.store %[[VAL_23]] to %[[VAL_15]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_24:.*]]:2 = hlfir.declare %[[VAL_19]] {uniq_name = "_QFmultiple_reductions_different_typeEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_25:.*]]:2 = hlfir.declare %[[VAL_20]] {uniq_name = "_QFmultiple_reductions_different_typeEy"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-array.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-array.f90 index be4d27f6ac47..a20ed1ca83ce 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-array.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-array.f90 @@ -14,7 +14,7 @@ enddo print *,r end program -! CHECK-LABEL omp.declare_reduction @add_reduction_i_32_box_2_byref : !fir.ref<!fir.box<!fir.array<2xi32>>> init { +! CHECK-LABEL omp.declare_reduction @add_reduction_byref_box_2xi32 : !fir.ref<!fir.box<!fir.array<2xi32>>> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>): ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<2xi32> {bindc_name = ".tmp"} ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 @@ -63,7 +63,7 @@ end program ! CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_5]]#1(%[[VAL_4]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>> ! CHECK: %[[VAL_12:.*]] = fir.alloca !fir.box<!fir.array<2xi32>> ! CHECK: fir.store %[[VAL_11]] to %[[VAL_12]] : !fir.ref<!fir.box<!fir.array<2xi32>>> -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_box_2_byref %[[VAL_12]] -> %[[VAL_13:.*]] : !fir.ref<!fir.box<!fir.array<2xi32>>>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_box_2xi32 %[[VAL_12]] -> %[[VAL_13:.*]] : !fir.ref<!fir.box<!fir.array<2xi32>>>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { ! CHECK: fir.store %[[VAL_14]] to %[[VAL_7]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_13]] {uniq_name = "_QFEr"} : (!fir.ref<!fir.box<!fir.array<2xi32>>>) -> (!fir.ref<!fir.box<!fir.array<2xi32>>>, !fir.ref<!fir.box<!fir.array<2xi32>>>) ! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 index c77bd72f916d..61599876da8e 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 @@ -14,7 +14,7 @@ enddo print *,r end program -! CHECK-LABEL omp.declare_reduction @add_reduction_i_32_box_2_byref : !fir.ref<!fir.box<!fir.array<2xi32>>> init { +! CHECK-LABEL omp.declare_reduction @add_reduction_byref_box_2xi32 : !fir.ref<!fir.box<!fir.array<2xi32>>> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>): ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<2xi32> {bindc_name = ".tmp"} ! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 @@ -63,7 +63,7 @@ end program ! CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_5]]#1(%[[VAL_4]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>> ! CHECK: %[[VAL_12:.*]] = fir.alloca !fir.box<!fir.array<2xi32>> ! CHECK: fir.store %[[VAL_11]] to %[[VAL_12]] : !fir.ref<!fir.box<!fir.array<2xi32>>> -! CHECK: omp.wsloop byref reduction(@add_reduction_i_32_box_2_byref %[[VAL_12]] -> %[[VAL_13:.*]] : !fir.ref<!fir.box<!fir.array<2xi32>>>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { +! CHECK: omp.wsloop byref reduction(@add_reduction_byref_box_2xi32 %[[VAL_12]] -> %[[VAL_13:.*]] : !fir.ref<!fir.box<!fir.array<2xi32>>>) for (%[[VAL_14:.*]]) : i32 = (%[[VAL_8]]) to (%[[VAL_9]]) inclusive step (%[[VAL_10]]) { ! CHECK: fir.store %[[VAL_14]] to %[[VAL_7]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_13]] {uniq_name = "_QFEr"} : (!fir.ref<!fir.box<!fir.array<2xi32>>>) -> (!fir.ref<!fir.box<!fir.array<2xi32>>>, !fir.ref<!fir.box<!fir.array<2xi32>>>) ! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_15]]#0 : !fir.ref<!fir.box<!fir.array<2xi32>>> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-iand-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-iand-byref.f90 index 2df3ad393ba5..e3f06a446ed4 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-iand-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-iand-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.declare_reduction @iand_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @iand_byref_i32 : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant -1 : i32 @@ -35,7 +35,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@iand_i_32_byref %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop byref reduction(@iand_byref_i32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_iandEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-iand.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-iand.f90 index 707be66def8d..746617e21062 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-iand.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-iand.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.declare_reduction @iand_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @iand_i32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant -1 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) @@ -29,7 +29,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@iand_i_32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop reduction(@iand_i32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_iandEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-ieor-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-ieor-byref.f90 index 72a6901878ad..7e3a283bf783 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-ieor-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-ieor-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s -! CHECK-LABEL: omp.declare_reduction @ieor_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @ieor_byref_i32 : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 @@ -28,7 +28,7 @@ !CHECK: omp.parallel !CHECK: %[[I_REF:.*]] = fir.alloca i32 {adapt.valuebyref, pinned} !CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %[[I_REF]] {uniq_name = "_QFreduction_ieorEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) -!CHECK: omp.wsloop byref reduction(@ieor_i_32_byref %[[X_DECL]]#0 -> %[[PRV:.+]] : !fir.ref<i32>) for +!CHECK: omp.wsloop byref reduction(@ieor_byref_i32 %[[X_DECL]]#0 -> %[[PRV:.+]] : !fir.ref<i32>) for !CHECK: fir.store %{{.*}} to %[[I_DECL]]#1 : !fir.ref<i32> !CHECK: %[[PRV_DECL:.+]]:2 = hlfir.declare %[[PRV]] {{.*}} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) !CHECK: %[[I_32:.*]] = fir.load %[[I_DECL]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-ior-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-ior-byref.f90 index 662e64b8fae6..c7f8e8bdede5 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-ior-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-ior-byref.f90 @@ -1,9 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp --force-byref-reduction %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --force-byref-reduction %s -o - | FileCheck %s -! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py - -! CHECK-LABEL: omp.declare_reduction @ior_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @ior_byref_i32 : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[C0_1:.*]] = arith.constant 0 : i32 @@ -35,7 +33,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@ior_i_32_byref %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) +! CHECK: omp.wsloop byref reduction(@ior_byref_i32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_iorEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-ior.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-ior.f90 index 8f6ca7c41c42..dd0bbeb1a076 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-ior.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-ior.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.declare_reduction @ior_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @ior_i32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) @@ -29,7 +29,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@ior_i_32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) +! CHECK: omp.wsloop reduction(@ior_i32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_iorEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max-2-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max-2-byref.f90 index 360cd34df2d1..5358806cdcde 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max-2-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max-2-byref.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp --force-byref-reduction -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --force-byref-reduction -o - %s 2>&1 | FileCheck %s -! CHECK: omp.wsloop byref reduction(@max_i_32 +! CHECK: omp.wsloop byref reduction(@max_byref_i32 ! CHECK: arith.cmpi sgt ! CHECK: arith.select diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max-2.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max-2.f90 index 1f4d61985689..abd7ca1ae555 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max-2.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max-2.f90 @@ -1,7 +1,7 @@ ! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s -! CHECK: omp.wsloop reduction(@max_i_32 +! CHECK: omp.wsloop reduction(@max_i32 ! CHECK: arith.cmpi sgt ! CHECK: arith.select diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 index 058eeea5fb92..ee562bbe1586 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -!CHECK: omp.declare_reduction @max_f_32_byref : !fir.ref<f32> +!CHECK: omp.declare_reduction @max_byref_f32 : !fir.ref<f32> !CHECK-SAME: init { !CHECK: %[[MINIMUM_VAL:.*]] = arith.constant -3.40282347E+38 : f32 !CHECK: %[[REF:.*]] = fir.alloca f32 @@ -17,7 +17,7 @@ !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32> !CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) -!CHECK-LABEL: omp.declare_reduction @max_i_32_byref : !fir.ref<i32> +!CHECK-LABEL: omp.declare_reduction @max_byref_i32 : !fir.ref<i32> !CHECK-SAME: init { !CHECK: %[[MINIMUM_VAL:.*]] = arith.constant -2147483648 : i32 !CHECK: %[[REF:.*]] = fir.alloca i32 @@ -46,7 +46,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@max_i_32_byref %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop byref reduction(@max_byref_i32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_max_intEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> @@ -75,7 +75,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@max_f_32_byref %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<f32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop byref reduction(@max_byref_f32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<f32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_max_realEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> @@ -94,7 +94,7 @@ ! CHECK: %[[VAL_32:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_33:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_34:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@max_f_32_byref %[[VAL_4]]#0 -> %[[VAL_35:.*]] : !fir.ref<f32>) for (%[[VAL_36:.*]]) : i32 = (%[[VAL_32]]) to (%[[VAL_33]]) inclusive step (%[[VAL_34]]) { +! CHECK: omp.wsloop byref reduction(@max_byref_f32 %[[VAL_4]]#0 -> %[[VAL_35:.*]] : !fir.ref<f32>) for (%[[VAL_36:.*]]) : i32 = (%[[VAL_32]]) to (%[[VAL_33]]) inclusive step (%[[VAL_34]]) { ! CHECK: fir.store %[[VAL_36]] to %[[VAL_31]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_37:.*]]:2 = hlfir.declare %[[VAL_35]] {uniq_name = "_QFreduction_max_realEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_31]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir-byref.f90 index 3a07450765cf..10bba6ac4b51 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.declare_reduction @max_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @max_byref_i32 : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[MINIMUM_VAL:.*]] = arith.constant -2147483648 : i32 @@ -33,7 +33,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@max_i_32_byref %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop byref reduction(@max_byref_i32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_max_intEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir.f90 index 3dfed100a02e..5ea5d6626f18 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max-hlfir.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.declare_reduction @max_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @max_i32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant -2147483648 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) @@ -29,7 +29,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@max_i_32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop reduction(@max_i32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_max_intEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 index 895eca85fd1e..6f11f0ec96a7 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.declare_reduction @max_f_32 : f32 init { +! CHECK-LABEL: omp.declare_reduction @max_f32 : f32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32): ! CHECK: %[[VAL_1:.*]] = arith.constant -3.40282347E+38 : f32 ! CHECK: omp.yield(%[[VAL_1]] : f32) @@ -14,7 +14,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @max_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @max_i32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant -2147483648 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) @@ -40,7 +40,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@max_i_32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop reduction(@max_i32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_max_intEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> @@ -69,7 +69,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@max_f_32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<f32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop reduction(@max_f32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<f32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_max_realEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> @@ -88,7 +88,7 @@ ! CHECK: %[[VAL_32:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_33:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_34:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@max_f_32 %[[VAL_4]]#0 -> %[[VAL_35:.*]] : !fir.ref<f32>) for (%[[VAL_36:.*]]) : i32 = (%[[VAL_32]]) to (%[[VAL_33]]) inclusive step (%[[VAL_34]]) { +! CHECK: omp.wsloop reduction(@max_f32 %[[VAL_4]]#0 -> %[[VAL_35:.*]] : !fir.ref<f32>) for (%[[VAL_36:.*]]) : i32 = (%[[VAL_32]]) to (%[[VAL_33]]) inclusive step (%[[VAL_34]]) { ! CHECK: fir.store %[[VAL_36]] to %[[VAL_31]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_37:.*]]:2 = hlfir.declare %[[VAL_35]] {uniq_name = "_QFreduction_max_realEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_31]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 index c44301f68b83..c0372117a03b 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -!CHECK: omp.declare_reduction @min_f_32_byref : !fir.ref<f32> +!CHECK: omp.declare_reduction @min_byref_f32 : !fir.ref<f32> !CHECK-SAME: init { !CHECK: %[[MAXIMUM_VAL:.*]] = arith.constant 3.40282347E+38 : f32 !CHECK: %[[REF:.*]] = fir.alloca f32 @@ -17,7 +17,7 @@ !CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32> !CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) -!CHECK-LABEL: omp.declare_reduction @min_i_32_byref : !fir.ref<i32> +!CHECK-LABEL: omp.declare_reduction @min_byref_i32 : !fir.ref<i32> !CHECK-SAME: init { !CHECK: %[[MAXIMUM_VAL:.*]] = arith.constant 2147483647 : i32 !CHECK: %[[REF:.*]] = fir.alloca i32 @@ -46,7 +46,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@min_i_32_byref %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop byref reduction(@min_byref_i32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_min_intEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> @@ -75,7 +75,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@min_f_32_byref %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<f32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop byref reduction(@min_byref_f32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<f32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_min_realEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> @@ -96,7 +96,7 @@ ! CHECK: %[[VAL_32:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_33:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_34:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@min_f_32_byref %[[VAL_4]]#0 -> %[[VAL_35:.*]] : !fir.ref<f32>) for (%[[VAL_36:.*]]) : i32 = (%[[VAL_32]]) to (%[[VAL_33]]) inclusive step (%[[VAL_34]]) { +! CHECK: omp.wsloop byref reduction(@min_byref_f32 %[[VAL_4]]#0 -> %[[VAL_35:.*]] : !fir.ref<f32>) for (%[[VAL_36:.*]]) : i32 = (%[[VAL_32]]) to (%[[VAL_33]]) inclusive step (%[[VAL_34]]) { ! CHECK: fir.store %[[VAL_36]] to %[[VAL_31]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_37:.*]]:2 = hlfir.declare %[[VAL_35]] {uniq_name = "_QFreduction_min_realEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_31]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 index 700ff78339c1..2c694f82e279 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-min.f90 @@ -3,7 +3,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.declare_reduction @min_f_32 : f32 init { +! CHECK-LABEL: omp.declare_reduction @min_f32 : f32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32): ! CHECK: %[[VAL_1:.*]] = arith.constant 3.40282347E+38 : f32 ! CHECK: omp.yield(%[[VAL_1]] : f32) @@ -14,7 +14,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @min_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @min_i32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 2147483647 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) @@ -40,7 +40,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@min_i_32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop reduction(@min_i32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<i32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_min_intEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> @@ -69,7 +69,7 @@ ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_10:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@min_f_32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<f32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { +! CHECK: omp.wsloop reduction(@min_f32 %[[VAL_4]]#0 -> %[[VAL_12:.*]] : !fir.ref<f32>) for (%[[VAL_13:.*]]) : i32 = (%[[VAL_9]]) to (%[[VAL_10]]) inclusive step (%[[VAL_11]]) { ! CHECK: fir.store %[[VAL_13]] to %[[VAL_8]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QFreduction_min_realEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref<i32> @@ -90,7 +90,7 @@ ! CHECK: %[[VAL_32:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_33:.*]] = arith.constant 100 : i32 ! CHECK: %[[VAL_34:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@min_f_32 %[[VAL_4]]#0 -> %[[VAL_35:.*]] : !fir.ref<f32>) for (%[[VAL_36:.*]]) : i32 = (%[[VAL_32]]) to (%[[VAL_33]]) inclusive step (%[[VAL_34]]) { +! CHECK: omp.wsloop reduction(@min_f32 %[[VAL_4]]#0 -> %[[VAL_35:.*]] : !fir.ref<f32>) for (%[[VAL_36:.*]]) : i32 = (%[[VAL_32]]) to (%[[VAL_33]]) inclusive step (%[[VAL_34]]) { ! CHECK: fir.store %[[VAL_36]] to %[[VAL_31]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_37:.*]]:2 = hlfir.declare %[[VAL_35]] {uniq_name = "_QFreduction_min_realEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_31]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-min2.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-min2.f90 index cef1102a2fcc..0138a9578206 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-min2.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-min2.f90 @@ -17,7 +17,7 @@ print *,r end program -! CHECK-LABEL: omp.declare_reduction @min_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @min_i32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 2147483647 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) @@ -39,7 +39,7 @@ end program ! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i32 ! CHECK: %[[VAL_7:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@min_i_32 %[[VAL_3]]#0 -> %[[VAL_9:.*]] : !fir.ref<i32>) for (%[[VAL_10:.*]]) : i32 = (%[[VAL_6]]) to (%[[VAL_7]]) inclusive step (%[[VAL_8]]) { +! CHECK: omp.wsloop reduction(@min_i32 %[[VAL_3]]#0 -> %[[VAL_9:.*]] : !fir.ref<i32>) for (%[[VAL_10:.*]]) : i32 = (%[[VAL_6]]) to (%[[VAL_7]]) inclusive step (%[[VAL_8]]) { ! CHECK: fir.store %[[VAL_10]] to %[[VAL_5]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_9]] {uniq_name = "_QFEr"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32> diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-mul-byref.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-mul-byref.f90 index c6aa21c4231c..a2829948d472 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-mul-byref.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-mul-byref.f90 @@ -4,7 +4,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.declare_reduction @multiply_reduction_f_64_byref : !fir.ref<f64> +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_byref_f64 : !fir.ref<f64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f64>): ! CHECK: %[[VAL_1:.*]] = arith.constant 1.000000e+00 : f64 @@ -21,7 +21,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f64>) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @multiply_reduction_i_64_byref : !fir.ref<i64> +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_byref_i64 : !fir.ref<i64> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i64>): ! CHECK: %[[VAL_1:.*]] = arith.constant 1 : i64 @@ -38,7 +38,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<i64>) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @multiply_reduction_f_32_byref : !fir.ref<f32> +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_byref_f32 : !fir.ref<f32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>): ! CHECK: %[[VAL_1:.*]] = arith.constant 1.000000e+00 : f32 @@ -55,7 +55,7 @@ ! CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @multiply_reduction_i_32_byref : !fir.ref<i32> +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_byref_i32 : !fir.ref<i32> ! CHECK-SAME: init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>): ! CHECK: %[[VAL_1:.*]] = arith.constant 1 : i32 @@ -85,7 +85,7 @@ ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@multiply_reduction_i_32_byref %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop byref reduction(@multiply_reduction_byref_i32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_int_reductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref<i32> @@ -121,7 +121,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@multiply_reduction_f_32_byref %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop byref reduction(@multiply_reduction_byref_f32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_real_reductionEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref<f32> @@ -158,7 +158,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@multiply_reduction_i_32_byref %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop byref reduction(@multiply_reduction_byref_i32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_int_reduction_switch_orderEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref<i32> @@ -194,7 +194,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@multiply_reduction_f_32_byref %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop byref reduction(@multiply_reduction_byref_f32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_real_reduction_switch_orderEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref<i32> @@ -239,7 +239,7 @@ end subroutine ! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_14:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_15:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@multiply_reduction_i_32_byref %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<i32>, @multiply_reduction_i_32_byref %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<i32>, @multiply_reduction_i_32_byref %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<i32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { +! CHECK: omp.wsloop byref reduction(@multiply_reduction_byref_i32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<i32>, @multiply_reduction_byref_i32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<i32>, @multiply_reduction_byref_i32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<i32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { ! CHECK: fir.store %[[VAL_19]] to %[[VAL_12]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_16]] {uniq_name = "_QFmultiple_int_reductions_same_typeEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_17]] {uniq_name = "_QFmultiple_int_reductions_same_typeEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) @@ -297,7 +297,7 @@ end subroutine ! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_14:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_15:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@multiply_reduction_f_32_byref %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<f32>, @multiply_reduction_f_32_byref %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<f32>, @multiply_reduction_f_32_byref %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<f32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { +! CHECK: omp.wsloop byref reduction(@multiply_reduction_byref_f32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<f32>, @multiply_reduction_byref_f32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<f32>, @multiply_reduction_byref_f32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<f32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { ! CHECK: fir.store %[[VAL_19]] to %[[VAL_12]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_16]] {uniq_name = "_QFmultiple_real_reductions_same_typeEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_17]] {uniq_name = "_QFmultiple_real_reductions_same_typeEy"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) @@ -362,7 +362,7 @@ end subroutine ! CHECK: %[[VAL_16:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_17:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_18:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop byref reduction(@multiply_reduction_i_32_byref %[[VAL_5]]#0 -> %[[VAL_19:.*]] : !fir.ref<i32>, @multiply_reduction_i_64_byref %[[VAL_7]]#0 -> %[[VAL_20:.*]] : !fir.ref<i64>, @multiply_reduction_f_32_byref %[[VAL_9]]#0 -> %[[VAL_21:.*]] : !fir.ref<f32>, @multiply_reduction_f_64_byref %[[VAL_3]]#0 -> %[[VAL_22:.*]] : !fir.ref<f64>) for (%[[VAL_23:.*]]) : i32 = (%[[VAL_16]]) to (%[[VAL_17]]) inclusive step (%[[VAL_18]]) { +! CHECK: omp.wsloop byref reduction(@multiply_reduction_byref_i32 %[[VAL_5]]#0 -> %[[VAL_19:.*]] : !fir.ref<i32>, @multiply_reduction_byref_i64 %[[VAL_7]]#0 -> %[[VAL_20:.*]] : !fir.ref<i64>, @multiply_reduction_byref_f32 %[[VAL_9]]#0 -> %[[VAL_21:.*]] : !fir.ref<f32>, @multiply_reduction_byref_f64 %[[VAL_3]]#0 -> %[[VAL_22:.*]] : !fir.ref<f64>) for (%[[VAL_23:.*]]) : i32 = (%[[VAL_16]]) to (%[[VAL_17]]) inclusive step (%[[VAL_18]]) { ! CHECK: fir.store %[[VAL_23]] to %[[VAL_15]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_24:.*]]:2 = hlfir.declare %[[VAL_19]] {uniq_name = "_QFmultiple_reductions_different_typeEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_25:.*]]:2 = hlfir.declare %[[VAL_20]] {uniq_name = "_QFmultiple_reductions_different_typeEy"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>) diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 index ce34aafe7dc5..90d9aa5e839b 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-mul.f90 @@ -4,8 +4,7 @@ ! NOTE: Assertions have been autogenerated by utils/generate-test-checks.py -! CHECK-LABEL: omp.declare_reduction @multiply_reduction_f_64 : f64 init { -! CHECK: ^bb0(%[[VAL_0:.*]]: f64): +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_f64 : f64 init { ! CHECK: %[[VAL_1:.*]] = arith.constant 1.000000e+00 : f64 ! CHECK: omp.yield(%[[VAL_1]] : f64) @@ -15,7 +14,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f64) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @multiply_reduction_i_64 : i64 init { +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_i64 : i64 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i64): ! CHECK: %[[VAL_1:.*]] = arith.constant 1 : i64 ! CHECK: omp.yield(%[[VAL_1]] : i64) @@ -26,7 +25,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : i64) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @multiply_reduction_f_32 : f32 init { +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_f32 : f32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: f32): ! CHECK: %[[VAL_1:.*]] = arith.constant 1.000000e+00 : f32 ! CHECK: omp.yield(%[[VAL_1]] : f32) @@ -37,7 +36,7 @@ ! CHECK: omp.yield(%[[VAL_2]] : f32) ! CHECK: } -! CHECK-LABEL: omp.declare_reduction @multiply_reduction_i_32 : i32 init { +! CHECK-LABEL: omp.declare_reduction @multiply_reduction_i32 : i32 init { ! CHECK: ^bb0(%[[VAL_0:.*]]: i32): ! CHECK: %[[VAL_1:.*]] = arith.constant 1 : i32 ! CHECK: omp.yield(%[[VAL_1]] : i32) @@ -61,7 +60,7 @@ ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@multiply_reduction_i_32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop reduction(@multiply_reduction_i32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_int_reductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref<i32> @@ -97,7 +96,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@multiply_reduction_f_32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop reduction(@multiply_reduction_f32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_real_reductionEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref<f32> @@ -134,7 +133,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@multiply_reduction_i_32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop reduction(@multiply_reduction_i32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<i32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_int_reduction_switch_orderEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref<i32> @@ -170,7 +169,7 @@ end subroutine ! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_8:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@multiply_reduction_f_32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { +! CHECK: omp.wsloop reduction(@multiply_reduction_f32 %[[VAL_3]]#0 -> %[[VAL_10:.*]] : !fir.ref<f32>) for (%[[VAL_11:.*]]) : i32 = (%[[VAL_7]]) to (%[[VAL_8]]) inclusive step (%[[VAL_9]]) { ! CHECK: fir.store %[[VAL_11]] to %[[VAL_6]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QFsimple_real_reduction_switch_orderEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref<i32> @@ -215,7 +214,7 @@ end subroutine ! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_14:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_15:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@multiply_reduction_i_32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<i32>, @multiply_reduction_i_32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<i32>, @multiply_reduction_i_32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<i32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { +! CHECK: omp.wsloop reduction(@multiply_reduction_i32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<i32>, @multiply_reduction_i32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<i32>, @multiply_reduction_i32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<i32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { ! CHECK: fir.store %[[VAL_19]] to %[[VAL_12]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_16]] {uniq_name = "_QFmultiple_int_reductions_same_typeEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_17]] {uniq_name = "_QFmultiple_int_reductions_same_typeEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) @@ -273,7 +272,7 @@ end subroutine ! CHECK: %[[VAL_13:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_14:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_15:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@multiply_reduction_f_32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<f32>, @multiply_reduction_f_32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<f32>, @multiply_reduction_f_32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<f32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { +! CHECK: omp.wsloop reduction(@multiply_reduction_f32 %[[VAL_3]]#0 -> %[[VAL_16:.*]] : !fir.ref<f32>, @multiply_reduction_f32 %[[VAL_5]]#0 -> %[[VAL_17:.*]] : !fir.ref<f32>, @multiply_reduction_f32 %[[VAL_7]]#0 -> %[[VAL_18:.*]] : !fir.ref<f32>) for (%[[VAL_19:.*]]) : i32 = (%[[VAL_13]]) to (%[[VAL_14]]) inclusive step (%[[VAL_15]]) { ! CHECK: fir.store %[[VAL_19]] to %[[VAL_12]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_16]] {uniq_name = "_QFmultiple_real_reductions_same_typeEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) ! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_17]] {uniq_name = "_QFmultiple_real_reductions_same_typeEy"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) @@ -338,7 +337,7 @@ end subroutine ! CHECK: %[[VAL_16:.*]] = arith.constant 1 : i32 ! CHECK: %[[VAL_17:.*]] = arith.constant 10 : i32 ! CHECK: %[[VAL_18:.*]] = arith.constant 1 : i32 -! CHECK: omp.wsloop reduction(@multiply_reduction_i_32 %[[VAL_5]]#0 -> %[[VAL_19:.*]] : !fir.ref<i32>, @multiply_reduction_i_64 %[[VAL_7]]#0 -> %[[VAL_20:.*]] : !fir.ref<i64>, @multiply_reduction_f_32 %[[VAL_9]]#0 -> %[[VAL_21:.*]] : !fir.ref<f32>, @multiply_reduction_f_64 %[[VAL_3]]#0 -> %[[VAL_22:.*]] : !fir.ref<f64>) for (%[[VAL_23:.*]]) : i32 = (%[[VAL_16]]) to (%[[VAL_17]]) inclusive step (%[[VAL_18]]) { +! CHECK: omp.wsloop reduction(@multiply_reduction_i32 %[[VAL_5]]#0 -> %[[VAL_19:.*]] : !fir.ref<i32>, @multiply_reduction_i64 %[[VAL_7]]#0 -> %[[VAL_20:.*]] : !fir.ref<i64>, @multiply_reduction_f32 %[[VAL_9]]#0 -> %[[VAL_21:.*]] : !fir.ref<f32>, @multiply_reduction_f64 %[[VAL_3]]#0 -> %[[VAL_22:.*]] : !fir.ref<f64>) for (%[[VAL_23:.*]]) : i32 = (%[[VAL_16]]) to (%[[VAL_17]]) inclusive step (%[[VAL_18]]) { ! CHECK: fir.store %[[VAL_23]] to %[[VAL_15]]#1 : !fir.ref<i32> ! CHECK: %[[VAL_24:.*]]:2 = hlfir.declare %[[VAL_19]] {uniq_name = "_QFmultiple_reductions_different_typeEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) ! CHECK: %[[VAL_25:.*]]:2 = hlfir.declare %[[VAL_20]] {uniq_name = "_QFmultiple_reductions_different_typeEy"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>) -- GitLab From 9ebd329ad87ca4cde3ce62e1bf5612c4fc0fcb7f Mon Sep 17 00:00:00 2001 From: Jonas Paulsson <paulson1@linux.ibm.com> Date: Wed, 20 Mar 2024 11:46:19 -0400 Subject: [PATCH 268/307] Revert "Move assertion for AdjustsStack from PEI to MachineVerifier. (#85698)" This reverts commit 05bde30585710a51592eee0a6cf6df8184d09c92. Reverting due to verifier complaints with expensive checks on build-bot. --- llvm/lib/CodeGen/MachineVerifier.cpp | 6 ----- llvm/lib/CodeGen/PrologEpilogInserter.cpp | 2 ++ .../clear-dead-implicit-def-impdef.mir | 2 -- ...plicit-def-remat-requires-impdef-check.mir | 2 -- ...implicit-def-with-impdef-greedy-assert.mir | 2 -- .../CodeGen/AMDGPU/fold-restore-undef-use.mir | 2 -- .../greedy-alloc-fail-sgpr1024-spill.mir | 1 - .../ran-out-of-sgprs-allocation-failure.mir | 1 - .../CodeGen/AMDGPU/sched-crash-dbg-value.mir | 2 -- .../AMDGPU/sgpr-spill-wrong-stack-id.mir | 1 - .../AMDGPU/snippet-copy-bundle-regression.mir | 1 - .../virtregrewrite-undef-identity-copy.mir | 1 - ...no-register-coalescing-in-returnsTwice.mir | 2 -- .../CodeGen/Hexagon/regalloc-bad-undef.mir | 2 +- .../SystemZ/RAbasic-invalid-LR-update.mir | 2 -- .../SystemZ/clear-liverange-spillreg.mir | 1 - llvm/test/CodeGen/SystemZ/int-cmp-56.mir | 4 --- .../SystemZ/regcoal-subranges-update.mir | 2 -- llvm/test/CodeGen/X86/callbr-asm-kill.mir | 1 - llvm/test/CodeGen/X86/regalloc-copy-hints.mir | 1 - .../CodeGen/X86/statepoint-fastregalloc.mir | 4 --- .../X86/statepoint-invoke-ra-enter-at-end.mir | 2 +- .../X86/statepoint-invoke-ra-hoist-copies.mir | 2 +- .../statepoint-invoke-ra-inline-spiller.mir | 2 +- ...tatepoint-invoke-ra-remove-back-copies.mir | 2 +- .../test/CodeGen/X86/statepoint-invoke-ra.mir | 2 +- .../CodeGen/X86/statepoint-vreg-folding.mir | 2 +- .../DebugInfo/MIR/InstrRef/phi-coalescing.mir | 1 - .../Mips/livedebugvars-stop-trimming-loc.mir | 2 -- .../MachineVerifier/test_adjustsstack.mir | 26 ------------------- 30 files changed, 9 insertions(+), 74 deletions(-) delete mode 100644 llvm/test/MachineVerifier/test_adjustsstack.mir diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index 005efe48ac0c..c69d36fc7fdd 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -3697,9 +3697,6 @@ void MachineVerifier::verifyStackFrame() { if (I.getOpcode() == FrameSetupOpcode) { if (BBState.ExitIsSetup) report("FrameSetup is after another FrameSetup", &I); - if (!MRI->isSSA() && !MF->getFrameInfo().adjustsStack()) - report("AdjustsStack not set in presence of a frame pseudo " - "instruction.", &I); BBState.ExitValue -= TII->getFrameTotalSize(I); BBState.ExitIsSetup = true; } @@ -3715,9 +3712,6 @@ void MachineVerifier::verifyStackFrame() { errs() << "FrameDestroy <" << Size << "> is after FrameSetup <" << AbsSPAdj << ">.\n"; } - if (!MRI->isSSA() && !MF->getFrameInfo().adjustsStack()) - report("AdjustsStack not set in presence of a frame pseudo " - "instruction.", &I); BBState.ExitValue += Size; BBState.ExitIsSetup = false; } diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index c942b8a3e268..eaf96ec5cbde 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -372,6 +372,8 @@ void PEI::calculateCallFrameInfo(MachineFunction &MF) { MFI.computeMaxCallFrameSize(MF, &FrameSDOps); assert(MFI.getMaxCallFrameSize() <= MaxCFSIn && "Recomputing MaxCFS gave a larger value."); + assert((FrameSDOps.empty() || MF.getFrameInfo().adjustsStack()) && + "AdjustsStack not set in presence of a frame pseudo instruction."); if (TFI->canSimplifyCallFramePseudos(MF)) { // If call frames are not being included as part of the stack frame, and diff --git a/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir b/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir index 2532c76b1336..9040937d027d 100644 --- a/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir +++ b/llvm/test/CodeGen/AArch64/clear-dead-implicit-def-impdef.mir @@ -2,8 +2,6 @@ # RUN: llc -mtriple=arm64-apple-macosx -mcpu=apple-m1 -verify-regalloc -run-pass=greedy -o - %s | FileCheck %s --- name: func -frameInfo: - adjustsStack: true tracksRegLiveness: true body: | bb.0: diff --git a/llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir b/llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir index 47aa34e3c011..aa94a03786f5 100644 --- a/llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir +++ b/llvm/test/CodeGen/AArch64/implicit-def-remat-requires-impdef-check.mir @@ -22,7 +22,6 @@ name: inst_stores_to_dead_spill_implicit_def_impdef tracksRegLiveness: true frameInfo: - adjustsStack: true hasCalls: true body: | bb.0: @@ -60,7 +59,6 @@ body: | name: inst_stores_to_dead_spill_movimm_impdef tracksRegLiveness: true frameInfo: - adjustsStack: true hasCalls: true body: | bb.0: diff --git a/llvm/test/CodeGen/AArch64/implicit-def-with-impdef-greedy-assert.mir b/llvm/test/CodeGen/AArch64/implicit-def-with-impdef-greedy-assert.mir index d55cf71cead6..e5395b20afd4 100644 --- a/llvm/test/CodeGen/AArch64/implicit-def-with-impdef-greedy-assert.mir +++ b/llvm/test/CodeGen/AArch64/implicit-def-with-impdef-greedy-assert.mir @@ -3,8 +3,6 @@ --- name: widget -frameInfo: - adjustsStack: true tracksRegLiveness: true jumpTable: kind: label-difference32 diff --git a/llvm/test/CodeGen/AMDGPU/fold-restore-undef-use.mir b/llvm/test/CodeGen/AMDGPU/fold-restore-undef-use.mir index 054eeec9e33f..3616d617f84a 100644 --- a/llvm/test/CodeGen/AMDGPU/fold-restore-undef-use.mir +++ b/llvm/test/CodeGen/AMDGPU/fold-restore-undef-use.mir @@ -7,8 +7,6 @@ --- name: restore_undef_copy_use -frameInfo: - adjustsStack: true tracksRegLiveness: true machineFunctionInfo: maxKernArgAlign: 1 diff --git a/llvm/test/CodeGen/AMDGPU/greedy-alloc-fail-sgpr1024-spill.mir b/llvm/test/CodeGen/AMDGPU/greedy-alloc-fail-sgpr1024-spill.mir index dde84af57ed2..bdd89a907790 100644 --- a/llvm/test/CodeGen/AMDGPU/greedy-alloc-fail-sgpr1024-spill.mir +++ b/llvm/test/CodeGen/AMDGPU/greedy-alloc-fail-sgpr1024-spill.mir @@ -13,7 +13,6 @@ name: greedy_fail_alloc_sgpr1024_spill tracksRegLiveness: true frameInfo: - adjustsStack: true hasCalls: true machineFunctionInfo: explicitKernArgSize: 16 diff --git a/llvm/test/CodeGen/AMDGPU/ran-out-of-sgprs-allocation-failure.mir b/llvm/test/CodeGen/AMDGPU/ran-out-of-sgprs-allocation-failure.mir index fdfc9b043cc9..2ccc24152a9f 100644 --- a/llvm/test/CodeGen/AMDGPU/ran-out-of-sgprs-allocation-failure.mir +++ b/llvm/test/CodeGen/AMDGPU/ran-out-of-sgprs-allocation-failure.mir @@ -24,7 +24,6 @@ registers: - { id: 10, class: sreg_64_xexec, preferred-register: '$vcc' } frameInfo: maxAlignment: 1 - adjustsStack: true hasCalls: true machineFunctionInfo: maxKernArgAlign: 1 diff --git a/llvm/test/CodeGen/AMDGPU/sched-crash-dbg-value.mir b/llvm/test/CodeGen/AMDGPU/sched-crash-dbg-value.mir index 158874e7c827..c0d199920bd9 100644 --- a/llvm/test/CodeGen/AMDGPU/sched-crash-dbg-value.mir +++ b/llvm/test/CodeGen/AMDGPU/sched-crash-dbg-value.mir @@ -180,8 +180,6 @@ exposesReturnsTwice: false legalized: false regBankSelected: false selected: false -frameInfo: - adjustsStack: true tracksRegLiveness: true liveins: - { reg: '$vgpr0', virtual-reg: '%0' } diff --git a/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir b/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir index c6ccbd99bf89..efbdbca9da6b 100644 --- a/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir +++ b/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir @@ -78,7 +78,6 @@ name: sgpr_spill_wrong_stack_id tracksRegLiveness: true frameInfo: - adjustsStack: true hasCalls: true machineFunctionInfo: scratchRSrcReg: $sgpr0_sgpr1_sgpr2_sgpr3 diff --git a/llvm/test/CodeGen/AMDGPU/snippet-copy-bundle-regression.mir b/llvm/test/CodeGen/AMDGPU/snippet-copy-bundle-regression.mir index f8ec6bb5d943..355829825146 100644 --- a/llvm/test/CodeGen/AMDGPU/snippet-copy-bundle-regression.mir +++ b/llvm/test/CodeGen/AMDGPU/snippet-copy-bundle-regression.mir @@ -21,7 +21,6 @@ name: kernel tracksRegLiveness: true frameInfo: - adjustsStack: true hasCalls: true machineFunctionInfo: isEntryFunction: true diff --git a/llvm/test/CodeGen/AMDGPU/virtregrewrite-undef-identity-copy.mir b/llvm/test/CodeGen/AMDGPU/virtregrewrite-undef-identity-copy.mir index 6659e9532376..3d9db687ffa1 100644 --- a/llvm/test/CodeGen/AMDGPU/virtregrewrite-undef-identity-copy.mir +++ b/llvm/test/CodeGen/AMDGPU/virtregrewrite-undef-identity-copy.mir @@ -20,7 +20,6 @@ name: undef_identity_copy tracksRegLiveness: true frameInfo: maxAlignment: 4 - adjustsStack: true hasCalls: true machineFunctionInfo: isEntryFunction: true diff --git a/llvm/test/CodeGen/ARM/no-register-coalescing-in-returnsTwice.mir b/llvm/test/CodeGen/ARM/no-register-coalescing-in-returnsTwice.mir index b4bbb9be8ae4..5c59566247d8 100644 --- a/llvm/test/CodeGen/ARM/no-register-coalescing-in-returnsTwice.mir +++ b/llvm/test/CodeGen/ARM/no-register-coalescing-in-returnsTwice.mir @@ -86,8 +86,6 @@ --- name: main exposesReturnsTwice: true -frameInfo: - adjustsStack: true stack: - { id: 0, name: P0, size: 80, alignment: 8, local-offset: -80 } - { id: 1, name: jb1, size: 160, alignment: 8, local-offset: -240 } diff --git a/llvm/test/CodeGen/Hexagon/regalloc-bad-undef.mir b/llvm/test/CodeGen/Hexagon/regalloc-bad-undef.mir index 9468b18bf8e4..67f4dd72ea0b 100644 --- a/llvm/test/CodeGen/Hexagon/regalloc-bad-undef.mir +++ b/llvm/test/CodeGen/Hexagon/regalloc-bad-undef.mir @@ -135,7 +135,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 - adjustsStack: true + adjustsStack: false hasCalls: true maxCallFrameSize: 0 hasOpaqueSPAdjustment: false diff --git a/llvm/test/CodeGen/SystemZ/RAbasic-invalid-LR-update.mir b/llvm/test/CodeGen/SystemZ/RAbasic-invalid-LR-update.mir index fbe2b687e850..3b308ce3d0d2 100644 --- a/llvm/test/CodeGen/SystemZ/RAbasic-invalid-LR-update.mir +++ b/llvm/test/CodeGen/SystemZ/RAbasic-invalid-LR-update.mir @@ -24,8 +24,6 @@ --- name: autogen_SD21418 alignment: 4 -frameInfo: - adjustsStack: true tracksRegLiveness: true registers: - { id: 0, class: vr128bit } diff --git a/llvm/test/CodeGen/SystemZ/clear-liverange-spillreg.mir b/llvm/test/CodeGen/SystemZ/clear-liverange-spillreg.mir index 197c3d8551fc..7ff7d9b8b709 100644 --- a/llvm/test/CodeGen/SystemZ/clear-liverange-spillreg.mir +++ b/llvm/test/CodeGen/SystemZ/clear-liverange-spillreg.mir @@ -157,7 +157,6 @@ registers: - { id: 129, class: grx32bit } - { id: 130, class: fp64bit } frameInfo: - adjustsStack: true hasCalls: true body: | bb.0: diff --git a/llvm/test/CodeGen/SystemZ/int-cmp-56.mir b/llvm/test/CodeGen/SystemZ/int-cmp-56.mir index 3e00b6065eb9..e52fd44ae47d 100644 --- a/llvm/test/CodeGen/SystemZ/int-cmp-56.mir +++ b/llvm/test/CodeGen/SystemZ/int-cmp-56.mir @@ -48,7 +48,6 @@ liveins: - { reg: '$r2d', virtual-reg: '%0' } frameInfo: maxAlignment: 1 - adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | @@ -126,7 +125,6 @@ liveins: - { reg: '$r2d', virtual-reg: '%0' } frameInfo: maxAlignment: 1 - adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | @@ -204,7 +202,6 @@ liveins: - { reg: '$r2d', virtual-reg: '%0' } frameInfo: maxAlignment: 1 - adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | @@ -282,7 +279,6 @@ liveins: - { reg: '$r2d', virtual-reg: '%0' } frameInfo: maxAlignment: 1 - adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | diff --git a/llvm/test/CodeGen/SystemZ/regcoal-subranges-update.mir b/llvm/test/CodeGen/SystemZ/regcoal-subranges-update.mir index d3ef9b0b9abf..f709b70ff1b7 100644 --- a/llvm/test/CodeGen/SystemZ/regcoal-subranges-update.mir +++ b/llvm/test/CodeGen/SystemZ/regcoal-subranges-update.mir @@ -48,8 +48,6 @@ body: | # represented for the value carried by %7. --- name: segfault -frameInfo: - adjustsStack: true tracksRegLiveness: true liveins: [] body: | diff --git a/llvm/test/CodeGen/X86/callbr-asm-kill.mir b/llvm/test/CodeGen/X86/callbr-asm-kill.mir index 0dded37c97af..86c58c4715ed 100644 --- a/llvm/test/CodeGen/X86/callbr-asm-kill.mir +++ b/llvm/test/CodeGen/X86/callbr-asm-kill.mir @@ -45,7 +45,6 @@ liveins: - { reg: '$rsi', virtual-reg: '%3' } frameInfo: maxAlignment: 1 - adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | diff --git a/llvm/test/CodeGen/X86/regalloc-copy-hints.mir b/llvm/test/CodeGen/X86/regalloc-copy-hints.mir index d09bcd6a6b40..13b5a541fa22 100644 --- a/llvm/test/CodeGen/X86/regalloc-copy-hints.mir +++ b/llvm/test/CodeGen/X86/regalloc-copy-hints.mir @@ -103,7 +103,6 @@ registers: - { id: 82, class: gr32 } frameInfo: maxAlignment: 4 - adjustsStack: true hasCalls: true fixedStack: - { id: 0, size: 4, alignment: 4, stack-id: default, isImmutable: true } diff --git a/llvm/test/CodeGen/X86/statepoint-fastregalloc.mir b/llvm/test/CodeGen/X86/statepoint-fastregalloc.mir index 87ffdd7c4e6b..02c931067300 100644 --- a/llvm/test/CodeGen/X86/statepoint-fastregalloc.mir +++ b/llvm/test/CodeGen/X86/statepoint-fastregalloc.mir @@ -5,8 +5,6 @@ # Tied def/use must be assigned to the same register. --- name: test_relocate -frameInfo: - adjustsStack: true tracksRegLiveness: true body: | bb.0.entry: @@ -26,8 +24,6 @@ body: | # These regmasks have no real meaning and chosen to allow only single register to be assignable ($rbp) --- name: test_relocate_multi_regmasks -frameInfo: - adjustsStack: true tracksRegLiveness: true body: | bb.0.entry: diff --git a/llvm/test/CodeGen/X86/statepoint-invoke-ra-enter-at-end.mir b/llvm/test/CodeGen/X86/statepoint-invoke-ra-enter-at-end.mir index 5f05270729fd..11968f17c70a 100644 --- a/llvm/test/CodeGen/X86/statepoint-invoke-ra-enter-at-end.mir +++ b/llvm/test/CodeGen/X86/statepoint-invoke-ra-enter-at-end.mir @@ -231,7 +231,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 1 - adjustsStack: true + adjustsStack: false hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/CodeGen/X86/statepoint-invoke-ra-hoist-copies.mir b/llvm/test/CodeGen/X86/statepoint-invoke-ra-hoist-copies.mir index cf9128260f19..aae2f3870138 100644 --- a/llvm/test/CodeGen/X86/statepoint-invoke-ra-hoist-copies.mir +++ b/llvm/test/CodeGen/X86/statepoint-invoke-ra-hoist-copies.mir @@ -398,7 +398,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 1 - adjustsStack: true + adjustsStack: false hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/CodeGen/X86/statepoint-invoke-ra-inline-spiller.mir b/llvm/test/CodeGen/X86/statepoint-invoke-ra-inline-spiller.mir index fcebc69d9b2e..87f5f0f96c50 100644 --- a/llvm/test/CodeGen/X86/statepoint-invoke-ra-inline-spiller.mir +++ b/llvm/test/CodeGen/X86/statepoint-invoke-ra-inline-spiller.mir @@ -175,7 +175,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 4 - adjustsStack: true + adjustsStack: false hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/CodeGen/X86/statepoint-invoke-ra-remove-back-copies.mir b/llvm/test/CodeGen/X86/statepoint-invoke-ra-remove-back-copies.mir index 8bb39a03f7e3..49253968fcca 100644 --- a/llvm/test/CodeGen/X86/statepoint-invoke-ra-remove-back-copies.mir +++ b/llvm/test/CodeGen/X86/statepoint-invoke-ra-remove-back-copies.mir @@ -226,7 +226,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 4 - adjustsStack: true + adjustsStack: false hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/CodeGen/X86/statepoint-invoke-ra.mir b/llvm/test/CodeGen/X86/statepoint-invoke-ra.mir index da651039ce21..858ff3f1888b 100644 --- a/llvm/test/CodeGen/X86/statepoint-invoke-ra.mir +++ b/llvm/test/CodeGen/X86/statepoint-invoke-ra.mir @@ -172,7 +172,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 4 - adjustsStack: true + adjustsStack: false hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/CodeGen/X86/statepoint-vreg-folding.mir b/llvm/test/CodeGen/X86/statepoint-vreg-folding.mir index d40a9a06d162..e24d5e8af1f5 100644 --- a/llvm/test/CodeGen/X86/statepoint-vreg-folding.mir +++ b/llvm/test/CodeGen/X86/statepoint-vreg-folding.mir @@ -114,7 +114,7 @@ frameInfo: stackSize: 0 offsetAdjustment: 0 maxAlignment: 8 - adjustsStack: true + adjustsStack: false hasCalls: true stackProtector: '' maxCallFrameSize: 4294967295 diff --git a/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir b/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir index 6460263c6025..bc1c7ebac6ce 100644 --- a/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir +++ b/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir @@ -106,7 +106,6 @@ liveins: - { reg: '$rsi', virtual-reg: '%5' } frameInfo: maxAlignment: 1 - adjustsStack: true hasCalls: true machineFunctionInfo: {} body: | diff --git a/llvm/test/DebugInfo/MIR/Mips/livedebugvars-stop-trimming-loc.mir b/llvm/test/DebugInfo/MIR/Mips/livedebugvars-stop-trimming-loc.mir index ac67b9671f53..35ab906efc90 100644 --- a/llvm/test/DebugInfo/MIR/Mips/livedebugvars-stop-trimming-loc.mir +++ b/llvm/test/DebugInfo/MIR/Mips/livedebugvars-stop-trimming-loc.mir @@ -71,8 +71,6 @@ --- name: fn2 alignment: 4 -frameInfo: - adjustsStack: true tracksRegLiveness: true registers: - { id: 0, class: gpr32, preferred-register: '' } diff --git a/llvm/test/MachineVerifier/test_adjustsstack.mir b/llvm/test/MachineVerifier/test_adjustsstack.mir deleted file mode 100644 index d333737e000c..000000000000 --- a/llvm/test/MachineVerifier/test_adjustsstack.mir +++ /dev/null @@ -1,26 +0,0 @@ -# RUN: not --crash llc -o - -start-before=twoaddressinstruction -verify-machineinstrs %s 2>&1 \ -# RUN: | FileCheck %s -# REQUIRES: aarch64-registered-target ---- | - target triple = "aarch64-unknown-linux" - declare i32 @bar(i32) nounwind - define i32 @foo() nounwind { - call i32 @bar(i32 0) - ret i32 0 - } -... ---- -name: foo -registers: - - { id: 0, class: gpr32 } -body: | - bb.0 (%ir-block.0): - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - %0 = COPY $wzr - $w0 = COPY %0 - BL @bar, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $w0, implicit-def $sp, implicit-def $w0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - $w0 = COPY killed %0 - RET_ReallyLR implicit $w0 -... -# CHECK-LABEL: Bad machine code: AdjustsStack not set in presence of a frame pseudo instruction. -- GitLab From d209d1340b99d4fbd325dffb5e13b757ab8264ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st> Date: Wed, 20 Mar 2024 17:48:48 +0200 Subject: [PATCH 269/307] [libcxx] [cmake] Fix cmake_path(ABSOLUTE_PATH) for empty CMAKE_INSTALL_PREFIX This should hopefully fix the issue brought up at https://github.com/llvm/llvm-project/pull/85756#issuecomment-2009852291. --- libcxx/modules/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/modules/CMakeLists.txt b/libcxx/modules/CMakeLists.txt index 8dd1b51aac2f..6c917200d6f3 100644 --- a/libcxx/modules/CMakeLists.txt +++ b/libcxx/modules/CMakeLists.txt @@ -207,10 +207,10 @@ add_custom_target(generate-cxx-modules # Use the relative path between the installation and the module in the json # file. This allows moving the entire installation to a different location. cmake_path(ABSOLUTE_PATH LIBCXX_INSTALL_LIBRARY_DIR - BASE_DIRECTORY ${CMAKE_INSTALL_PREFIX} + BASE_DIRECTORY "${CMAKE_INSTALL_PREFIX}" OUTPUT_VARIABLE ABS_LIBRARY_DIR) cmake_path(ABSOLUTE_PATH LIBCXX_INSTALL_MODULES_DIR - BASE_DIRECTORY ${CMAKE_INSTALL_PREFIX} + BASE_DIRECTORY "${CMAKE_INSTALL_PREFIX}" OUTPUT_VARIABLE ABS_MODULES_DIR) file(RELATIVE_PATH LIBCXX_MODULE_RELATIVE_PATH ${ABS_LIBRARY_DIR} -- GitLab From eb861acd49e4c6777e2fe09dd2004ac1f4731bba Mon Sep 17 00:00:00 2001 From: Steven Varoumas <steven.varoumas@huawei.com> Date: Wed, 20 Mar 2024 15:56:22 +0000 Subject: [PATCH 270/307] [mlir][python] Enable python bindings for Index dialect (#85827) This small patch enables python bindings for the index dialect. --------- Co-authored-by: Steven Varoumas <steven.varoumas1@huawei.com> --- mlir/python/CMakeLists.txt | 9 + mlir/python/mlir/dialects/IndexOps.td | 14 ++ mlir/python/mlir/dialects/index.py | 6 + mlir/test/python/dialects/index_dialect.py | 235 +++++++++++++++++++++ 4 files changed, 264 insertions(+) create mode 100644 mlir/python/mlir/dialects/IndexOps.td create mode 100644 mlir/python/mlir/dialects/index.py create mode 100644 mlir/test/python/dialects/index_dialect.py diff --git a/mlir/python/CMakeLists.txt b/mlir/python/CMakeLists.txt index 563d035f1552..c27ee688a040 100644 --- a/mlir/python/CMakeLists.txt +++ b/mlir/python/CMakeLists.txt @@ -108,6 +108,15 @@ declare_mlir_dialect_python_bindings( dialects/complex.py DIALECT_NAME complex) +declare_mlir_dialect_python_bindings( + ADD_TO_PARENT MLIRPythonSources.Dialects + ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir" + TD_FILE dialects/IndexOps.td + SOURCES + dialects/index.py + DIALECT_NAME index + GEN_ENUM_BINDINGS) + declare_mlir_dialect_python_bindings( ADD_TO_PARENT MLIRPythonSources.Dialects ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir" diff --git a/mlir/python/mlir/dialects/IndexOps.td b/mlir/python/mlir/dialects/IndexOps.td new file mode 100644 index 000000000000..13b1d782c853 --- /dev/null +++ b/mlir/python/mlir/dialects/IndexOps.td @@ -0,0 +1,14 @@ +//===-- IndexOps.td - Entry point for Index bindings -----*- tablegen -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef PYTHON_BINDINGS_INDEX_OPS +#define PYTHON_BINDINGS_INDEX_OPS + +include "mlir/Dialect/Index/IR/IndexOps.td" + +#endif diff --git a/mlir/python/mlir/dialects/index.py b/mlir/python/mlir/dialects/index.py new file mode 100644 index 000000000000..73708c7d71a8 --- /dev/null +++ b/mlir/python/mlir/dialects/index.py @@ -0,0 +1,6 @@ +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +from ._index_ops_gen import * +from ._index_enum_gen import * diff --git a/mlir/test/python/dialects/index_dialect.py b/mlir/test/python/dialects/index_dialect.py new file mode 100644 index 000000000000..9db883469792 --- /dev/null +++ b/mlir/test/python/dialects/index_dialect.py @@ -0,0 +1,235 @@ +# RUN: %PYTHON %s | FileCheck %s + +from mlir.ir import * +from mlir.dialects import index, arith + + +def run(f): + print("\nTEST:", f.__name__) + with Context() as ctx, Location.unknown(): + module = Module.create() + with InsertionPoint(module.body): + f(ctx) + print(module) + + +# CHECK-LABEL: TEST: testConstantOp +@run +def testConstantOp(ctx): + a = index.ConstantOp(value=42) + # CHECK: %{{.*}} = index.constant 42 + + +# CHECK-LABEL: TEST: testBoolConstantOp +@run +def testBoolConstantOp(ctx): + a = index.BoolConstantOp(value=True) + # CHECK: %{{.*}} = index.bool.constant true + + +# CHECK-LABEL: TEST: testAndOp +@run +def testAndOp(ctx): + a = index.ConstantOp(value=42) + r = index.AndOp(a, a) + # CHECK: %{{.*}} = index.and %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testOrOp +@run +def testOrOp(ctx): + a = index.ConstantOp(value=42) + r = index.OrOp(a, a) + # CHECK: %{{.*}} = index.or %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testXOrOp +@run +def testXOrOp(ctx): + a = index.ConstantOp(value=42) + r = index.XOrOp(a, a) + # CHECK: %{{.*}} = index.xor %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testCastSOp +@run +def testCastSOp(ctx): + a = index.ConstantOp(value=42) + b = arith.ConstantOp(value=23, result=IntegerType.get_signless(64)) + c = index.CastSOp(input=a, output=IntegerType.get_signless(32)) + d = index.CastSOp(input=b, output=IndexType.get()) + # CHECK: %{{.*}} = index.casts %{{.*}} : index to i32 + # CHECK: %{{.*}} = index.casts %{{.*}} : i64 to index + + +# CHECK-LABEL: TEST: testCastUOp +@run +def testCastUOp(ctx): + a = index.ConstantOp(value=42) + b = arith.ConstantOp(value=23, result=IntegerType.get_signless(64)) + c = index.CastUOp(input=a, output=IntegerType.get_signless(32)) + d = index.CastUOp(input=b, output=IndexType.get()) + # CHECK: %{{.*}} = index.castu %{{.*}} : index to i32 + # CHECK: %{{.*}} = index.castu %{{.*}} : i64 to index + + +# CHECK-LABEL: TEST: testCeilDivSOp +@run +def testCeilDivSOp(ctx): + a = index.ConstantOp(value=42) + r = index.CeilDivSOp(a, a) + # CHECK: %{{.*}} = index.ceildivs %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testCeilDivUOp +@run +def testCeilDivUOp(ctx): + a = index.ConstantOp(value=42) + r = index.CeilDivUOp(a, a) + # CHECK: %{{.*}} = index.ceildivu %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testCmpOp +@run +def testCmpOp(ctx): + a = index.ConstantOp(value=42) + b = index.ConstantOp(value=23) + pred = AttrBuilder.get("IndexCmpPredicateAttr")("slt", context=ctx) + r = index.CmpOp(pred, lhs=a, rhs=b) + # CHECK: %{{.*}} = index.cmp slt(%{{.*}}, %{{.*}}) + + +# CHECK-LABEL: TEST: testAddOp +@run +def testAddOp(ctx): + a = index.ConstantOp(value=42) + r = index.AddOp(a, a) + # CHECK: %{{.*}} = index.add %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testSubOp +@run +def testSubOp(ctx): + a = index.ConstantOp(value=42) + r = index.SubOp(a, a) + # CHECK: %{{.*}} = index.sub %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testMulOp +@run +def testMulOp(ctx): + a = index.ConstantOp(value=42) + r = index.MulOp(a, a) + # CHECK: %{{.*}} = index.mul %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testDivSOp +@run +def testDivSOp(ctx): + a = index.ConstantOp(value=42) + r = index.DivSOp(a, a) + # CHECK: %{{.*}} = index.divs %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testDivUOp +@run +def testDivUOp(ctx): + a = index.ConstantOp(value=42) + r = index.DivUOp(a, a) + # CHECK: %{{.*}} = index.divu %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testFloorDivSOp +@run +def testFloorDivSOp(ctx): + a = index.ConstantOp(value=42) + r = index.FloorDivSOp(a, a) + # CHECK: %{{.*}} = index.floordivs %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testMaxSOp +@run +def testMaxSOp(ctx): + a = index.ConstantOp(value=42) + b = index.ConstantOp(value=23) + r = index.MaxSOp(a, b) + # CHECK: %{{.*}} = index.maxs %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testMaxUOp +@run +def testMaxUOp(ctx): + a = index.ConstantOp(value=42) + b = index.ConstantOp(value=23) + r = index.MaxUOp(a, b) + # CHECK: %{{.*}} = index.maxu %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testMinSOp +@run +def testMinSOp(ctx): + a = index.ConstantOp(value=42) + b = index.ConstantOp(value=23) + r = index.MinSOp(a, b) + # CHECK: %{{.*}} = index.mins %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testMinUOp +@run +def testMinUOp(ctx): + a = index.ConstantOp(value=42) + b = index.ConstantOp(value=23) + r = index.MinUOp(a, b) + # CHECK: %{{.*}} = index.minu %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testRemSOp +@run +def testRemSOp(ctx): + a = index.ConstantOp(value=42) + b = index.ConstantOp(value=23) + r = index.RemSOp(a, b) + # CHECK: %{{.*}} = index.rems %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testRemUOp +@run +def testRemUOp(ctx): + a = index.ConstantOp(value=42) + b = index.ConstantOp(value=23) + r = index.RemUOp(a, b) + # CHECK: %{{.*}} = index.remu %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testShlOp +@run +def testShlOp(ctx): + a = index.ConstantOp(value=42) + b = index.ConstantOp(value=3) + r = index.ShlOp(a, b) + # CHECK: %{{.*}} = index.shl %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testShrSOp +@run +def testShrSOp(ctx): + a = index.ConstantOp(value=42) + b = index.ConstantOp(value=3) + r = index.ShrSOp(a, b) + # CHECK: %{{.*}} = index.shrs %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testShrUOp +@run +def testShrUOp(ctx): + a = index.ConstantOp(value=42) + b = index.ConstantOp(value=3) + r = index.ShrUOp(a, b) + # CHECK: %{{.*}} = index.shru %{{.*}}, %{{.*}} + + +# CHECK-LABEL: TEST: testSizeOfOp +@run +def testSizeOfOp(ctx): + r = index.SizeOfOp() + # CHECK: %{{.*}} = index.sizeof -- GitLab From 75dfa58ea93aa93b97534906778cb3dd24ba841a Mon Sep 17 00:00:00 2001 From: Stephen Tozer <stephen.tozer@sony.com> Date: Wed, 20 Mar 2024 16:00:10 +0000 Subject: [PATCH 271/307] [RemoveDIs][NFC] Rename DPMarker->DbgMarker (#85931) Another trivial rename patch, the last big one for now, which renamed DPMarkers to DbgMarkers. This required the field `DbgMarker` in `Instruction` to be renamed to `DebugMarker` to avoid a clash, but otherwise was a simple string substitution of `s/DPMarker/DbgMarker` and a manual renaming of `DPM` to `DM` in the few places where that acronym was used for debug markers. --- llvm/docs/RemoveDIsDebugInfo.md | 14 +-- llvm/include/llvm/IR/BasicBlock.h | 28 ++--- .../include/llvm/IR/DebugProgramInstruction.h | 71 +++++------ llvm/include/llvm/IR/Instruction.h | 11 +- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 2 +- llvm/lib/IR/AsmWriter.cpp | 23 ++-- llvm/lib/IR/BasicBlock.cpp | 113 +++++++++--------- llvm/lib/IR/DebugProgramInstruction.cpp | 69 +++++------ llvm/lib/IR/Instruction.cpp | 43 +++---- llvm/lib/IR/LLVMContextImpl.h | 8 +- llvm/lib/IR/Value.cpp | 2 +- llvm/lib/IR/Verifier.cpp | 10 +- llvm/lib/Transforms/Scalar/JumpThreading.cpp | 4 +- .../Transforms/Utils/LoopRotationUtils.cpp | 4 +- llvm/unittests/IR/BasicBlockDbgInfoTest.cpp | 77 ++++++------ llvm/unittests/IR/DebugInfoTest.cpp | 84 ++++++------- llvm/unittests/Transforms/Utils/LocalTest.cpp | 8 +- 17 files changed, 292 insertions(+), 279 deletions(-) diff --git a/llvm/docs/RemoveDIsDebugInfo.md b/llvm/docs/RemoveDIsDebugInfo.md index f8405767a579..a2f1e173d9d9 100644 --- a/llvm/docs/RemoveDIsDebugInfo.md +++ b/llvm/docs/RemoveDIsDebugInfo.md @@ -82,18 +82,18 @@ Like so: | | v - +------------+ - <-------+ DPMarker |<------- - / +------------+ \ - / \ - / \ - v ^ + +-------------+ + <-------+ DbgMarker |<------- + / +-------------+ \ + / \ + / \ + v ^ +-------------+ +-------------+ +-------------+ | DbgRecord +--->| DbgRecord +-->| DbgRecord | +-------------+ +-------------+ +-------------+ ``` -Each instruction has a pointer to a `DPMarker` (which will become optional), that contains a list of `DbgRecord` objects. No debugging records appear in the instruction list at all. `DbgRecord`s have a parent pointer to their owning `DPMarker`, and each `DPMarker` has a pointer back to it's owning instruction. +Each instruction has a pointer to a `DbgMarker` (which will become optional), that contains a list of `DbgRecord` objects. No debugging records appear in the instruction list at all. `DbgRecord`s have a parent pointer to their owning `DbgMarker`, and each `DbgMarker` has a pointer back to it's owning instruction. Not shown are the links from DbgRecord to other parts of the `Value`/`Metadata` hierachy: `DbgRecord` subclasses have tracking pointers to the DIMetadata that they use, and `DbgVariableRecord` has references to `Value`s that are stored in a `DebugValueUser` base class. This refers to a `ValueAsMetadata` object referring to `Value`s, via the `TrackingMetadata` facility. diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index 51444c7f8c9c..0eea4cdccca5 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -39,7 +39,7 @@ class Module; class PHINode; class ValueSymbolTable; class DbgVariableRecord; -class DPMarker; +class DbgMarker; /// LLVM Basic Block Representation /// @@ -72,18 +72,18 @@ private: Function *Parent; public: - /// Attach a DPMarker to the given instruction. Enables the storage of any + /// Attach a DbgMarker to the given instruction. Enables the storage of any /// debug-info at this position in the program. - DPMarker *createMarker(Instruction *I); - DPMarker *createMarker(InstListType::iterator It); + DbgMarker *createMarker(Instruction *I); + DbgMarker *createMarker(InstListType::iterator It); /// Convert variable location debugging information stored in dbg.value - /// intrinsics into DPMarkers / DbgRecords. Deletes all dbg.values in + /// intrinsics into DbgMarkers / DbgRecords. Deletes all dbg.values in /// the process and sets IsNewDbgInfoFormat = true. Only takes effect if /// the UseNewDbgInfoFormat LLVM command line option is given. void convertToNewDbgValues(); - /// Convert variable location debugging information stored in DPMarkers and + /// Convert variable location debugging information stored in DbgMarkers and /// DbgRecords into the dbg.value intrinsic representation. Sets /// IsNewDbgInfoFormat = false. void convertFromNewDbgValues(); @@ -97,12 +97,12 @@ public: /// instruction of this block. These are equivalent to dbg.value intrinsics /// that exist at the end of a basic block with no terminator (a transient /// state that occurs regularly). - void setTrailingDbgRecords(DPMarker *M); + void setTrailingDbgRecords(DbgMarker *M); /// Fetch the collection of DbgRecords that "trail" after the last instruction /// of this block, see \ref setTrailingDbgRecords. If there are none, returns /// nullptr. - DPMarker *getTrailingDbgRecords(); + DbgMarker *getTrailingDbgRecords(); /// Delete any trailing DbgRecords at the end of this block, see /// \ref setTrailingDbgRecords. @@ -110,15 +110,15 @@ public: void dumpDbgValues() const; - /// Return the DPMarker for the position given by \p It, so that DbgRecords + /// Return the DbgMarker for the position given by \p It, so that DbgRecords /// can be inserted there. This will either be nullptr if not present, a - /// DPMarker, or TrailingDbgRecords if It is end(). - DPMarker *getMarker(InstListType::iterator It); + /// DbgMarker, or TrailingDbgRecords if It is end(). + DbgMarker *getMarker(InstListType::iterator It); - /// Return the DPMarker for the position that comes after \p I. \see - /// BasicBlock::getMarker, this can be nullptr, a DPMarker, or + /// Return the DbgMarker for the position that comes after \p I. \see + /// BasicBlock::getMarker, this can be nullptr, a DbgMarker, or /// TrailingDbgRecords if there is no next instruction. - DPMarker *getNextMarker(Instruction *I); + DbgMarker *getNextMarker(Instruction *I); /// Insert a DbgRecord into a block at the position given by \p I. void insertDbgRecordAfter(DbgRecord *DR, Instruction *I); diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h index 8bd6331a9a3e..7214d7ad65da 100644 --- a/llvm/include/llvm/IR/DebugProgramInstruction.h +++ b/llvm/include/llvm/IR/DebugProgramInstruction.h @@ -16,22 +16,22 @@ // // and all information is stored in the Value / Metadata hierachy defined // elsewhere in LLVM. In the "DbgRecord" design, each instruction /may/ have a -// connection with a DPMarker, which identifies a position immediately before -// the instruction, and each DPMarker /may/ then have connections to DbgRecords +// connection with a DbgMarker, which identifies a position immediately before +// the instruction, and each DbgMarker /may/ then have connections to DbgRecords // which record the variable assignment information. To illustrate: // // %foo = add i32 1, %0 -// ; foo->DbgMarker == nullptr +// ; foo->DebugMarker == nullptr // ;; There are no variable assignments / debug records "in front" of -// ;; the instruction for %foo, therefore it has no DbgMarker. +// ;; the instruction for %foo, therefore it has no DebugMarker. // %bar = void call @ext(%foo) -// ; bar->DbgMarker = { +// ; bar->DebugMarker = { // ; StoredDbgRecords = { // ; DbgVariableRecord(metadata i32 %foo, ...) // ; } // ; } // ;; There is a debug-info record in front of the %bar instruction, -// ;; thus it points at a DPMarker object. That DPMarker contains a +// ;; thus it points at a DbgMarker object. That DbgMarker contains a // ;; DbgVariableRecord in it's ilist, storing the equivalent information // to the // ;; dbg.value above: the Value, DILocalVariable, etc. @@ -66,7 +66,7 @@ class DbgVariableIntrinsic; class DbgInfoIntrinsic; class DbgLabelInst; class DIAssignID; -class DPMarker; +class DbgMarker; class DbgVariableRecord; class raw_ostream; @@ -120,7 +120,7 @@ public: /// Base class for non-instruction debug metadata records that have positions /// within IR. Features various methods copied across from the Instruction /// class to aid ease-of-use. DbgRecords should always be linked into a -/// DPMarker's StoredDbgRecords list. The marker connects a DbgRecord back to +/// DbgMarker's StoredDbgRecords list. The marker connects a DbgRecord back to /// it's position in the BasicBlock. /// /// We need a discriminator for dyn/isa casts. In order to avoid paying for a @@ -134,7 +134,7 @@ public: class DbgRecord : public ilist_node<DbgRecord> { public: /// Marker that this DbgRecord is linked into. - DPMarker *Marker = nullptr; + DbgMarker *Marker = nullptr; /// Subclass discriminator. enum Kind : uint8_t { ValueKind, LabelKind }; @@ -166,10 +166,10 @@ public: Kind getRecordKind() const { return RecordKind; } - void setMarker(DPMarker *M) { Marker = M; } + void setMarker(DbgMarker *M) { Marker = M; } - DPMarker *getMarker() { return Marker; } - const DPMarker *getMarker() const { return Marker; } + DbgMarker *getMarker() { return Marker; } + const DbgMarker *getMarker() const { return Marker; } BasicBlock *getBlock(); const BasicBlock *getBlock() const; @@ -539,7 +539,7 @@ filterDbgVars(iterator_range<simple_ilist<DbgRecord>::iterator> R) { } /// Per-instruction record of debug-info. If an Instruction is the position of -/// some debugging information, it points at a DPMarker storing that info. Each +/// some debugging information, it points at a DbgMarker storing that info. Each /// marker points back at the instruction that owns it. Various utilities are /// provided for manipulating the DbgRecords contained within this marker. /// @@ -559,9 +559,9 @@ filterDbgVars(iterator_range<simple_ilist<DbgRecord>::iterator> R) { /// which we can improve in the future. Additionally, many improvements in the /// way that debug-info is stored can be achieved in this class, at a future /// date. -class DPMarker { +class DbgMarker { public: - DPMarker() {} + DbgMarker() {} /// Link back to the Instruction that owns this marker. Can be null during /// operations that move a marker from one instruction to another. Instruction *MarkedInstr = nullptr; @@ -585,7 +585,7 @@ public: void removeFromParent(); void eraseFromParent(); - /// Implement operator<< on DPMarker. + /// Implement operator<< on DbgMarker. void print(raw_ostream &O, bool IsForDebug = false) const; void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const; @@ -593,22 +593,23 @@ public: iterator_range<simple_ilist<DbgRecord>::iterator> getDbgRecordRange(); iterator_range<simple_ilist<DbgRecord>::const_iterator> getDbgRecordRange() const; - /// Transfer any DbgRecords from \p Src into this DPMarker. If \p InsertAtHead - /// is true, place them before existing DbgRecords, otherwise afterwards. - void absorbDebugValues(DPMarker &Src, bool InsertAtHead); - /// Transfer the DbgRecords in \p Range from \p Src into this DPMarker. If + /// Transfer any DbgRecords from \p Src into this DbgMarker. If \p + /// InsertAtHead is true, place them before existing DbgRecords, otherwise + /// afterwards. + void absorbDebugValues(DbgMarker &Src, bool InsertAtHead); + /// Transfer the DbgRecords in \p Range from \p Src into this DbgMarker. If /// \p InsertAtHead is true, place them before existing DbgRecords, otherwise // afterwards. void absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range, - DPMarker &Src, bool InsertAtHead); - /// Insert a DbgRecord into this DPMarker, at the end of the list. If + DbgMarker &Src, bool InsertAtHead); + /// Insert a DbgRecord into this DbgMarker, at the end of the list. If /// \p InsertAtHead is true, at the start. void insertDbgRecord(DbgRecord *New, bool InsertAtHead); /// Insert a DbgRecord prior to a DbgRecord contained within this marker. void insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore); /// Insert a DbgRecord after a DbgRecord contained within this marker. void insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter); - /// Clone all DPMarkers from \p From into this marker. There are numerous + /// Clone all DbgMarkers from \p From into this marker. There are numerous /// options to customise the source/destination, due to gnarliness, see class /// comment. /// \p FromHere If non-null, copy from FromHere to the end of From's @@ -617,10 +618,10 @@ public: /// StoredDbgRecords /// \returns Range over all the newly cloned DbgRecords iterator_range<simple_ilist<DbgRecord>::iterator> - cloneDebugInfoFrom(DPMarker *From, + cloneDebugInfoFrom(DbgMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> FromHere, bool InsertAtHead = false); - /// Erase all DbgRecords in this DPMarker. + /// Erase all DbgRecords in this DbgMarker. void dropDbgRecords(); /// Erase a single DbgRecord from this marker. In an ideal future, we would /// never erase an assignment in this way, but it's the equivalent to @@ -628,34 +629,34 @@ public: void dropOneDbgRecord(DbgRecord *DR); /// We generally act like all llvm Instructions have a range of DbgRecords - /// attached to them, but in reality sometimes we don't allocate the DPMarker + /// attached to them, but in reality sometimes we don't allocate the DbgMarker /// to save time and memory, but still have to return ranges of DbgRecords. /// When we need to describe such an unallocated DbgRecord range, use this /// static markers range instead. This will bite us if someone tries to insert /// a DbgRecord in that range, but they should be using the Official (TM) API /// for that. - static DPMarker EmptyDPMarker; + static DbgMarker EmptyDbgMarker; static iterator_range<simple_ilist<DbgRecord>::iterator> getEmptyDbgRecordRange() { - return make_range(EmptyDPMarker.StoredDbgRecords.end(), - EmptyDPMarker.StoredDbgRecords.end()); + return make_range(EmptyDbgMarker.StoredDbgRecords.end(), + EmptyDbgMarker.StoredDbgRecords.end()); } }; -inline raw_ostream &operator<<(raw_ostream &OS, const DPMarker &Marker) { +inline raw_ostream &operator<<(raw_ostream &OS, const DbgMarker &Marker) { Marker.print(OS); return OS; } /// Inline helper to return a range of DbgRecords attached to a marker. It needs /// to be inlined as it's frequently called, but also come after the declaration -/// of DPMarker. Thus: it's pre-declared by users like Instruction, then an +/// of DbgMarker. Thus: it's pre-declared by users like Instruction, then an /// inlineable body defined here. inline iterator_range<simple_ilist<DbgRecord>::iterator> -getDbgRecordRange(DPMarker *DbgMarker) { - if (!DbgMarker) - return DPMarker::getEmptyDbgRecordRange(); - return DbgMarker->getDbgRecordRange(); +getDbgRecordRange(DbgMarker *DebugMarker) { + if (!DebugMarker) + return DbgMarker::getEmptyDbgRecordRange(); + return DebugMarker->getDbgRecordRange(); } DEFINE_ISA_CONVERSION_FUNCTIONS(DbgRecord, LLVMDbgRecordRef) diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h index d6cf15577523..6e0874c5b04f 100644 --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -29,19 +29,20 @@ namespace llvm { class BasicBlock; -class DPMarker; +class DbgMarker; class FastMathFlags; class MDNode; class Module; struct AAMDNodes; -class DPMarker; +class DbgMarker; class DbgRecord; template <> struct ilist_alloc_traits<Instruction> { static inline void deleteNode(Instruction *V); }; -iterator_range<simple_ilist<DbgRecord>::iterator> getDbgRecordRange(DPMarker *); +iterator_range<simple_ilist<DbgRecord>::iterator> +getDbgRecordRange(DbgMarker *); class Instruction : public User, public ilist_node_with_parent<Instruction, BasicBlock, @@ -60,7 +61,7 @@ public: /// Optional marker recording the position for debugging information that /// takes effect immediately before this instruction. Null unless there is /// debugging information present. - DPMarker *DbgMarker = nullptr; + DbgMarker *DebugMarker = nullptr; /// Clone any debug-info attached to \p From onto this instruction. Used to /// copy debugging information from one block to another, when copying entire @@ -81,7 +82,7 @@ public: /// Return a range over the DbgRecords attached to this instruction. iterator_range<simple_ilist<DbgRecord>::iterator> getDbgRecordRange() const { - return llvm::getDbgRecordRange(DbgMarker); + return llvm::getDbgRecordRange(DebugMarker); } /// Return an iterator to the position of the "Next" DbgRecord after this diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 5addf0ac33c4..a8b69f89e7de 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -3569,7 +3569,7 @@ void ModuleBitcodeWriter::writeFunction( // Write out non-instruction debug information attached to this // instruction. Write it after the instruction so that it's easy to // re-attach to the instruction reading the records in. - for (DbgRecord &DR : I.DbgMarker->getDbgRecordRange()) { + for (DbgRecord &DR : I.DebugMarker->getDbgRecordRange()) { if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) { Vals.push_back(VE.getMetadataID(&*DLR->getDebugLoc())); Vals.push_back(VE.getMetadataID(DLR->getLabel())); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 8ce6fabb30f2..38c191a2dec6 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -286,7 +286,7 @@ static const Module *getModuleFromVal(const Value *V) { return nullptr; } -static const Module *getModuleFromDPI(const DPMarker *Marker) { +static const Module *getModuleFromDPI(const DbgMarker *Marker) { const Function *M = Marker->getParent() ? Marker->getParent()->getParent() : nullptr; return M ? M->getParent() : nullptr; @@ -2717,7 +2717,7 @@ public: void printBasicBlock(const BasicBlock *BB); void printInstructionLine(const Instruction &I); void printInstruction(const Instruction &I); - void printDPMarker(const DPMarker &DPI); + void printDbgMarker(const DbgMarker &DPI); void printDbgVariableRecord(const DbgVariableRecord &DVR); void printDbgLabelRecord(const DbgLabelRecord &DLR); void printDbgRecord(const DbgRecord &DR); @@ -4604,15 +4604,15 @@ void AssemblyWriter::printInstruction(const Instruction &I) { printInfoComment(I); } -void AssemblyWriter::printDPMarker(const DPMarker &Marker) { - // There's no formal representation of a DPMarker -- print purely as a +void AssemblyWriter::printDbgMarker(const DbgMarker &Marker) { + // There's no formal representation of a DbgMarker -- print purely as a // debugging aid. for (const DbgRecord &DPR : Marker.StoredDbgRecords) { printDbgRecord(DPR); Out << "\n"; } - Out << " DPMarker -> { "; + Out << " DbgMarker -> { "; printInstruction(*Marker.MarkedInstr); Out << " }"; return; @@ -4907,7 +4907,7 @@ static bool isReferencingMDNode(const Instruction &I) { return false; } -void DPMarker::print(raw_ostream &ROS, bool IsForDebug) const { +void DbgMarker::print(raw_ostream &ROS, bool IsForDebug) const { ModuleSlotTracker MST(getModuleFromDPI(this), true); print(ROS, MST, IsForDebug); @@ -4919,8 +4919,8 @@ void DbgVariableRecord::print(raw_ostream &ROS, bool IsForDebug) const { print(ROS, MST, IsForDebug); } -void DPMarker::print(raw_ostream &ROS, ModuleSlotTracker &MST, - bool IsForDebug) const { +void DbgMarker::print(raw_ostream &ROS, ModuleSlotTracker &MST, + bool IsForDebug) const { formatted_raw_ostream OS(ROS); SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr)); SlotTracker &SlotTable = @@ -4931,7 +4931,7 @@ void DPMarker::print(raw_ostream &ROS, ModuleSlotTracker &MST, }; incorporateFunction(getParent() ? getParent()->getParent() : nullptr); AssemblyWriter W(OS, SlotTable, getModuleFromDPI(this), nullptr, IsForDebug); - W.printDPMarker(*this); + W.printDbgMarker(*this); } void DbgLabelRecord::print(raw_ostream &ROS, bool IsForDebug) const { @@ -5220,7 +5220,10 @@ void Value::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; } // Value::dump - allow easy printing of Values from the debugger. LLVM_DUMP_METHOD -void DPMarker::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; } +void DbgMarker::dump() const { + print(dbgs(), /*IsForDebug=*/true); + dbgs() << '\n'; +} // Value::dump - allow easy printing of Values from the debugger. LLVM_DUMP_METHOD diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp index 2fa9b3330d18..f088c7a2cc4e 100644 --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -41,28 +41,28 @@ cl::opt<bool, true> WriteNewDbgInfoFormatToBitcode2( "write-experimental-debuginfo-iterators-to-bitcode", cl::Hidden, cl::location(WriteNewDbgInfoFormatToBitcode), cl::init(false)); -DPMarker *BasicBlock::createMarker(Instruction *I) { +DbgMarker *BasicBlock::createMarker(Instruction *I) { assert(IsNewDbgInfoFormat && "Tried to create a marker in a non new debug-info block!"); - if (I->DbgMarker) - return I->DbgMarker; - DPMarker *Marker = new DPMarker(); + if (I->DebugMarker) + return I->DebugMarker; + DbgMarker *Marker = new DbgMarker(); Marker->MarkedInstr = I; - I->DbgMarker = Marker; + I->DebugMarker = Marker; return Marker; } -DPMarker *BasicBlock::createMarker(InstListType::iterator It) { +DbgMarker *BasicBlock::createMarker(InstListType::iterator It) { assert(IsNewDbgInfoFormat && "Tried to create a marker in a non new debug-info block!"); if (It != end()) return createMarker(&*It); - DPMarker *DPM = getTrailingDbgRecords(); - if (DPM) - return DPM; - DPM = new DPMarker(); - setTrailingDbgRecords(DPM); - return DPM; + DbgMarker *DM = getTrailingDbgRecords(); + if (DM) + return DM; + DM = new DbgMarker(); + setTrailingDbgRecords(DM); + return DM; } void BasicBlock::convertToNewDbgValues() { @@ -70,10 +70,11 @@ void BasicBlock::convertToNewDbgValues() { // Iterate over all instructions in the instruction list, collecting debug // info intrinsics and converting them to DbgRecords. Once we find a "real" - // instruction, attach all those DbgRecords to a DPMarker in that instruction. + // instruction, attach all those DbgRecords to a DbgMarker in that + // instruction. SmallVector<DbgRecord *, 4> DbgVarRecs; for (Instruction &I : make_early_inc_range(InstList)) { - assert(!I.DbgMarker && "DbgMarker already set on old-format instrs?"); + assert(!I.DebugMarker && "DebugMarker already set on old-format instrs?"); if (DbgVariableIntrinsic *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) { // Convert this dbg.value to a DbgVariableRecord. DbgVariableRecord *Value = new DbgVariableRecord(DVI); @@ -94,7 +95,7 @@ void BasicBlock::convertToNewDbgValues() { // Create a marker to store DbgRecords in. createMarker(&I); - DPMarker *Marker = I.DbgMarker; + DbgMarker *Marker = I.DebugMarker; for (DbgRecord *DVR : DbgVarRecs) Marker->insertDbgRecord(DVR, false); @@ -107,14 +108,14 @@ void BasicBlock::convertFromNewDbgValues() { invalidateOrders(); IsNewDbgInfoFormat = false; - // Iterate over the block, finding instructions annotated with DPMarkers. + // Iterate over the block, finding instructions annotated with DbgMarkers. // Convert any attached DbgRecords to debug intrinsics and insert ahead of the // instruction. for (auto &Inst : *this) { - if (!Inst.DbgMarker) + if (!Inst.DebugMarker) continue; - DPMarker &Marker = *Inst.DbgMarker; + DbgMarker &Marker = *Inst.DebugMarker; for (DbgRecord &DR : Marker.getDbgRecordRange()) InstList.insert(Inst.getIterator(), DR.createDebugIntrinsic(getModule(), nullptr)); @@ -131,11 +132,11 @@ void BasicBlock::convertFromNewDbgValues() { #ifndef NDEBUG void BasicBlock::dumpDbgValues() const { for (auto &Inst : *this) { - if (!Inst.DbgMarker) + if (!Inst.DebugMarker) continue; - dbgs() << "@ " << Inst.DbgMarker << " "; - Inst.DbgMarker->dump(); + dbgs() << "@ " << Inst.DebugMarker << " "; + Inst.DebugMarker->dump(); }; } #endif @@ -218,9 +219,9 @@ BasicBlock::~BasicBlock() { assert(getParent() == nullptr && "BasicBlock still linked into the program!"); dropAllReferences(); for (auto &Inst : *this) { - if (!Inst.DbgMarker) + if (!Inst.DebugMarker) continue; - Inst.DbgMarker->eraseFromParent(); + Inst.DebugMarker->eraseFromParent(); } InstList.clear(); } @@ -717,13 +718,13 @@ void BasicBlock::flushTerminatorDbgRecords() { return; // Are there any dangling DbgRecords? - DPMarker *TrailingDbgRecords = getTrailingDbgRecords(); + DbgMarker *TrailingDbgRecords = getTrailingDbgRecords(); if (!TrailingDbgRecords) return; // Transfer DbgRecords from the trailing position onto the terminator. createMarker(Term); - Term->DbgMarker->absorbDebugValues(*TrailingDbgRecords, false); + Term->DebugMarker->absorbDebugValues(*TrailingDbgRecords, false); TrailingDbgRecords->eraseFromParent(); deleteTrailingDbgRecords(); } @@ -760,7 +761,7 @@ void BasicBlock::spliceDebugInfoEmptyBlock(BasicBlock::iterator Dest, // occur when a block is optimised away and the terminator has been moved // somewhere else. if (Src->empty()) { - DPMarker *SrcTrailingDbgRecords = Src->getTrailingDbgRecords(); + DbgMarker *SrcTrailingDbgRecords = Src->getTrailingDbgRecords(); if (!SrcTrailingDbgRecords) return; @@ -780,7 +781,7 @@ void BasicBlock::spliceDebugInfoEmptyBlock(BasicBlock::iterator Dest, if (!First->hasDbgRecords()) return; - createMarker(Dest)->absorbDebugValues(*First->DbgMarker, InsertAtHead); + createMarker(Dest)->absorbDebugValues(*First->DebugMarker, InsertAtHead); return; } @@ -822,8 +823,8 @@ void BasicBlock::spliceDebugInfo(BasicBlock::iterator Dest, BasicBlock *Src, // If we're inserting at end(), and not in front of dangling DbgRecords, then // move the DbgRecords onto "First". They'll then be moved naturally in the // splice process. - DPMarker *MoreDanglingDbgRecords = nullptr; - DPMarker *OurTrailingDbgRecords = getTrailingDbgRecords(); + DbgMarker *MoreDanglingDbgRecords = nullptr; + DbgMarker *OurTrailingDbgRecords = getTrailingDbgRecords(); if (Dest == end() && !Dest.getHeadBit() && OurTrailingDbgRecords) { // Are the "+" DbgRecords not supposed to move? If so, detach them // temporarily. @@ -844,7 +845,7 @@ void BasicBlock::spliceDebugInfo(BasicBlock::iterator Dest, BasicBlock *Src, } else { // No current marker, create one and absorb in. (FIXME: we can avoid an // allocation in the future). - DPMarker *CurMarker = Src->createMarker(&*First); + DbgMarker *CurMarker = Src->createMarker(&*First); CurMarker->absorbDebugValues(*OurTrailingDbgRecords, false); OurTrailingDbgRecords->eraseFromParent(); } @@ -862,7 +863,7 @@ void BasicBlock::spliceDebugInfo(BasicBlock::iterator Dest, BasicBlock *Src, // FIXME: we could avoid an allocation here sometimes. (adoptDbgRecords // requires an iterator). - DPMarker *LastMarker = Src->createMarker(Last); + DbgMarker *LastMarker = Src->createMarker(Last); LastMarker->absorbDebugValues(*MoreDanglingDbgRecords, true); MoreDanglingDbgRecords->eraseFromParent(); } @@ -943,7 +944,7 @@ void BasicBlock::spliceDebugInfoImpl(BasicBlock::iterator Dest, BasicBlock *Src, // Detach the marker at Dest -- this lets us move the "====" DbgRecords // around. - DPMarker *DestMarker = nullptr; + DbgMarker *DestMarker = nullptr; if (Dest != end()) { if ((DestMarker = getMarker(Dest))) DestMarker->removeFromParent(); @@ -952,14 +953,14 @@ void BasicBlock::spliceDebugInfoImpl(BasicBlock::iterator Dest, BasicBlock *Src, // If we're moving the tail range of DbgRecords (":::"), absorb them into the // front of the DbgRecords at Dest. if (ReadFromTail && Src->getMarker(Last)) { - DPMarker *FromLast = Src->getMarker(Last); + DbgMarker *FromLast = Src->getMarker(Last); if (LastIsEnd) { Dest->adoptDbgRecords(Src, Last, true); // adoptDbgRecords will release any trailers. assert(!Src->getTrailingDbgRecords()); } else { // FIXME: can we use adoptDbgRecords here to reduce allocations? - DPMarker *OntoDest = createMarker(Dest); + DbgMarker *OntoDest = createMarker(Dest); OntoDest->absorbDebugValues(*FromLast, true); } } @@ -971,8 +972,8 @@ void BasicBlock::spliceDebugInfoImpl(BasicBlock::iterator Dest, BasicBlock *Src, if (Last != Src->end()) { Last->adoptDbgRecords(Src, First, true); } else { - DPMarker *OntoLast = Src->createMarker(Last); - DPMarker *FromFirst = Src->createMarker(First); + DbgMarker *OntoLast = Src->createMarker(Last); + DbgMarker *FromFirst = Src->createMarker(First); // Always insert at front of Last. OntoLast->absorbDebugValues(*FromFirst, true); } @@ -983,12 +984,12 @@ void BasicBlock::spliceDebugInfoImpl(BasicBlock::iterator Dest, BasicBlock *Src, if (InsertAtHead) { // Insert them at the end of the DbgRecords at Dest. The "::::" DbgRecords // might be in front of them. - DPMarker *NewDestMarker = createMarker(Dest); + DbgMarker *NewDestMarker = createMarker(Dest); NewDestMarker->absorbDebugValues(*DestMarker, false); } else { // Insert them right at the start of the range we moved, ahead of First // and the "++++" DbgRecords. - DPMarker *FirstMarker = createMarker(First); + DbgMarker *FirstMarker = createMarker(First); FirstMarker->absorbDebugValues(*DestMarker, true); } DestMarker->eraseFromParent(); @@ -997,8 +998,8 @@ void BasicBlock::spliceDebugInfoImpl(BasicBlock::iterator Dest, BasicBlock *Src, // generate the iterator with begin() / getFirstInsertionPt(), it means // any trailing debug-info at the end of the block would "normally" have // been pushed in front of "First". Move it there now. - DPMarker *FirstMarker = getMarker(First); - DPMarker *TrailingDbgRecords = getTrailingDbgRecords(); + DbgMarker *FirstMarker = getMarker(First); + DbgMarker *TrailingDbgRecords = getTrailingDbgRecords(); if (TrailingDbgRecords) { FirstMarker->absorbDebugValues(*TrailingDbgRecords, true); TrailingDbgRecords->eraseFromParent(); @@ -1040,7 +1041,7 @@ void BasicBlock::insertDbgRecordAfter(DbgRecord *DR, Instruction *I) { assert(I->getParent() == this); iterator NextIt = std::next(I->getIterator()); - DPMarker *NextMarker = createMarker(NextIt); + DbgMarker *NextMarker = createMarker(NextIt); NextMarker->insertDbgRecord(DR, true); } @@ -1048,20 +1049,20 @@ void BasicBlock::insertDbgRecordBefore(DbgRecord *DR, InstListType::iterator Where) { assert(Where == end() || Where->getParent() == this); bool InsertAtHead = Where.getHeadBit(); - DPMarker *M = createMarker(Where); + DbgMarker *M = createMarker(Where); M->insertDbgRecord(DR, InsertAtHead); } -DPMarker *BasicBlock::getNextMarker(Instruction *I) { +DbgMarker *BasicBlock::getNextMarker(Instruction *I) { return getMarker(std::next(I->getIterator())); } -DPMarker *BasicBlock::getMarker(InstListType::iterator It) { +DbgMarker *BasicBlock::getMarker(InstListType::iterator It) { if (It == end()) { - DPMarker *DPM = getTrailingDbgRecords(); - return DPM; + DbgMarker *DM = getTrailingDbgRecords(); + return DM; } - return It->DbgMarker; + return It->DebugMarker; } void BasicBlock::reinsertInstInDbgRecords( @@ -1095,27 +1096,27 @@ void BasicBlock::reinsertInstInDbgRecords( // This happens if there were no DbgRecords on I0. Are there now DbgRecords // there? if (!Pos) { - DPMarker *NextMarker = getNextMarker(I); + DbgMarker *NextMarker = getNextMarker(I); if (!NextMarker) return; if (NextMarker->StoredDbgRecords.empty()) return; - // There are DPMarkers there now -- they fell down from "I". - DPMarker *ThisMarker = createMarker(I); + // There are DbgMarkers there now -- they fell down from "I". + DbgMarker *ThisMarker = createMarker(I); ThisMarker->absorbDebugValues(*NextMarker, false); return; } // Is there even a range of DbgRecords to move? - DPMarker *DPM = (*Pos)->getMarker(); - auto Range = make_range(DPM->StoredDbgRecords.begin(), (*Pos)); + DbgMarker *DM = (*Pos)->getMarker(); + auto Range = make_range(DM->StoredDbgRecords.begin(), (*Pos)); if (Range.begin() == Range.end()) return; // Otherwise: splice. - DPMarker *ThisMarker = createMarker(I); + DbgMarker *ThisMarker = createMarker(I); assert(ThisMarker->StoredDbgRecords.empty()); - ThisMarker->absorbDebugValues(Range, *DPM, true); + ThisMarker->absorbDebugValues(Range, *DM, true); } #ifndef NDEBUG @@ -1133,11 +1134,11 @@ void BasicBlock::validateInstrOrdering() const { } #endif -void BasicBlock::setTrailingDbgRecords(DPMarker *foo) { +void BasicBlock::setTrailingDbgRecords(DbgMarker *foo) { getContext().pImpl->setTrailingDbgRecords(this, foo); } -DPMarker *BasicBlock::getTrailingDbgRecords() { +DbgMarker *BasicBlock::getTrailingDbgRecords() { return getContext().pImpl->getTrailingDbgRecords(this); } diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp index 1c0be6f598cc..fbca7cdfcf3f 100644 --- a/llvm/lib/IR/DebugProgramInstruction.cpp +++ b/llvm/lib/IR/DebugProgramInstruction.cpp @@ -1,4 +1,4 @@ -//=====-- DebugProgramInstruction.cpp - Implement DbgRecords/DPMarkers --=====// +//=====-- DebugProgramInstruction.cpp - Implement DbgRecords/DbgMarkers --====// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -529,40 +529,40 @@ const LLVMContext &DbgRecord::getContext() const { void DbgRecord::insertBefore(DbgRecord *InsertBefore) { assert(!getMarker() && - "Cannot insert a DbgRecord that is already has a DPMarker!"); + "Cannot insert a DbgRecord that is already has a DbgMarker!"); assert(InsertBefore->getMarker() && "Cannot insert a DbgRecord before a DbgRecord that does not have a " - "DPMarker!"); + "DbgMarker!"); InsertBefore->getMarker()->insertDbgRecord(this, InsertBefore); } void DbgRecord::insertAfter(DbgRecord *InsertAfter) { assert(!getMarker() && - "Cannot insert a DbgRecord that is already has a DPMarker!"); + "Cannot insert a DbgRecord that is already has a DbgMarker!"); assert(InsertAfter->getMarker() && "Cannot insert a DbgRecord after a DbgRecord that does not have a " - "DPMarker!"); + "DbgMarker!"); InsertAfter->getMarker()->insertDbgRecordAfter(this, InsertAfter); } void DbgRecord::moveBefore(DbgRecord *MoveBefore) { assert(getMarker() && - "Canot move a DbgRecord that does not currently have a DPMarker!"); + "Canot move a DbgRecord that does not currently have a DbgMarker!"); removeFromParent(); insertBefore(MoveBefore); } void DbgRecord::moveAfter(DbgRecord *MoveAfter) { assert(getMarker() && - "Canot move a DbgRecord that does not currently have a DPMarker!"); + "Canot move a DbgRecord that does not currently have a DbgMarker!"); removeFromParent(); insertAfter(MoveAfter); } /////////////////////////////////////////////////////////////////////////////// -// An empty, global, DPMarker for the purpose of describing empty ranges of +// An empty, global, DbgMarker for the purpose of describing empty ranges of // DbgRecords. -DPMarker DPMarker::EmptyDPMarker; +DbgMarker DbgMarker::EmptyDbgMarker; -void DPMarker::dropDbgRecords() { +void DbgMarker::dropDbgRecords() { while (!StoredDbgRecords.empty()) { auto It = StoredDbgRecords.begin(); DbgRecord *DR = &*It; @@ -571,31 +571,31 @@ void DPMarker::dropDbgRecords() { } } -void DPMarker::dropOneDbgRecord(DbgRecord *DR) { +void DbgMarker::dropOneDbgRecord(DbgRecord *DR) { assert(DR->getMarker() == this); StoredDbgRecords.erase(DR->getIterator()); DR->deleteRecord(); } -const BasicBlock *DPMarker::getParent() const { +const BasicBlock *DbgMarker::getParent() const { return MarkedInstr->getParent(); } -BasicBlock *DPMarker::getParent() { return MarkedInstr->getParent(); } +BasicBlock *DbgMarker::getParent() { return MarkedInstr->getParent(); } -void DPMarker::removeMarker() { - // Are there any DbgRecords in this DPMarker? If not, nothing to preserve. +void DbgMarker::removeMarker() { + // Are there any DbgRecords in this DbgMarker? If not, nothing to preserve. Instruction *Owner = MarkedInstr; if (StoredDbgRecords.empty()) { eraseFromParent(); - Owner->DbgMarker = nullptr; + Owner->DebugMarker = nullptr; return; } // The attached DbgRecords need to be preserved; attach them to the next // instruction. If there isn't a next instruction, put them on the // "trailing" list. - DPMarker *NextMarker = Owner->getParent()->getNextMarker(Owner); + DbgMarker *NextMarker = Owner->getParent()->getNextMarker(Owner); if (NextMarker) { NextMarker->absorbDebugValues(*this, true); eraseFromParent(); @@ -608,30 +608,30 @@ void DPMarker::removeMarker() { getParent()->setTrailingDbgRecords(this); MarkedInstr = nullptr; } else { - NextIt->DbgMarker = this; + NextIt->DebugMarker = this; MarkedInstr = &*NextIt; } } - Owner->DbgMarker = nullptr; + Owner->DebugMarker = nullptr; } -void DPMarker::removeFromParent() { - MarkedInstr->DbgMarker = nullptr; +void DbgMarker::removeFromParent() { + MarkedInstr->DebugMarker = nullptr; MarkedInstr = nullptr; } -void DPMarker::eraseFromParent() { +void DbgMarker::eraseFromParent() { if (MarkedInstr) removeFromParent(); dropDbgRecords(); delete this; } -iterator_range<DbgRecord::self_iterator> DPMarker::getDbgRecordRange() { +iterator_range<DbgRecord::self_iterator> DbgMarker::getDbgRecordRange() { return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end()); } iterator_range<DbgRecord::const_self_iterator> -DPMarker::getDbgRecordRange() const { +DbgMarker::getDbgRecordRange() const { return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end()); } @@ -645,25 +645,25 @@ void DbgRecord::eraseFromParent() { deleteRecord(); } -void DPMarker::insertDbgRecord(DbgRecord *New, bool InsertAtHead) { +void DbgMarker::insertDbgRecord(DbgRecord *New, bool InsertAtHead) { auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end(); StoredDbgRecords.insert(It, *New); New->setMarker(this); } -void DPMarker::insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore) { +void DbgMarker::insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore) { assert(InsertBefore->getMarker() == this && - "DbgRecord 'InsertBefore' must be contained in this DPMarker!"); + "DbgRecord 'InsertBefore' must be contained in this DbgMarker!"); StoredDbgRecords.insert(InsertBefore->getIterator(), *New); New->setMarker(this); } -void DPMarker::insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter) { +void DbgMarker::insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter) { assert(InsertAfter->getMarker() == this && - "DbgRecord 'InsertAfter' must be contained in this DPMarker!"); + "DbgRecord 'InsertAfter' must be contained in this DbgMarker!"); StoredDbgRecords.insert(++(InsertAfter->getIterator()), *New); New->setMarker(this); } -void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) { +void DbgMarker::absorbDebugValues(DbgMarker &Src, bool InsertAtHead) { auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end(); for (DbgRecord &DVR : Src.StoredDbgRecords) DVR.setMarker(this); @@ -671,8 +671,9 @@ void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) { StoredDbgRecords.splice(It, Src.StoredDbgRecords); } -void DPMarker::absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range, - DPMarker &Src, bool InsertAtHead) { +void DbgMarker::absorbDebugValues( + iterator_range<DbgRecord::self_iterator> Range, DbgMarker &Src, + bool InsertAtHead) { for (DbgRecord &DR : Range) DR.setMarker(this); @@ -683,8 +684,8 @@ void DPMarker::absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range, Range.end()); } -iterator_range<simple_ilist<DbgRecord>::iterator> DPMarker::cloneDebugInfoFrom( - DPMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here, +iterator_range<simple_ilist<DbgRecord>::iterator> DbgMarker::cloneDebugInfoFrom( + DbgMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here, bool InsertAtHead) { DbgRecord *First = nullptr; // Work out what range of DbgRecords to clone: normally all the contents of diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 9744eb32d27a..47a7f2c9de79 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -93,10 +93,10 @@ void Instruction::removeFromParent() { } void Instruction::handleMarkerRemoval() { - if (!Parent->IsNewDbgInfoFormat || !DbgMarker) + if (!Parent->IsNewDbgInfoFormat || !DebugMarker) return; - DbgMarker->removeMarker(); + DebugMarker->removeMarker(); } BasicBlock::iterator Instruction::eraseFromParent() { @@ -135,7 +135,7 @@ extern cl::opt<bool> UseNewDbgInfoFormat; void Instruction::insertBefore(BasicBlock &BB, InstListType::iterator InsertPos) { - assert(!DbgMarker); + assert(!DebugMarker); BB.getInstList().insert(InsertPos, this); @@ -147,7 +147,7 @@ void Instruction::insertBefore(BasicBlock &BB, // DbgRecords should now come before "this". bool InsertAtHead = InsertPos.getHeadBit(); if (!InsertAtHead) { - DPMarker *SrcMarker = BB.getMarker(InsertPos); + DbgMarker *SrcMarker = BB.getMarker(InsertPos); if (SrcMarker && !SrcMarker->empty()) { // If this assertion fires, the calling code is about to insert a PHI // after debug-records, which would form a sequence like: @@ -214,7 +214,7 @@ void Instruction::moveBeforeImpl(BasicBlock &BB, InstListType::iterator I, // If we've been given the "Preserve" flag, then just move the DbgRecords with // the instruction, no more special handling needed. - if (BB.IsNewDbgInfoFormat && DbgMarker && !Preserve) { + if (BB.IsNewDbgInfoFormat && DebugMarker && !Preserve) { if (I != this->getIterator() || InsertAtHead) { // "this" is definitely moving in the list, or it's moving ahead of its // attached DbgVariableRecords. Detach any existing DbgRecords. @@ -227,7 +227,7 @@ void Instruction::moveBeforeImpl(BasicBlock &BB, InstListType::iterator I, BB.getInstList().splice(I, getParent()->getInstList(), getIterator()); if (BB.IsNewDbgInfoFormat && !Preserve) { - DPMarker *NextMarker = getParent()->getNextMarker(this); + DbgMarker *NextMarker = getParent()->getNextMarker(this); // If we're inserting at point I, and not in front of the DbgRecords // attached there, then we should absorb the DbgRecords attached to I. @@ -243,23 +243,24 @@ void Instruction::moveBeforeImpl(BasicBlock &BB, InstListType::iterator I, iterator_range<DbgRecord::self_iterator> Instruction::cloneDebugInfoFrom( const Instruction *From, std::optional<DbgRecord::self_iterator> FromHere, bool InsertAtHead) { - if (!From->DbgMarker) - return DPMarker::getEmptyDbgRecordRange(); + if (!From->DebugMarker) + return DbgMarker::getEmptyDbgRecordRange(); assert(getParent()->IsNewDbgInfoFormat); assert(getParent()->IsNewDbgInfoFormat == From->getParent()->IsNewDbgInfoFormat); - if (!DbgMarker) + if (!DebugMarker) getParent()->createMarker(this); - return DbgMarker->cloneDebugInfoFrom(From->DbgMarker, FromHere, InsertAtHead); + return DebugMarker->cloneDebugInfoFrom(From->DebugMarker, FromHere, + InsertAtHead); } std::optional<DbgRecord::self_iterator> Instruction::getDbgReinsertionPosition() { // Is there a marker on the next instruction? - DPMarker *NextMarker = getParent()->getNextMarker(this); + DbgMarker *NextMarker = getParent()->getNextMarker(this); if (!NextMarker) return std::nullopt; @@ -274,7 +275,7 @@ bool Instruction::hasDbgRecords() const { return !getDbgRecordRange().empty(); } void Instruction::adoptDbgRecords(BasicBlock *BB, BasicBlock::iterator It, bool InsertAtHead) { - DPMarker *SrcMarker = BB->getMarker(It); + DbgMarker *SrcMarker = BB->getMarker(It); auto ReleaseTrailingDbgRecords = [BB, It, SrcMarker]() { if (BB->end() == It) { SrcMarker->eraseFromParent(); @@ -287,13 +288,13 @@ void Instruction::adoptDbgRecords(BasicBlock *BB, BasicBlock::iterator It, return; } - // If we have DPMarkers attached to this instruction, we have to honour the + // If we have DbgMarkers attached to this instruction, we have to honour the // ordering of DbgRecords between this and the other marker. Fall back to just // absorbing from the source. - if (DbgMarker || It == BB->end()) { + if (DebugMarker || It == BB->end()) { // Ensure we _do_ have a marker. getParent()->createMarker(this); - DbgMarker->absorbDebugValues(*SrcMarker, InsertAtHead); + DebugMarker->absorbDebugValues(*SrcMarker, InsertAtHead); // Having transferred everything out of SrcMarker, we _could_ clean it up // and free the marker now. However, that's a lot of heap-accounting for a @@ -309,19 +310,19 @@ void Instruction::adoptDbgRecords(BasicBlock *BB, BasicBlock::iterator It, // Optimisation: we're transferring all the DbgRecords from the source // marker onto this empty location: just adopt the other instructions // marker. - DbgMarker = SrcMarker; - DbgMarker->MarkedInstr = this; - It->DbgMarker = nullptr; + DebugMarker = SrcMarker; + DebugMarker->MarkedInstr = this; + It->DebugMarker = nullptr; } } void Instruction::dropDbgRecords() { - if (DbgMarker) - DbgMarker->dropDbgRecords(); + if (DebugMarker) + DebugMarker->dropDbgRecords(); } void Instruction::dropOneDbgRecord(DbgRecord *DVR) { - DbgMarker->dropOneDbgRecord(DVR); + DebugMarker->dropOneDbgRecord(DVR); } bool Instruction::comesBefore(const Instruction *Other) const { diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 4542e16e59fd..58e0f21244f7 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -58,7 +58,7 @@ class AttributeSetNode; class BasicBlock; class ConstantRangeAttributeImpl; struct DiagnosticHandler; -class DPMarker; +class DbgMarker; class ElementCount; class Function; class GlobalObject; @@ -1689,15 +1689,15 @@ public: /// "trail" in such a way. These are stored in LLVMContext because typically /// LLVM only edits a small number of blocks at a time, so there's no need to /// bloat BasicBlock with such a data structure. - SmallDenseMap<BasicBlock *, DPMarker *> TrailingDbgRecords; + SmallDenseMap<BasicBlock *, DbgMarker *> TrailingDbgRecords; // Set, get and delete operations for TrailingDbgRecords. - void setTrailingDbgRecords(BasicBlock *B, DPMarker *M) { + void setTrailingDbgRecords(BasicBlock *B, DbgMarker *M) { assert(!TrailingDbgRecords.count(B)); TrailingDbgRecords[B] = M; } - DPMarker *getTrailingDbgRecords(BasicBlock *B) { + DbgMarker *getTrailingDbgRecords(BasicBlock *B) { return TrailingDbgRecords.lookup(B); } diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index 61e1c35ba4a3..8522747ccf12 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -581,7 +581,7 @@ static void replaceDbgUsesOutsideBlock(Value *V, Value *New, BasicBlock *BB) { DVI->replaceVariableLocationOp(V, New); } for (auto *DVR : DPUsers) { - DPMarker *Marker = DVR->getMarker(); + DbgMarker *Marker = DVR->getMarker(); if (Marker->getParent() != BB) DVR->replaceVariableLocationOp(V, New); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index a99b307a3536..819722566831 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -678,15 +678,15 @@ private: } while (false) void Verifier::visitDbgRecords(Instruction &I) { - if (!I.DbgMarker) + if (!I.DebugMarker) return; - CheckDI(I.DbgMarker->MarkedInstr == &I, "Instruction has invalid DbgMarker", - &I); + CheckDI(I.DebugMarker->MarkedInstr == &I, + "Instruction has invalid DebugMarker", &I); CheckDI(!isa<PHINode>(&I) || !I.hasDbgRecords(), "PHI Node must not have any attached DbgRecords", &I); for (DbgRecord &DR : I.getDbgRecordRange()) { - CheckDI(DR.getMarker() == I.DbgMarker, "DbgRecord had invalid DbgMarker", - &I, &DR); + CheckDI(DR.getMarker() == I.DebugMarker, + "DbgRecord had invalid DebugMarker", &I, &DR); if (auto *Loc = dyn_cast_or_null<DILocation>(DR.getDebugLoc().getAsMDNode())) visitMDNode(*Loc, AreDebugLocsAllowed::Yes); diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index fd6835952570..ffcb511e6a83 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -2113,8 +2113,8 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI, // marker to marker as there isn't an instruction there. if (BE != RangeBB->end() && BE->hasDbgRecords()) { // Dump them at the end. - DPMarker *Marker = RangeBB->getMarker(BE); - DPMarker *EndMarker = NewBB->createMarker(NewBB->end()); + DbgMarker *Marker = RangeBB->getMarker(BE); + DbgMarker *EndMarker = NewBB->createMarker(NewBB->end()); auto DVRRange = EndMarker->cloneDebugInfoFrom(Marker, std::nullopt); for (DbgVariableRecord &DVR : filterDbgVars(DVRRange)) RetargetDbgVariableRecordIfPossible(&DVR); diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp index 4470c5af870a..bc6711711371 100644 --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -601,7 +601,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { // a range because it gives us a natural way of testing whether // there were DbgRecords on the next instruction before we hoisted things). iterator_range<DbgRecord::self_iterator> NextDbgInsts = - (I != E) ? I->getDbgRecordRange() : DPMarker::getEmptyDbgRecordRange(); + (I != E) ? I->getDbgRecordRange() : DbgMarker::getEmptyDbgRecordRange(); while (I != E) { Instruction *Inst = &*I++; @@ -659,7 +659,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { RemapDbgVariableRecordRange(M, Range, ValueMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); - NextDbgInsts = DPMarker::getEmptyDbgRecordRange(); + NextDbgInsts = DbgMarker::getEmptyDbgRecordRange(); // Erase anything we've seen before. for (DbgVariableRecord &DVR : make_early_inc_range(filterDbgVars(Range))) diff --git a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp index 92658b7b6895..905928819dda 100644 --- a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp +++ b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp @@ -147,10 +147,10 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) { // Fetch out our two markers, Instruction *Instr1 = &*BB.begin(); Instruction *Instr2 = Instr1->getNextNode(); - DPMarker *Marker1 = Instr1->DbgMarker; - DPMarker *Marker2 = Instr2->DbgMarker; + DbgMarker *Marker1 = Instr1->DebugMarker; + DbgMarker *Marker2 = Instr2->DebugMarker; // There's no TrailingDbgRecords marker allocated yet. - DPMarker *EndMarker = nullptr; + DbgMarker *EndMarker = nullptr; // Check that the "getMarker" utilities operate as expected. EXPECT_EQ(BB.getMarker(Instr1->getIterator()), Marker1); @@ -219,7 +219,7 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) { // Inserting at end(): should dislodge the DbgVariableRecords, if they were // dbg.values then they would sit "above" the new instruction. Instr1->insertBefore(BB, BB.end()); - EXPECT_EQ(Instr1->DbgMarker->StoredDbgRecords.size(), 2u); + EXPECT_EQ(Instr1->DebugMarker->StoredDbgRecords.size(), 2u); // We should de-allocate the trailing marker when something is inserted // at end(). EXPECT_EQ(BB.getTrailingDbgRecords(), nullptr); @@ -234,7 +234,7 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) { // this be the final instr in the block, and DbgVariableRecords aren't allowed // to live off the end forever. Instr2->insertBefore(BB, BB.begin()); - EXPECT_EQ(Instr2->DbgMarker->StoredDbgRecords.size(), 2u); + EXPECT_EQ(Instr2->DebugMarker->StoredDbgRecords.size(), 2u); EXPECT_EQ(BB.getTrailingDbgRecords(), nullptr); // Teardown, @@ -297,26 +297,27 @@ TEST(BasicBlockDbgInfoTest, HeadBitOperations) { Instruction *CInst = BInst->getNextNode(); Instruction *DInst = CInst->getNextNode(); // CInst should have debug-info. - ASSERT_TRUE(CInst->DbgMarker); - EXPECT_FALSE(CInst->DbgMarker->StoredDbgRecords.empty()); + ASSERT_TRUE(CInst->DebugMarker); + EXPECT_FALSE(CInst->DebugMarker->StoredDbgRecords.empty()); // If we move "c" to the start of the block, just normally, then the // DbgVariableRecords should fall down to "d". CInst->moveBefore(BB, BeginIt2); - EXPECT_TRUE(!CInst->DbgMarker || CInst->DbgMarker->StoredDbgRecords.empty()); - ASSERT_TRUE(DInst->DbgMarker); - EXPECT_FALSE(DInst->DbgMarker->StoredDbgRecords.empty()); + EXPECT_TRUE(!CInst->DebugMarker || + CInst->DebugMarker->StoredDbgRecords.empty()); + ASSERT_TRUE(DInst->DebugMarker); + EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty()); // Wheras if we move D to the start of the block with moveBeforePreserving, // the DbgVariableRecords should move with it. DInst->moveBeforePreserving(BB, BB.begin()); - EXPECT_FALSE(DInst->DbgMarker->StoredDbgRecords.empty()); + EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty()); EXPECT_EQ(&*BB.begin(), DInst); // Similarly, moveAfterPreserving "D" to "C" should move DbgVariableRecords // with "D". DInst->moveAfterPreserving(CInst); - EXPECT_FALSE(DInst->DbgMarker->StoredDbgRecords.empty()); + EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty()); // (move back to the start...) DInst->moveBeforePreserving(BB, BB.begin()); @@ -325,8 +326,9 @@ TEST(BasicBlockDbgInfoTest, HeadBitOperations) { // If we move "C" to the beginning of the block, it should go before the // DbgVariableRecords. They'll stay on "D". CInst->moveBefore(BB, BB.begin()); - EXPECT_TRUE(!CInst->DbgMarker || CInst->DbgMarker->StoredDbgRecords.empty()); - EXPECT_FALSE(DInst->DbgMarker->StoredDbgRecords.empty()); + EXPECT_TRUE(!CInst->DebugMarker || + CInst->DebugMarker->StoredDbgRecords.empty()); + EXPECT_FALSE(DInst->DebugMarker->StoredDbgRecords.empty()); EXPECT_EQ(&*BB.begin(), CInst); EXPECT_EQ(CInst->getNextNode(), DInst); @@ -342,8 +344,9 @@ TEST(BasicBlockDbgInfoTest, HeadBitOperations) { // run of dbg.values and the next instruction. CInst->moveBefore(BB, DInst->getIterator()); // CInst gains the DbgVariableRecords. - EXPECT_TRUE(!DInst->DbgMarker || DInst->DbgMarker->StoredDbgRecords.empty()); - EXPECT_FALSE(CInst->DbgMarker->StoredDbgRecords.empty()); + EXPECT_TRUE(!DInst->DebugMarker || + DInst->DebugMarker->StoredDbgRecords.empty()); + EXPECT_FALSE(CInst->DebugMarker->StoredDbgRecords.empty()); EXPECT_EQ(&*BB.begin(), CInst); UseNewDbgInfoFormat = false; @@ -380,7 +383,7 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) { )"); // Check that DbgVariableRecords can be accessed from Instructions without - // digging into the depths of DPMarkers. + // digging into the depths of DbgMarkers. BasicBlock &BB = M->getFunction("f")->getEntryBlock(); // Convert the module to "new" form debug-info. M->convertToNewDbgValues(); @@ -389,18 +392,18 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) { Instruction *CInst = BInst->getNextNode(); Instruction *DInst = CInst->getNextNode(); - ASSERT_FALSE(BInst->DbgMarker); - ASSERT_TRUE(CInst->DbgMarker); - ASSERT_EQ(CInst->DbgMarker->StoredDbgRecords.size(), 1u); - DbgRecord *DVR1 = &*CInst->DbgMarker->StoredDbgRecords.begin(); + ASSERT_FALSE(BInst->DebugMarker); + ASSERT_TRUE(CInst->DebugMarker); + ASSERT_EQ(CInst->DebugMarker->StoredDbgRecords.size(), 1u); + DbgRecord *DVR1 = &*CInst->DebugMarker->StoredDbgRecords.begin(); ASSERT_TRUE(DVR1); EXPECT_FALSE(BInst->hasDbgRecords()); // Clone DbgVariableRecords from one inst to another. Other arguments to clone - // are tested in DPMarker test. + // are tested in DbgMarker test. auto Range1 = BInst->cloneDebugInfoFrom(CInst); - EXPECT_EQ(BInst->DbgMarker->StoredDbgRecords.size(), 1u); - DbgRecord *DVR2 = &*BInst->DbgMarker->StoredDbgRecords.begin(); + EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 1u); + DbgRecord *DVR2 = &*BInst->DebugMarker->StoredDbgRecords.begin(); EXPECT_EQ(std::distance(Range1.begin(), Range1.end()), 1u); EXPECT_EQ(&*Range1.begin(), DVR2); EXPECT_NE(DVR1, DVR2); @@ -418,12 +421,12 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) { // Dropping should be easy, BInst->dropDbgRecords(); EXPECT_FALSE(BInst->hasDbgRecords()); - EXPECT_EQ(BInst->DbgMarker->StoredDbgRecords.size(), 0u); + EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 0u); // And we should be able to drop individual DbgVariableRecords. CInst->dropOneDbgRecord(DVR1); EXPECT_FALSE(CInst->hasDbgRecords()); - EXPECT_EQ(CInst->DbgMarker->StoredDbgRecords.size(), 0u); + EXPECT_EQ(CInst->DebugMarker->StoredDbgRecords.size(), 0u); UseNewDbgInfoFormat = false; } @@ -533,11 +536,11 @@ protected: CInst = &*Dest; DVRA = - cast<DbgVariableRecord>(&*BInst->DbgMarker->StoredDbgRecords.begin()); - DVRB = - cast<DbgVariableRecord>(&*Branch->DbgMarker->StoredDbgRecords.begin()); + cast<DbgVariableRecord>(&*BInst->DebugMarker->StoredDbgRecords.begin()); + DVRB = cast<DbgVariableRecord>( + &*Branch->DebugMarker->StoredDbgRecords.begin()); DVRConst = - cast<DbgVariableRecord>(&*CInst->DbgMarker->StoredDbgRecords.begin()); + cast<DbgVariableRecord>(&*CInst->DebugMarker->StoredDbgRecords.begin()); } void TearDown() override { UseNewDbgInfoFormat = false; } @@ -546,8 +549,8 @@ protected: for (DbgRecord &D : I->getDbgRecordRange()) { if (&D == DVR) { // Confirm too that the links between the records are correct. - EXPECT_EQ(DVR->Marker, I->DbgMarker); - EXPECT_EQ(I->DbgMarker->MarkedInstr, I); + EXPECT_EQ(DVR->Marker, I->DebugMarker); + EXPECT_EQ(I->DebugMarker->MarkedInstr, I); return true; } } @@ -1173,14 +1176,14 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceTrailing) { // The trailing DbgVariableRecord should have been placed at the front of // what's been spliced in. Instruction *BInst = &*Entry.begin(); - ASSERT_TRUE(BInst->DbgMarker); - EXPECT_EQ(BInst->DbgMarker->StoredDbgRecords.size(), 1u); + ASSERT_TRUE(BInst->DebugMarker); + EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 1u); UseNewDbgInfoFormat = false; } // When we remove instructions from the program, adjacent DbgVariableRecords -// coalesce together into one DPMarker. In "old" dbg.value mode you could +// coalesce together into one DbgMarker. In "old" dbg.value mode you could // re-insert the removed instruction back into the middle of a sequence of // dbg.values. Test that this can be replicated correctly by DbgVariableRecords TEST(BasicBlockDbgInfoTest, RemoveInstAndReinsert) { @@ -1392,7 +1395,7 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty1) { // should be in the correct order of %a, then 0. Instruction *BInst = &*Entry.begin(); ASSERT_TRUE(BInst->hasDbgRecords()); - EXPECT_EQ(BInst->DbgMarker->StoredDbgRecords.size(), 2u); + EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 2u); SmallVector<DbgVariableRecord *, 2> DbgVariableRecords; for (DbgRecord &DVR : BInst->getDbgRecordRange()) DbgVariableRecords.push_back(cast<DbgVariableRecord>(&DVR)); @@ -1462,7 +1465,7 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty2) { // We should now have one dbg.values on the first instruction, %a. Instruction *BInst = &*Entry.begin(); ASSERT_TRUE(BInst->hasDbgRecords()); - EXPECT_EQ(BInst->DbgMarker->StoredDbgRecords.size(), 1u); + EXPECT_EQ(BInst->DebugMarker->StoredDbgRecords.size(), 1u); SmallVector<DbgVariableRecord *, 2> DbgVariableRecords; for (DbgRecord &DVR : BInst->getDbgRecordRange()) DbgVariableRecords.push_back(cast<DbgVariableRecord>(&DVR)); diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp index 3672f2bccfec..d06b979bf4a1 100644 --- a/llvm/unittests/IR/DebugInfoTest.cpp +++ b/llvm/unittests/IR/DebugInfoTest.cpp @@ -947,67 +947,68 @@ TEST(MetadataTest, ConvertDbgToDbgVariableRecord) { Instruction *FirstInst = &ExitBlock->front(); Instruction *RetInst = &*std::next(FirstInst->getIterator()); - // Set-up DPMarkers in this block. + // Set-up DbgMarkers in this block. ExitBlock->IsNewDbgInfoFormat = true; ExitBlock->createMarker(FirstInst); ExitBlock->createMarker(RetInst); // Insert DbgRecords into markers, order should come out DVR2, DVR1. - FirstInst->DbgMarker->insertDbgRecord(DVR1, false); - FirstInst->DbgMarker->insertDbgRecord(DVR2, true); + FirstInst->DebugMarker->insertDbgRecord(DVR1, false); + FirstInst->DebugMarker->insertDbgRecord(DVR2, true); unsigned int ItCount = 0; - for (DbgRecord &Item : FirstInst->DbgMarker->getDbgRecordRange()) { + for (DbgRecord &Item : FirstInst->DebugMarker->getDbgRecordRange()) { EXPECT_TRUE((&Item == DVR2 && ItCount == 0) || (&Item == DVR1 && ItCount == 1)); - EXPECT_EQ(Item.getMarker(), FirstInst->DbgMarker); + EXPECT_EQ(Item.getMarker(), FirstInst->DebugMarker); ++ItCount; } // Clone them onto the second marker -- should allocate new DVRs. - RetInst->DbgMarker->cloneDebugInfoFrom(FirstInst->DbgMarker, std::nullopt, false); - EXPECT_EQ(RetInst->DbgMarker->StoredDbgRecords.size(), 2u); + RetInst->DebugMarker->cloneDebugInfoFrom(FirstInst->DebugMarker, std::nullopt, + false); + EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 2u); ItCount = 0; // Check these things store the same information; but that they're not the same // objects. for (DbgVariableRecord &Item : - filterDbgVars(RetInst->DbgMarker->getDbgRecordRange())) { + filterDbgVars(RetInst->DebugMarker->getDbgRecordRange())) { EXPECT_TRUE( (Item.getRawLocation() == DVR2->getRawLocation() && ItCount == 0) || (Item.getRawLocation() == DVR1->getRawLocation() && ItCount == 1)); - EXPECT_EQ(Item.getMarker(), RetInst->DbgMarker); + EXPECT_EQ(Item.getMarker(), RetInst->DebugMarker); EXPECT_NE(&Item, DVR1); EXPECT_NE(&Item, DVR2); ++ItCount; } - RetInst->DbgMarker->dropDbgRecords(); - EXPECT_EQ(RetInst->DbgMarker->StoredDbgRecords.size(), 0u); + RetInst->DebugMarker->dropDbgRecords(); + EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 0u); // Try cloning one single DbgVariableRecord. - auto DIIt = std::next(FirstInst->DbgMarker->getDbgRecordRange().begin()); - RetInst->DbgMarker->cloneDebugInfoFrom(FirstInst->DbgMarker, DIIt, false); - EXPECT_EQ(RetInst->DbgMarker->StoredDbgRecords.size(), 1u); + auto DIIt = std::next(FirstInst->DebugMarker->getDbgRecordRange().begin()); + RetInst->DebugMarker->cloneDebugInfoFrom(FirstInst->DebugMarker, DIIt, false); + EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 1u); // The second DbgVariableRecord should have been cloned; it should have the // same values as DVR1. EXPECT_EQ( - cast<DbgVariableRecord>(RetInst->DbgMarker->StoredDbgRecords.begin()) + cast<DbgVariableRecord>(RetInst->DebugMarker->StoredDbgRecords.begin()) ->getRawLocation(), DVR1->getRawLocation()); // We should be able to drop individual DbgRecords. - RetInst->DbgMarker->dropOneDbgRecord( - &*RetInst->DbgMarker->StoredDbgRecords.begin()); + RetInst->DebugMarker->dropOneDbgRecord( + &*RetInst->DebugMarker->StoredDbgRecords.begin()); - // "Aborb" a DPMarker: this means pretend that the instruction it's attached + // "Aborb" a DbgMarker: this means pretend that the instruction it's attached // to is disappearing so it needs to be transferred into "this" marker. - RetInst->DbgMarker->absorbDebugValues(*FirstInst->DbgMarker, true); - EXPECT_EQ(RetInst->DbgMarker->StoredDbgRecords.size(), 2u); + RetInst->DebugMarker->absorbDebugValues(*FirstInst->DebugMarker, true); + EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 2u); // Should be the DVR1 and DVR2 objects. ItCount = 0; - for (DbgRecord &Item : RetInst->DbgMarker->getDbgRecordRange()) { + for (DbgRecord &Item : RetInst->DebugMarker->getDbgRecordRange()) { EXPECT_TRUE((&Item == DVR2 && ItCount == 0) || (&Item == DVR1 && ItCount == 1)); - EXPECT_EQ(Item.getMarker(), RetInst->DbgMarker); + EXPECT_EQ(Item.getMarker(), RetInst->DebugMarker); ++ItCount; } @@ -1015,12 +1016,12 @@ TEST(MetadataTest, ConvertDbgToDbgVariableRecord) { // evrything in the basic block, then they should sink down into the // "TrailingDbgRecords" container for dangling debug-info. Future facilities // will restore them back when a terminator is inserted. - FirstInst->DbgMarker->removeMarker(); + FirstInst->DebugMarker->removeMarker(); FirstInst->eraseFromParent(); - RetInst->DbgMarker->removeMarker(); + RetInst->DebugMarker->removeMarker(); RetInst->eraseFromParent(); - DPMarker *EndMarker = ExitBlock->getTrailingDbgRecords(); + DbgMarker *EndMarker = ExitBlock->getTrailingDbgRecords(); ASSERT_NE(EndMarker, nullptr); EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u); // Test again that it's those two DbgVariableRecords, DVR1 and DVR2. @@ -1083,7 +1084,7 @@ TEST(MetadataTest, DbgVariableRecordConversionRoutines) { // First instruction should be a dbg.value. EXPECT_TRUE(isa<DbgValueInst>(BB1->front())); EXPECT_FALSE(BB1->IsNewDbgInfoFormat); - // Validating the block for DbgVariableRecords / DPMarkers shouldn't fail -- + // Validating the block for DbgVariableRecords / DbgMarkers shouldn't fail -- // there's no data stored right now. bool BrokenDebugInfo = false; bool Error = verifyModule(*M, &errs(), &BrokenDebugInfo); @@ -1107,38 +1108,39 @@ TEST(MetadataTest, DbgVariableRecordConversionRoutines) { for (auto &I : BB) EXPECT_FALSE(isa<DbgValueInst>(I)); - // There should be a DPMarker on each of the two instructions in the entry + // There should be a DbgMarker on each of the two instructions in the entry // block, each containing one DbgVariableRecord. EXPECT_EQ(BB1->size(), 2u); Instruction *FirstInst = &BB1->front(); Instruction *SecondInst = FirstInst->getNextNode(); - ASSERT_TRUE(FirstInst->DbgMarker); - ASSERT_TRUE(SecondInst->DbgMarker); - EXPECT_NE(FirstInst->DbgMarker, SecondInst->DbgMarker); - EXPECT_EQ(FirstInst, FirstInst->DbgMarker->MarkedInstr); - EXPECT_EQ(SecondInst, SecondInst->DbgMarker->MarkedInstr); + ASSERT_TRUE(FirstInst->DebugMarker); + ASSERT_TRUE(SecondInst->DebugMarker); + EXPECT_NE(FirstInst->DebugMarker, SecondInst->DebugMarker); + EXPECT_EQ(FirstInst, FirstInst->DebugMarker->MarkedInstr); + EXPECT_EQ(SecondInst, SecondInst->DebugMarker->MarkedInstr); - EXPECT_EQ(FirstInst->DbgMarker->StoredDbgRecords.size(), 1u); + EXPECT_EQ(FirstInst->DebugMarker->StoredDbgRecords.size(), 1u); DbgVariableRecord *DVR1 = cast<DbgVariableRecord>( - &*FirstInst->DbgMarker->getDbgRecordRange().begin()); - EXPECT_EQ(DVR1->getMarker(), FirstInst->DbgMarker); + &*FirstInst->DebugMarker->getDbgRecordRange().begin()); + EXPECT_EQ(DVR1->getMarker(), FirstInst->DebugMarker); // Should point at %a, an argument. EXPECT_TRUE(isa<Argument>(DVR1->getVariableLocationOp(0))); - EXPECT_EQ(SecondInst->DbgMarker->StoredDbgRecords.size(), 1u); + EXPECT_EQ(SecondInst->DebugMarker->StoredDbgRecords.size(), 1u); DbgVariableRecord *DVR2 = cast<DbgVariableRecord>( - &*SecondInst->DbgMarker->getDbgRecordRange().begin()); - EXPECT_EQ(DVR2->getMarker(), SecondInst->DbgMarker); + &*SecondInst->DebugMarker->getDbgRecordRange().begin()); + EXPECT_EQ(DVR2->getMarker(), SecondInst->DebugMarker); // Should point at FirstInst. EXPECT_EQ(DVR2->getVariableLocationOp(0), FirstInst); - // There should be no DbgVariableRecords / DPMarkers in the second block, but + // There should be no DbgVariableRecords / DbgMarkers in the second block, but // it should be marked as being in the new format. BasicBlock *BB2 = BB1->getNextNode(); EXPECT_TRUE(BB2->IsNewDbgInfoFormat); for (auto &Inst : *BB2) // Either there should be no marker, or it should be empty. - EXPECT_TRUE(!Inst.DbgMarker || Inst.DbgMarker->StoredDbgRecords.empty()); + EXPECT_TRUE(!Inst.DebugMarker || + Inst.DebugMarker->StoredDbgRecords.empty()); // Validating the first block should continue to not be a problem, Error = verifyModule(*M, &errs(), &BrokenDebugInfo); @@ -1152,7 +1154,7 @@ TEST(MetadataTest, DbgVariableRecordConversionRoutines) { Error = verifyModule(*M, &errs(), &BrokenDebugInfo); EXPECT_FALSE(Error); EXPECT_TRUE(BrokenDebugInfo); - DVR1->setMarker(FirstInst->DbgMarker); + DVR1->setMarker(FirstInst->DebugMarker); DILocalVariable *DLV1 = DVR1->getVariable(); DIExpression *Expr1 = DVR1->getExpression(); diff --git a/llvm/unittests/Transforms/Utils/LocalTest.cpp b/llvm/unittests/Transforms/Utils/LocalTest.cpp index 4258f218794f..a86775a1366b 100644 --- a/llvm/unittests/Transforms/Utils/LocalTest.cpp +++ b/llvm/unittests/Transforms/Utils/LocalTest.cpp @@ -1324,10 +1324,10 @@ TEST(Local, ReplaceDbgVariableRecord) { Instruction *RetInst = &*It; // Convert DVI into a DbgVariableRecord. - RetInst->DbgMarker = new DPMarker(); - RetInst->DbgMarker->MarkedInstr = RetInst; + RetInst->DebugMarker = new DbgMarker(); + RetInst->DebugMarker->MarkedInstr = RetInst; DbgVariableRecord *DVR = new DbgVariableRecord(DVI); - RetInst->DbgMarker->insertDbgRecord(DVR, false); + RetInst->DebugMarker->insertDbgRecord(DVR, false); // ... and erase the dbg.value. DVI->eraseFromParent(); @@ -1341,5 +1341,5 @@ TEST(Local, ReplaceDbgVariableRecord) { EXPECT_EQ(DVR->getVariableLocationOp(0), FooInst); // Teardown. - RetInst->DbgMarker->eraseFromParent(); + RetInst->DebugMarker->eraseFromParent(); } -- GitLab From 407937036fa7640f61f225474b1ea6623a40dbdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st> Date: Wed, 20 Mar 2024 18:06:07 +0200 Subject: [PATCH 272/307] Revert "[libcxx] [modules] Fix relative paths with absolute LIBCXX_INSTALL_MODULES_DIR (#85756)" This reverts commit 272d1b44efdedb68c194970a610f0ca1b7b769c5, and the follow-up fix in d209d1340b99d4fbd325dffb5e13b757ab8264ea. Even after the follow-up fix, building with an empty CMAKE_INSTALL_PREFIX errors out with errors like this: CMake Error at /b/s/w/ir/x/w/llvm-llvm-project/libcxx/modules/CMakeLists.txt:215 (file): file RELATIVE_PATH must be passed a full path to the directory: lib/x86_64-pc-windows-msvc --- libcxx/modules/CMakeLists.txt | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/libcxx/modules/CMakeLists.txt b/libcxx/modules/CMakeLists.txt index 6c917200d6f3..0dea8cfca94a 100644 --- a/libcxx/modules/CMakeLists.txt +++ b/libcxx/modules/CMakeLists.txt @@ -206,15 +206,9 @@ add_custom_target(generate-cxx-modules # Configure the modules manifest. # Use the relative path between the installation and the module in the json # file. This allows moving the entire installation to a different location. -cmake_path(ABSOLUTE_PATH LIBCXX_INSTALL_LIBRARY_DIR - BASE_DIRECTORY "${CMAKE_INSTALL_PREFIX}" - OUTPUT_VARIABLE ABS_LIBRARY_DIR) -cmake_path(ABSOLUTE_PATH LIBCXX_INSTALL_MODULES_DIR - BASE_DIRECTORY "${CMAKE_INSTALL_PREFIX}" - OUTPUT_VARIABLE ABS_MODULES_DIR) file(RELATIVE_PATH LIBCXX_MODULE_RELATIVE_PATH - ${ABS_LIBRARY_DIR} - ${ABS_MODULES_DIR}) + ${CMAKE_INSTALL_PREFIX}/${LIBCXX_INSTALL_LIBRARY_DIR} + ${CMAKE_INSTALL_PREFIX}/${LIBCXX_INSTALL_MODULES_DIR}) configure_file( "modules.json.in" "${LIBCXX_LIBRARY_DIR}/libc++.modules.json" -- GitLab From 12028cb1dab9ba1b4ac826c3d70ca19c3b379255 Mon Sep 17 00:00:00 2001 From: Will Hawkins <hawkinsw@obs.cr> Date: Wed, 20 Mar 2024 12:18:31 -0400 Subject: [PATCH 273/307] [DwarfGenerator] Calculate relative offset according to Dwarf Version (#84847) The relative offset for a CU in Dwarf v5 (and later) is different than the relative offset for a CU in Dwarf v4 (and before). Signed-off-by: Will Hawkins <hawkinsw@obs.cr> --- llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp index c5b9f5cfc0d4..ad5e51b7efb8 100644 --- a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp @@ -568,12 +568,20 @@ StringRef dwarfgen::Generator::generate() { for (auto &CU : CompileUnits) { // Set the absolute .debug_info offset for this compile unit. CU->setOffset(SecOffset); - // The DIEs contain compile unit relative offsets. - unsigned CUOffset = 11; + // The DIEs contain compile unit relative offsets and the offset depends + // on the Dwarf version. + unsigned CUOffset = 4 + // Length + 2 + // Version + 4 + // Abbreviation offset + 1; // Address size + if (Asm->getDwarfVersion() >= 5) + CUOffset += 1; // DW_UT_compile tag. + CUOffset = CU->getUnitDIE().computeSizeAndOffsets(CUOffset); // Update our absolute .debug_info offset. SecOffset += CUOffset; - CU->setLength(CUOffset - 4); + unsigned CUOffsetUnitLength = 4; + CU->setLength(CUOffset - CUOffsetUnitLength); } Abbreviations.Emit(Asm.get(), TLOF->getDwarfAbbrevSection()); -- GitLab From 1b5b4eebb6a012cf223954013d34c6e896720822 Mon Sep 17 00:00:00 2001 From: Thurston Dang <thurston@google.com> Date: Wed, 20 Mar 2024 09:19:20 -0700 Subject: [PATCH 274/307] [memprof] Move allocator base to avoid conflict with high-entropy ASLR (#85834) memprof often fails when ASLR entropy is too high ('sudo sysctl vm.mmap_rnd_bits=32; ninja check-memprof'), which is the default setting for newer versions of Ubuntu (https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/jammy/commit/?h=hwe-6.5-next--2024.03.04-1--auto&id=6b522637c6a7dabd8530026ae933fb5ff17e877f). This patch fixes the issue by moving the allocator base, analogously to ASan (https://reviews.llvm.org/D148280). Explanation from the ASan patch: when CONFIG_ARCH_MMAP_RND_BITS == 32, it will frequently conflict with memprof's allocator, because the PIE program segment base address of 0x555555555554 plus an ASLR shift of up to ((2**32) * 4K == 0x100000000000) will sometimes exceed memprof's hardcoded base address of 0x600000000000. We fix this by simply moving the allocator base to 0x500000000000, which is below the PIE program segment base address. This is cleaner than trying to move it to another location that is sandwiched between the PIE program and library segments, because if either of those grow too large, it will collide with the allocator region. Note that we will never need to change this base address again (unless we want to increase the size of the allocator), because ASLR cannot be set above 32-bits for x86-64 Linux (the PIE program segment and library segments would collide with each other; see also ARCH_MMAP_RND_BITS_MAX in https://github.com/torvalds/linux/blob/master/arch/x86/Kconfig). --- compiler-rt/lib/memprof/memprof_allocator.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler-rt/lib/memprof/memprof_allocator.h b/compiler-rt/lib/memprof/memprof_allocator.h index f583cee020e4..89e924f80d41 100644 --- a/compiler-rt/lib/memprof/memprof_allocator.h +++ b/compiler-rt/lib/memprof/memprof_allocator.h @@ -46,7 +46,11 @@ struct MemprofMapUnmapCallback { void OnUnmap(uptr p, uptr size) const; }; +#if SANITIZER_APPLE constexpr uptr kAllocatorSpace = 0x600000000000ULL; +#else +constexpr uptr kAllocatorSpace = 0x500000000000ULL; +#endif constexpr uptr kAllocatorSize = 0x40000000000ULL; // 4T. typedef DefaultSizeClassMap SizeClassMap; template <typename AddressSpaceViewTy> -- GitLab From a6a6066290679f23f2bd6b27afc7a06aab07590f Mon Sep 17 00:00:00 2001 From: Eric Li <li.zhe.hua@gmail.com> Date: Wed, 20 Mar 2024 12:45:30 -0400 Subject: [PATCH 275/307] [clang][dataflow] Fix crash when analyzing a coroutine (#85957) A coroutine function body (`CoroutineBodyStmt`) may have null children, which causes `isa` to segfault. --- .../lib/Analysis/FlowSensitive/AdornedCFG.cpp | 2 +- .../Analysis/FlowSensitive/TransferTest.cpp | 54 ++++++++++++++++++- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp index 3813b8c3ee8a..daa73bed1bd9 100644 --- a/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp +++ b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp @@ -103,7 +103,7 @@ buildContainsExprConsumedInDifferentBlock( auto CheckChildExprs = [&Result, &StmtToBlock](const Stmt *S, const CFGBlock *Block) { for (const Stmt *Child : S->children()) { - if (!isa<Expr>(Child)) + if (!isa_and_nonnull<Expr>(Child)) continue; const CFGBlock *ChildBlock = StmtToBlock.lookup(Child); if (ChildBlock != Block) diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index a243535d3872..1d3b268976a7 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -37,6 +37,40 @@ using ::testing::Ne; using ::testing::NotNull; using ::testing::UnorderedElementsAre; +// Declares a minimal coroutine library. +constexpr llvm::StringRef CoroutineLibrary = R"cc( +struct promise; +struct task; + +namespace std { +template <class, class...> +struct coroutine_traits {}; +template <> +struct coroutine_traits<task> { + using promise_type = promise; +}; + +template <class Promise = void> +struct coroutine_handle { + static constexpr coroutine_handle from_address(void *addr) { return {}; } +}; +} // namespace std + +struct awaitable { + bool await_ready() const noexcept; + void await_suspend(std::coroutine_handle<promise>) const noexcept; + void await_resume() const noexcept; +}; +struct task {}; +struct promise { + task get_return_object(); + awaitable initial_suspend(); + awaitable final_suspend() noexcept; + void unhandled_exception(); + void return_void(); +}; +)cc"; + void runDataflow( llvm::StringRef Code, std::function< @@ -4607,7 +4641,7 @@ TEST(TransferTest, LoopCanProveInvariantForBoolean) { } TEST(TransferTest, DoesNotCrashOnUnionThisExpr) { - std::string Code = R"( + std::string Code = R"cc( union Union { int A; float B; @@ -4618,7 +4652,7 @@ TEST(TransferTest, DoesNotCrashOnUnionThisExpr) { Union B; A = B; } - )"; + )cc"; // This is a crash regression test when calling the transfer function on a // `CXXThisExpr` that refers to a union. runDataflow( @@ -4628,6 +4662,22 @@ TEST(TransferTest, DoesNotCrashOnUnionThisExpr) { LangStandard::lang_cxx17, /*ApplyBuiltinTransfer=*/true, "operator="); } +TEST(TransferTest, DoesNotCrashOnNullChildren) { + std::string Code = (CoroutineLibrary + R"cc( + task target() noexcept { + co_return; + } + )cc") + .str(); + // This is a crash regression test when calling `AdornedCFG::build` on a + // statement (in this case, the `CoroutineBodyStmt`) with null children. + runDataflow( + Code, + [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &, + ASTContext &) {}, + LangStandard::lang_cxx20, /*ApplyBuiltinTransfer=*/true); +} + TEST(TransferTest, StructuredBindingAssignFromStructIntMembersToRefs) { std::string Code = R"( struct A { -- GitLab From 9cb5004209323d6fa8af8c41e456818c20585984 Mon Sep 17 00:00:00 2001 From: Alexandros Lamprineas <alexandros.lamprineas@arm.com> Date: Wed, 20 Mar 2024 16:49:51 +0000 Subject: [PATCH 276/307] =?UTF-8?q?Reland=20[FMV]=20Emit=20the=20resolver?= =?UTF-8?q?=20along=20with=20the=20default=20version=20definit=E2=80=A6=20?= =?UTF-8?q?(#85923)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …ion. This was reverted because the resolver didn't look as expected in one of the tests. I believe it had some interaction with #84146. I have now regenerated it using -target-feature -fp-armv8. --- clang/lib/CodeGen/CodeGenModule.cpp | 55 +- clang/lib/CodeGen/CodeGenModule.h | 5 + clang/test/CodeGen/attr-target-version.c | 546 ++++++++++++------ clang/test/CodeGenCXX/attr-target-version.cpp | 261 +++++++-- 4 files changed, 629 insertions(+), 238 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index bb26bfcddaeb..cb153066b28d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3449,6 +3449,9 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) { // Implicit template instantiations may change linkage if they are later // explicitly instantiated, so they should not be emitted eagerly. return false; + // Defer until all versions have been semantically checked. + if (FD->hasAttr<TargetVersionAttr>() && !FD->isMultiVersion()) + return false; } if (const auto *VD = dyn_cast<VarDecl>(Global)) { if (Context.getInlineVariableDefinitionKind(VD) == @@ -3997,10 +4000,13 @@ void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD, EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr); // Ensure that the resolver function is also emitted. GetOrCreateMultiVersionResolver(GD); - } else if (FD->hasAttr<TargetVersionAttr>()) { - GetOrCreateMultiVersionResolver(GD); } else EmitGlobalFunctionDefinition(GD, GV); + + // Defer the resolver emission until we can reason whether the TU + // contains a default target version implementation. + if (FD->isTargetVersionMultiVersion()) + AddDeferredMultiVersionResolverToEmit(GD); } void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { @@ -4093,10 +4099,11 @@ void CodeGenModule::emitMultiVersionFunctions() { const auto *FD = cast<FunctionDecl>(GD.getDecl()); assert(FD && "Expected a FunctionDecl"); + bool EmitResolver = !FD->isTargetVersionMultiVersion(); SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options; if (FD->isTargetMultiVersion()) { getContext().forEachMultiversionedFunctionVersion( - FD, [this, &GD, &Options](const FunctionDecl *CurFD) { + FD, [this, &GD, &Options, &EmitResolver](const FunctionDecl *CurFD) { GlobalDecl CurGD{ (CurFD->isDefined() ? CurFD->getDefinition() : CurFD)}; StringRef MangledName = getMangledName(CurGD); @@ -4122,6 +4129,9 @@ void CodeGenModule::emitMultiVersionFunctions() { TA->getArchitecture(), Feats); } else { const auto *TVA = CurFD->getAttr<TargetVersionAttr>(); + if (CurFD->isUsed() || (TVA->isDefaultVersion() && + CurFD->doesThisDeclarationHaveABody())) + EmitResolver = true; llvm::SmallVector<StringRef, 8> Feats; TVA->getFeatures(Feats); Options.emplace_back(cast<llvm::Function>(Func), @@ -4177,22 +4187,27 @@ void CodeGenModule::emitMultiVersionFunctions() { continue; } + if (!EmitResolver) + continue; + llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver(GD); if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) { ResolverConstant = IFunc->getResolver(); if (FD->isTargetClonesMultiVersion() || FD->isTargetVersionMultiVersion()) { - const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); - llvm::FunctionType *DeclTy = getTypes().GetFunctionType(FI); std::string MangledName = getMangledNameImpl( *this, GD, FD, /*OmitMultiVersionMangling=*/true); - // In prior versions of Clang, the mangling for ifuncs incorrectly - // included an .ifunc suffix. This alias is generated for backward - // compatibility. It is deprecated, and may be removed in the future. - auto *Alias = llvm::GlobalAlias::create( - DeclTy, 0, getMultiversionLinkage(*this, GD), - MangledName + ".ifunc", IFunc, &getModule()); - SetCommonAttributes(FD, Alias); + if (!GetGlobalValue(MangledName + ".ifunc")) { + const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); + llvm::FunctionType *DeclTy = getTypes().GetFunctionType(FI); + // In prior versions of Clang, the mangling for ifuncs incorrectly + // included an .ifunc suffix. This alias is generated for backward + // compatibility. It is deprecated, and may be removed in the future. + auto *Alias = llvm::GlobalAlias::create( + DeclTy, 0, getMultiversionLinkage(*this, GD), + MangledName + ".ifunc", IFunc, &getModule()); + SetCommonAttributes(FD, Alias); + } } } llvm::Function *ResolverFunc = cast<llvm::Function>(ResolverConstant); @@ -4349,6 +4364,20 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { } } +/// Adds a declaration to the list of multi version functions if not present. +void CodeGenModule::AddDeferredMultiVersionResolverToEmit(GlobalDecl GD) { + const auto *FD = cast<FunctionDecl>(GD.getDecl()); + assert(FD && "Not a FunctionDecl?"); + + if (FD->isTargetVersionMultiVersion()) { + std::string MangledName = + getMangledNameImpl(*this, GD, FD, /*OmitMultiVersionMangling=*/true); + if (!DeferredResolversToEmit.insert(MangledName).second) + return; + } + MultiVersionFuncs.push_back(GD); +} + /// If a dispatcher for the specified mangled name is not in the module, create /// and return an llvm Function with the specified type. llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { @@ -4388,7 +4417,7 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { // The resolver needs to be created. For target and target_clones, defer // creation until the end of the TU. if (FD->isTargetMultiVersion() || FD->isTargetClonesMultiVersion()) - MultiVersionFuncs.push_back(GD); + AddDeferredMultiVersionResolverToEmit(GD); // For cpu_specific, don't create an ifunc yet because we don't know if the // cpu_dispatch will be emitted in this translation unit. diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index ec34680fd3f7..1cc447765e2c 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -348,6 +348,8 @@ private: /// yet. llvm::DenseMap<StringRef, GlobalDecl> DeferredDecls; + llvm::StringSet<llvm::BumpPtrAllocator> DeferredResolversToEmit; + /// This is a list of deferred decls which we have seen that *are* actually /// referenced. These get code generated when the module is done. std::vector<GlobalDecl> DeferredDeclsToEmit; @@ -1588,6 +1590,9 @@ private: llvm::AttributeList ExtraAttrs = llvm::AttributeList(), ForDefinition_t IsForDefinition = NotForDefinition); + // Adds a declaration to the list of multi version functions if not present. + void AddDeferredMultiVersionResolverToEmit(GlobalDecl GD); + // References to multiversion functions are resolved through an implicitly // defined resolver function. This function is responsible for creating // the resolver symbol for the provided declaration. The value returned diff --git a/clang/test/CodeGen/attr-target-version.c b/clang/test/CodeGen/attr-target-version.c index b7112c783da9..25129605e76c 100644 --- a/clang/test/CodeGen/attr-target-version.c +++ b/clang/test/CodeGen/attr-target-version.c @@ -1,5 +1,5 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals --include-generated-funcs -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +ls64 -target-feature +fullfp16 -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -v9.5a -target-feature -fp-armv8 -S -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fmv -S -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NOFMV int __attribute__((target_version("rng+flagm+fp16fml"))) fmv(void) { return 1; } @@ -11,15 +11,15 @@ int __attribute__((target_version("fp+aes"))) fmv(void) { return 6; } int __attribute__((target_version("crc+ls64_v"))) fmv(void) { return 7; } int __attribute__((target_version("bti"))) fmv(void) { return 8; } int __attribute__((target_version("sme2"))) fmv(void) { return 9; } -int __attribute__((target_version("default"))) fmv(void) { return 0; } +int __attribute__((target_version("default"))) fmv(void); int __attribute__((target_version("ls64+simd"))) fmv_one(void) { return 1; } int __attribute__((target_version("dpb"))) fmv_one(void) { return 2; } -int __attribute__((target_version("default"))) fmv_one(void) { return 0; } +int __attribute__((target_version("default"))) fmv_one(void); int __attribute__((target_version("fp"))) fmv_two(void) { return 1; } int __attribute__((target_version("simd"))) fmv_two(void) { return 2; } int __attribute__((target_version("dgh"))) fmv_two(void) { return 3; } int __attribute__((target_version("fp16+simd"))) fmv_two(void) { return 4; } -int __attribute__((target_version("default"))) fmv_two(void) { return 0; } +int __attribute__((target_version("default"))) fmv_two(void); int foo() { return fmv()+fmv_one()+fmv_two(); } @@ -84,9 +84,33 @@ int hoo(void) { return fp1() + fp2(); } +// This should generate one target version but no resolver. +__attribute__((target_version("default"))) int unused_with_forward_default_decl(void); +__attribute__((target_version("mops"))) int unused_with_forward_default_decl(void) { return 0; } +// This should also generate one target version but no resolver. +extern int unused_with_implicit_extern_forward_default_decl(void); +__attribute__((target_version("dotprod"))) +int unused_with_implicit_extern_forward_default_decl(void) { return 0; } +// This should also generate one target version but no resolver. +__attribute__((target_version("aes"))) int unused_with_default_decl(void) { return 0; } +__attribute__((target_version("default"))) int unused_with_default_decl(void); +// This should generate two target versions and the resolver. +__attribute__((target_version("sve"))) int unused_with_default_def(void) { return 0; } +__attribute__((target_version("default"))) int unused_with_default_def(void) { return 1; } + +// This should also generate two target versions and the resolver. +__attribute__((target_version("fp16"))) int unused_with_implicit_default_def(void) { return 0; } +int unused_with_implicit_default_def(void) { return 1; } + +// This should also generate two target versions and the resolver. +int unused_with_implicit_forward_default_def(void) { return 0; } +__attribute__((target_version("lse"))) int unused_with_implicit_forward_default_def(void) { return 1; } + +// This should generate a normal function. +__attribute__((target_version("rdm"))) int unused_without_default(void) { return 0; } //. // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } @@ -97,38 +121,107 @@ int hoo(void) { // CHECK: @fmv_c.ifunc = weak_odr alias void (), ptr @fmv_c // CHECK: @fmv_inline.ifunc = weak_odr alias i32 (), ptr @fmv_inline // CHECK: @fmv_d.ifunc = internal alias i32 (), ptr @fmv_d +// CHECK: @unused_with_default_def.ifunc = weak_odr alias i32 (), ptr @unused_with_default_def +// CHECK: @unused_with_implicit_default_def.ifunc = weak_odr alias i32 (), ptr @unused_with_implicit_default_def +// CHECK: @unused_with_implicit_forward_default_def.ifunc = weak_odr alias i32 (), ptr @unused_with_implicit_forward_default_def // CHECK: @fmv = weak_odr ifunc i32 (), ptr @fmv.resolver // CHECK: @fmv_one = weak_odr ifunc i32 (), ptr @fmv_one.resolver // CHECK: @fmv_two = weak_odr ifunc i32 (), ptr @fmv_two.resolver -// CHECK: @fmv_e = weak_odr ifunc i32 (), ptr @fmv_e.resolver -// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver // CHECK: @fmv_inline = weak_odr ifunc i32 (), ptr @fmv_inline.resolver +// CHECK: @fmv_e = weak_odr ifunc i32 (), ptr @fmv_e.resolver // CHECK: @fmv_d = internal ifunc i32 (), ptr @fmv_d.resolver +// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver +// CHECK: @unused_with_default_def = weak_odr ifunc i32 (), ptr @unused_with_default_def.resolver +// CHECK: @unused_with_implicit_default_def = weak_odr ifunc i32 (), ptr @unused_with_implicit_default_def.resolver +// CHECK: @unused_with_implicit_forward_default_def = weak_odr ifunc i32 (), ptr @unused_with_implicit_forward_default_def.resolver //. // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MflagmMfp16fmlMrng +// CHECK-LABEL: define {{[^@]+}}@fmv._Mflagm2Msme-i16i64 // CHECK-SAME: () #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 2 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mls64Msimd +// CHECK-LABEL: define {{[^@]+}}@fmv._MlseMsha2 // CHECK-SAME: () #[[ATTR1:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 3 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp -// CHECK-SAME: () #[[ATTR1]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._MdotprodMls64_accdata +// CHECK-SAME: () #[[ATTR2:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 4 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._Mfp16fmlMmemtag +// CHECK-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 5 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._MaesMfp +// CHECK-SAME: () #[[ATTR4:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 6 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._McrcMls64_v +// CHECK-SAME: () #[[ATTR5:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 7 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._Mbti +// CHECK-SAME: () #[[ATTR6:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 8 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._Msme2 +// CHECK-SAME: () #[[ATTR7:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 9 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mdpb +// CHECK-SAME: () #[[ATTR8:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 2 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Msimd +// CHECK-SAME: () #[[ATTR4]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 2 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mdgh +// CHECK-SAME: () #[[ATTR9:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 3 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp16Msimd +// CHECK-SAME: () #[[ATTR10:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 4 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@foo -// CHECK-SAME: () #[[ATTR2:[0-9]+]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv() // CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_one() @@ -158,16 +251,16 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv._Mflagm2Msme-i16i64 // CHECK: resolver_else2: // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 16 -// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16 +// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 9007199254741008 +// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 9007199254741008 // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] // CHECK: resolver_return3: // CHECK-NEXT: ret ptr @fmv._MdotprodMls64_accdata // CHECK: resolver_else4: // CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 1024 -// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 1024 +// CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 4503599627371520 +// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 4503599627371520 // CHECK-NEXT: [[TMP15:%.*]] = and i1 true, [[TMP14]] // CHECK-NEXT: br i1 [[TMP15]], label [[RESOLVER_RETURN5:%.*]], label [[RESOLVER_ELSE6:%.*]] // CHECK: resolver_return5: @@ -182,8 +275,8 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv._Mfp16fmlMmemtag // CHECK: resolver_else8: // CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 16384 -// CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 16384 +// CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 16640 +// CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 16640 // CHECK-NEXT: [[TMP23:%.*]] = and i1 true, [[TMP22]] // CHECK-NEXT: br i1 [[TMP23]], label [[RESOLVER_RETURN9:%.*]], label [[RESOLVER_ELSE10:%.*]] // CHECK: resolver_return9: @@ -218,43 +311,95 @@ int hoo(void) { // // CHECK-LABEL: define {{[^@]+}}@fmv_one.resolver() comdat { // CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2251799813685760 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2251799813685760 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: // CHECK-NEXT: ret ptr @fmv_one._Mls64Msimd +// CHECK: resolver_else: +// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 262144 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 262144 +// CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] +// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] +// CHECK: resolver_return1: +// CHECK-NEXT: ret ptr @fmv_one._Mdpb +// CHECK: resolver_else2: +// CHECK-NEXT: ret ptr @fmv_one.default // // // CHECK-LABEL: define {{[^@]+}}@fmv_two.resolver() comdat { // CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 66048 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 66048 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: // CHECK-NEXT: ret ptr @fmv_two._Mfp16Msimd +// CHECK: resolver_else: +// CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 33554432 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 33554432 +// CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] +// CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] +// CHECK: resolver_return1: +// CHECK-NEXT: ret ptr @fmv_two._Mdgh +// CHECK: resolver_else2: +// CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 512 +// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 512 +// CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] +// CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] +// CHECK: resolver_return3: +// CHECK-NEXT: ret ptr @fmv_two._Msimd +// CHECK: resolver_else4: +// CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 256 +// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 256 +// CHECK-NEXT: [[TMP15:%.*]] = and i1 true, [[TMP14]] +// CHECK-NEXT: br i1 [[TMP15]], label [[RESOLVER_RETURN5:%.*]], label [[RESOLVER_ELSE6:%.*]] +// CHECK: resolver_return5: +// CHECK-NEXT: ret ptr @fmv_two._Mfp +// CHECK: resolver_else6: +// CHECK-NEXT: ret ptr @fmv_two.default // // -// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: ret ptr @fmv_e._Mls64 +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_e.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 20 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 111 // // -// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat { -// CHECK-NEXT: resolver_entry: -// CHECK-NEXT: call void @__init_cpu_features_resolver() -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656 -// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] -// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] -// CHECK: resolver_return: -// CHECK-NEXT: ret ptr @fmv_c._Mssbs -// CHECK: resolver_else: -// CHECK-NEXT: ret ptr @fmv_c.default +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret void +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv_c.default +// CHECK-SAME: () #[[ATTR9]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret void // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@goo -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv_inline() // CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_e() @@ -268,8 +413,8 @@ int hoo(void) { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398048608320 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398048608320 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398048673856 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398048673856 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: @@ -364,8 +509,8 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv_inline._Mdpb2Mjscvt // CHECK: resolver_else22: // CHECK-NEXT: [[TMP48:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP49:%.*]] = and i64 [[TMP48]], 8 -// CHECK-NEXT: [[TMP50:%.*]] = icmp eq i64 [[TMP49]], 8 +// CHECK-NEXT: [[TMP49:%.*]] = and i64 [[TMP48]], 520 +// CHECK-NEXT: [[TMP50:%.*]] = icmp eq i64 [[TMP49]], 520 // CHECK-NEXT: [[TMP51:%.*]] = and i1 true, [[TMP50]] // CHECK-NEXT: br i1 [[TMP51]], label [[RESOLVER_RETURN23:%.*]], label [[RESOLVER_ELSE24:%.*]] // CHECK: resolver_return23: @@ -388,8 +533,8 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv_inline._MlseMrdm // CHECK: resolver_else28: // CHECK-NEXT: [[TMP60:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP61:%.*]] = and i64 [[TMP60]], 32 -// CHECK-NEXT: [[TMP62:%.*]] = icmp eq i64 [[TMP61]], 32 +// CHECK-NEXT: [[TMP61:%.*]] = and i64 [[TMP60]], 288 +// CHECK-NEXT: [[TMP62:%.*]] = icmp eq i64 [[TMP61]], 288 // CHECK-NEXT: [[TMP63:%.*]] = and i1 true, [[TMP62]] // CHECK-NEXT: br i1 [[TMP63]], label [[RESOLVER_RETURN29:%.*]], label [[RESOLVER_ELSE30:%.*]] // CHECK: resolver_return29: @@ -398,6 +543,20 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv_inline.default // // +// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2251799813685248 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2251799813685248 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @fmv_e._Mls64 +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @fmv_e.default +// +// // CHECK-LABEL: define {{[^@]+}}@fmv_d.resolver() { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -412,9 +571,23 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv_d.default // // +// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @fmv_c._Mssbs +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @fmv_c.default +// +// // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@recur -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: call void @reca() // CHECK-NEXT: ret void @@ -422,7 +595,7 @@ int hoo(void) { // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@main -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 @@ -433,7 +606,7 @@ int hoo(void) { // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@hoo -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FP1:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[FP2:%.*]] = alloca ptr, align 8 @@ -449,288 +622,274 @@ int hoo(void) { // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Mflagm2Msme-i16i64 -// CHECK-SAME: () #[[ATTR4:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MlseMsha2 -// CHECK-SAME: () #[[ATTR5:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 3 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MdotprodMls64_accdata -// CHECK-SAME: () #[[ATTR6:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 4 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Mfp16fmlMmemtag -// CHECK-SAME: () #[[ATTR7:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 5 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._MaesMfp -// CHECK-SAME: () #[[ATTR1]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_forward_default_decl._Mmops +// CHECK-SAME: () #[[ATTR12:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 6 +// CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._McrcMls64_v -// CHECK-SAME: () #[[ATTR8:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_extern_forward_default_decl._Mdotprod +// CHECK-SAME: () #[[ATTR13:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 7 +// CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Mbti -// CHECK-SAME: () #[[ATTR9:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def.default +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 8 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv._Msme2 -// CHECK-SAME: () #[[ATTR10:[0-9]+]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def.default +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 9 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def.default +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mdpb -// CHECK-SAME: () #[[ATTR11:[0-9]+]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 -// -// -// CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_one.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def._Mlse +// CHECK-SAME: () #[[ATTR14:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 0 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Msimd -// CHECK-SAME: () #[[ATTR1]] { +// CHECK-LABEL: define {{[^@]+}}@fmv._MflagmMfp16fmlMrng +// CHECK-SAME: () #[[ATTR15:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 2 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mdgh -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_one._Mls64Msimd +// CHECK-SAME: () #[[ATTR4]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 3 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp16Msimd -// CHECK-SAME: () #[[ATTR1]] { +// CHECK-LABEL: define {{[^@]+}}@fmv_two._Mfp +// CHECK-SAME: () #[[ATTR4]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 4 +// CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_two.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_decl._Maes +// CHECK-SAME: () #[[ATTR4]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_e.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def._Msve +// CHECK-SAME: () #[[ATTR16:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 20 +// CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_c.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def._Mfp16 +// CHECK-SAME: () #[[ATTR10]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret void +// CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone -// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-LABEL: define {{[^@]+}}@unused_without_default +// CHECK-SAME: () #[[ATTR17:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: ret void +// CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mf64mmMpmullMsha1 -// CHECK-SAME: () #[[ATTR12:[0-9]+]] { +// CHECK-SAME: () #[[ATTR18:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 1 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfcmaMfp16MrdmMsme -// CHECK-SAME: () #[[ATTR13:[0-9]+]] { +// CHECK-SAME: () #[[ATTR19:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 2 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mf32mmMi8mmMsha3 -// CHECK-SAME: () #[[ATTR14:[0-9]+]] { +// CHECK-SAME: () #[[ATTR20:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 12 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MditMsve-ebf16 -// CHECK-SAME: () #[[ATTR15:[0-9]+]] { +// CHECK-SAME: () #[[ATTR21:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 8 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MdpbMrcpc2 -// CHECK-SAME: () #[[ATTR16:[0-9]+]] { +// CHECK-SAME: () #[[ATTR22:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 6 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mdpb2Mjscvt -// CHECK-SAME: () #[[ATTR17:[0-9]+]] { +// CHECK-SAME: () #[[ATTR23:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 7 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfrinttsMrcpc -// CHECK-SAME: () #[[ATTR18:[0-9]+]] { +// CHECK-SAME: () #[[ATTR24:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 3 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MsveMsve-bf16 -// CHECK-SAME: () #[[ATTR19:[0-9]+]] { +// CHECK-SAME: () #[[ATTR25:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 4 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Msve2-aesMsve2-sha3 -// CHECK-SAME: () #[[ATTR20:[0-9]+]] { +// CHECK-SAME: () #[[ATTR26:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 5 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Msve2Msve2-bitpermMsve2-pmull128 -// CHECK-SAME: () #[[ATTR21:[0-9]+]] { +// CHECK-SAME: () #[[ATTR27:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 9 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mmemtag2Msve2-sm4 -// CHECK-SAME: () #[[ATTR22:[0-9]+]] { +// CHECK-SAME: () #[[ATTR28:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 10 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mmemtag3MmopsMrcpc3 -// CHECK-SAME: () #[[ATTR23:[0-9]+]] { +// CHECK-SAME: () #[[ATTR29:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 11 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MaesMdotprod -// CHECK-SAME: () #[[ATTR6]] { +// CHECK-SAME: () #[[ATTR13]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 13 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._Mfp16fmlMsimd -// CHECK-SAME: () #[[ATTR7]] { +// CHECK-SAME: () #[[ATTR3]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 14 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MfpMsm4 -// CHECK-SAME: () #[[ATTR24:[0-9]+]] { +// CHECK-SAME: () #[[ATTR30:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 15 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline._MlseMrdm -// CHECK-SAME: () #[[ATTR25:[0-9]+]] { +// CHECK-SAME: () #[[ATTR31:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 16 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_inline.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 3 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_d._Msb -// CHECK-SAME: () #[[ATTR26:[0-9]+]] { +// CHECK-SAME: () #[[ATTR32:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 0 // // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@fmv_d.default -// CHECK-SAME: () #[[ATTR2]] { +// CHECK-SAME: () #[[ATTR9]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 1 // // -// CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv -// CHECK-NOFMV-SAME: () #[[ATTR0:[0-9]+]] { -// CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 0 +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @unused_with_default_def._Msve +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @unused_with_default_def.default // // -// CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_one -// CHECK-NOFMV-SAME: () #[[ATTR0]] { -// CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 0 +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65536 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65536 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @unused_with_implicit_default_def._Mfp16 +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @unused_with_implicit_default_def.default // // -// CHECK-NOFMV: Function Attrs: noinline nounwind optnone -// CHECK-NOFMV-LABEL: define {{[^@]+}}@fmv_two -// CHECK-NOFMV-SAME: () #[[ATTR0]] { -// CHECK-NOFMV-NEXT: entry: -// CHECK-NOFMV-NEXT: ret i32 0 +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def.resolver() comdat { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 128 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 128 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @unused_with_implicit_forward_default_def._Mlse +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @unused_with_implicit_forward_default_def.default // // // CHECK-NOFMV: Function Attrs: noinline nounwind optnone // CHECK-NOFMV-LABEL: define {{[^@]+}}@foo -// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-SAME: () #[[ATTR0:[0-9]+]] { // CHECK-NOFMV-NEXT: entry: // CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 @fmv() // CHECK-NOFMV-NEXT: [[CALL1:%.*]] = call i32 @fmv_one() @@ -815,34 +974,61 @@ int hoo(void) { // CHECK-NOFMV-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] // CHECK-NOFMV-NEXT: ret i32 [[ADD]] // +// +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_default_def +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 1 +// +// +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_implicit_default_def +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 1 +// +// +// CHECK-NOFMV: Function Attrs: noinline nounwind optnone +// CHECK-NOFMV-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def +// CHECK-NOFMV-SAME: () #[[ATTR0]] { +// CHECK-NOFMV-NEXT: entry: +// CHECK-NOFMV-NEXT: ret i32 0 +// //. -// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+flagm,+fp-armv8,+fp16fml,+fullfp16,+ls64,+neon,+rand" } -// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon" } -// CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } -// CHECK: attributes #[[ATTR3:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } -// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+altnzcv,+bf16,+flagm,+fullfp16,+ls64,+sme,+sme-i16i64" } -// CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+lse,+neon,+sha2" } -// CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+fullfp16,+ls64,+neon" } -// CHECK: attributes #[[ATTR7]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fp16fml,+fullfp16,+ls64,+neon" } -// CHECK: attributes #[[ATTR8]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,+fullfp16,+ls64" } -// CHECK: attributes #[[ATTR9]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti,+fullfp16,+ls64" } -// CHECK: attributes #[[ATTR10]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fullfp16,+ls64,+sme,+sme2" } -// CHECK: attributes #[[ATTR11]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+fullfp16,+ls64" } -// CHECK: attributes #[[ATTR12]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+aes,+f64mm,+fp-armv8,+fullfp16,+ls64,+neon,+sve" } -// CHECK: attributes #[[ATTR13]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+complxnum,+fp-armv8,+fullfp16,+ls64,+neon,+rdm,+sme" } -// CHECK: attributes #[[ATTR14]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+f32mm,+fp-armv8,+fullfp16,+i8mm,+ls64,+neon,+sha2,+sha3,+sve" } -// CHECK: attributes #[[ATTR15]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+dit,+fp-armv8,+fullfp16,+ls64,+neon,+sve" } -// CHECK: attributes #[[ATTR16]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+fullfp16,+ls64,+rcpc" } -// CHECK: attributes #[[ATTR17]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccdp,+ccpp,+fp-armv8,+fullfp16,+jsconv,+ls64,+neon" } -// CHECK: attributes #[[ATTR18]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint,+fullfp16,+ls64,+rcpc" } -// CHECK: attributes #[[ATTR19]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+fullfp16,+ls64,+neon,+sve" } -// CHECK: attributes #[[ATTR20]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon,+sve,+sve2,+sve2-aes,+sve2-sha3" } -// CHECK: attributes #[[ATTR21]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon,+sve,+sve2,+sve2-aes,+sve2-bitperm" } -// CHECK: attributes #[[ATTR22]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+mte,+neon,+sve,+sve2,+sve2-sm4" } -// CHECK: attributes #[[ATTR23]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64,+mops,+mte,+rcpc,+rcpc3" } -// CHECK: attributes #[[ATTR24]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon,+sm4" } -// CHECK: attributes #[[ATTR25]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+lse,+neon,+rdm" } -// CHECK: attributes #[[ATTR26]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64,+sb" } +// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+altnzcv,+bf16,+flagm,+sme,+sme-i16i64,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,+neon,+sha2,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+ls64,+neon,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR3]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp16fml,+fullfp16,+neon,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+neon,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR7]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme2,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR8]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR9]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR10]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+neon,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR11:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR12]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR13]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+neon,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR14]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR15]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+flagm,+fp16fml,+fullfp16,+neon,+rand,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR16]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+neon,+sve,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR17]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+neon,+rdm,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR18]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+aes,+f64mm,+fullfp16,+neon,+sve,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR19]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+complxnum,+fullfp16,+neon,+rdm,+sme,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR20]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+f32mm,+fullfp16,+i8mm,+neon,+sha2,+sha3,+sve,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR21]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+dit,+fullfp16,+neon,+sve,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR22]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+rcpc,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR23]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccdp,+ccpp,+jsconv,+neon,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR24]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint,+rcpc,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR25]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fullfp16,+neon,+sve,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR26]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+neon,+sve,+sve2,+sve2-aes,+sve2-sha3,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR27]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+neon,+sve,+sve2,+sve2-aes,+sve2-bitperm,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR28]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+mte,+neon,+sve,+sve2,+sve2-sm4,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR29]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops,+mte,+rcpc,+rcpc3,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR30]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+neon,+sm4,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR31]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,+neon,+rdm,-fp-armv8,-v9.5a" } +// CHECK: attributes #[[ATTR32]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+sb,-fp-armv8,-v9.5a" } //. // CHECK-NOFMV: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" } // CHECK-NOFMV: attributes #[[ATTR1:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" } diff --git a/clang/test/CodeGenCXX/attr-target-version.cpp b/clang/test/CodeGenCXX/attr-target-version.cpp index 82a928a385e1..e06121d1a719 100644 --- a/clang/test/CodeGenCXX/attr-target-version.cpp +++ b/clang/test/CodeGenCXX/attr-target-version.cpp @@ -10,41 +10,196 @@ struct MyClass { int __attribute__((target_version("dotprod"))) goo(int); int __attribute__((target_version("crc"))) goo(int); int __attribute__((target_version("default"))) goo(int); + + // This should generate one target version but no resolver. + int __attribute__((target_version("default"))) unused_with_forward_default_decl(void); + int __attribute__((target_version("mops"))) unused_with_forward_default_decl(void); + + // This should also generate one target version but no resolver. + int unused_with_implicit_forward_default_decl(void); + int __attribute__((target_version("dotprod"))) unused_with_implicit_forward_default_decl(void); + + // This should also generate one target version but no resolver. + int __attribute__((target_version("aes"))) unused_with_default_decl(void); + int __attribute__((target_version("default"))) unused_with_default_decl(void); + + // This should generate two target versions and the resolver. + int __attribute__((target_version("sve"))) unused_with_default_def(void); + int __attribute__((target_version("default"))) unused_with_default_def(void); + + // This should also generate two target versions and the resolver. + int __attribute__((target_version("fp16"))) unused_with_implicit_default_def(void); + int unused_with_implicit_default_def(void); + + // This should also generate two target versions and the resolver. + int unused_with_implicit_forward_default_def(void); + int __attribute__((target_version("lse"))) unused_with_implicit_forward_default_def(void); + + // This should generate a normal function. + int __attribute__((target_version("rdm"))) unused_without_default(void); }; int __attribute__((target_version("default"))) MyClass::goo(int) { return 1; } int __attribute__((target_version("crc"))) MyClass::goo(int) { return 2; } int __attribute__((target_version("dotprod"))) MyClass::goo(int) { return 3; } +int __attribute__((target_version("mops"))) MyClass::unused_with_forward_default_decl(void) { return 0; } +int __attribute__((target_version("dotprod"))) MyClass::unused_with_implicit_forward_default_decl(void) { return 0; } +int __attribute__((target_version("aes"))) MyClass::unused_with_default_decl(void) { return 0; } +int __attribute__((target_version("sve"))) MyClass::unused_with_default_def(void) { return 0; } +int __attribute__((target_version("default"))) MyClass::unused_with_default_def(void) { return 1; } +int __attribute__((target_version("fp16"))) MyClass::unused_with_implicit_default_def(void) { return 0; } +int MyClass::unused_with_implicit_default_def(void) { return 1; } +int MyClass::unused_with_implicit_forward_default_def(void) { return 0; } +int __attribute__((target_version("lse"))) MyClass::unused_with_implicit_forward_default_def(void) { return 1; } +int __attribute__((target_version("rdm"))) MyClass::unused_without_default(void) { return 0; } + int bar() { MyClass m; return m.goo(1) + foo(1) + foo(); } - - //. // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } -// CHECK: @_ZN7MyClass3gooEi.ifunc = weak_odr alias i32 (ptr, i32), ptr @_ZN7MyClass3gooEi // CHECK: @_Z3fooi.ifunc = weak_odr alias i32 (i32), ptr @_Z3fooi // CHECK: @_Z3foov.ifunc = weak_odr alias i32 (), ptr @_Z3foov +// CHECK: @_ZN7MyClass3gooEi.ifunc = weak_odr alias i32 (ptr, i32), ptr @_ZN7MyClass3gooEi +// CHECK: @_ZN7MyClass23unused_with_default_defEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN7MyClass23unused_with_default_defEv +// CHECK: @_ZN7MyClass32unused_with_implicit_default_defEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN7MyClass32unused_with_implicit_default_defEv +// CHECK: @_ZN7MyClass40unused_with_implicit_forward_default_defEv.ifunc = weak_odr alias i32 (ptr), ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv // CHECK: @_ZN7MyClass3gooEi = weak_odr ifunc i32 (ptr, i32), ptr @_ZN7MyClass3gooEi.resolver // CHECK: @_Z3fooi = weak_odr ifunc i32 (i32), ptr @_Z3fooi.resolver // CHECK: @_Z3foov = weak_odr ifunc i32 (), ptr @_Z3foov.resolver +// CHECK: @_ZN7MyClass23unused_with_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass23unused_with_default_defEv.resolver +// CHECK: @_ZN7MyClass32unused_with_implicit_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass32unused_with_implicit_default_defEv.resolver +// CHECK: @_ZN7MyClass40unused_with_implicit_forward_default_defEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver //. -// CHECK-LABEL: @_Z3fooi._Mbf16Msme-f64f64( +// CHECK-LABEL: @_Z3fooi.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: ret i32 2 +// +// +// CHECK-LABEL: @_Z3foov.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 4 +// +// +// CHECK-LABEL: @_ZN7MyClass3gooEi.default( // CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_Z3foov._Mebf16Msm4( +// CHECK-LABEL: @_ZN7MyClass3gooEi._Mcrc( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 2 +// +// +// CHECK-LABEL: @_ZN7MyClass3gooEi._Mdotprod( // CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: ret i32 3 // // +// CHECK-LABEL: @_ZN7MyClass32unused_with_forward_default_declEv._Mmops( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass41unused_with_implicit_forward_default_declEv._Mdotprod( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass24unused_with_default_declEv._Maes( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv._Msve( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 1 +// +// +// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv._Mfp16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 1 +// +// +// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv.default( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv._Mlse( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: ret i32 1 +// +// +// CHECK-LABEL: @_Z3barv( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[M:%.*]] = alloca [[STRUCT_MYCLASS:%.*]], align 1 +// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN7MyClass3gooEi(ptr noundef nonnull align 1 dereferenceable(1) [[M]], i32 noundef 1) +// CHECK-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z3fooi(i32 noundef 1) +// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] +// CHECK-NEXT: [[CALL2:%.*]] = call noundef i32 @_Z3foov() +// CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]] +// CHECK-NEXT: ret i32 [[ADD3]] +// +// // CHECK-LABEL: @_ZN7MyClass3gooEi.resolver( // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -67,17 +222,6 @@ int bar() { // CHECK-NEXT: ret ptr @_ZN7MyClass3gooEi.default // // -// CHECK-LABEL: @_Z3barv( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[M:%.*]] = alloca [[STRUCT_MYCLASS:%.*]], align 1 -// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN7MyClass3gooEi(ptr noundef nonnull align 1 dereferenceable(1) [[M]], i32 noundef 1) -// CHECK-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z3fooi(i32 noundef 1) -// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] -// CHECK-NEXT: [[CALL2:%.*]] = call noundef i32 @_Z3foov() -// CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]] -// CHECK-NEXT: ret i32 [[ADD3]] -// -// // CHECK-LABEL: @_Z3fooi.resolver( // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() @@ -106,53 +250,80 @@ int bar() { // CHECK-NEXT: ret ptr @_Z3foov.default // // -// CHECK-LABEL: @_ZN7MyClass3gooEi._Mdotprod( +// CHECK-LABEL: @_Z3fooi._Mbf16Msme-f64f64( // CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 // CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 3 +// CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: @_ZN7MyClass3gooEi._Mcrc( +// CHECK-LABEL: @_Z3foov._Mebf16Msm4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 -// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 2 +// CHECK-NEXT: ret i32 3 // // -// CHECK-LABEL: @_ZN7MyClass3gooEi.default( +// CHECK-LABEL: @_ZN7MyClass22unused_without_defaultEv( // CHECK-NEXT: entry: // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 // CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-NEXT: ret i32 1 +// CHECK-NEXT: ret i32 0 // // -// CHECK-LABEL: @_Z3fooi.default( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[DOTADDR]], align 4 -// CHECK-NEXT: ret i32 2 +// CHECK-LABEL: @_ZN7MyClass23unused_with_default_defEv.resolver( +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @_ZN7MyClass23unused_with_default_defEv._Msve +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @_ZN7MyClass23unused_with_default_defEv.default // // -// CHECK-LABEL: @_Z3foov.default( -// CHECK-NEXT: entry: -// CHECK-NEXT: ret i32 4 +// CHECK-LABEL: @_ZN7MyClass32unused_with_implicit_default_defEv.resolver( +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65536 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65536 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @_ZN7MyClass32unused_with_implicit_default_defEv._Mfp16 +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @_ZN7MyClass32unused_with_implicit_default_defEv.default +// +// +// CHECK-LABEL: @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver( +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 128 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 128 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv._Mlse +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.default // //. -// CHECK: attributes #[[ATTR0:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } -// CHECK: attributes #[[ATTR1:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+neon,+sm4" } -// CHECK: attributes #[[ATTR2:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -// CHECK: attributes #[[ATTR3:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon" } -// CHECK: attributes #[[ATTR4:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc" } +// CHECK: attributes #[[ATTR0:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR1:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc" } +// CHECK: attributes #[[ATTR2:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon" } +// CHECK: attributes #[[ATTR3:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops" } +// CHECK: attributes #[[ATTR4:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon" } +// CHECK: attributes #[[ATTR5:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } +// CHECK: attributes #[[ATTR6:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" } +// CHECK: attributes #[[ATTR7:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse" } +// CHECK: attributes #[[ATTR8:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } +// CHECK: attributes #[[ATTR9:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+neon,+sm4" } +// CHECK: attributes #[[ATTR10:[0-9]+]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm" } +// CHECK: attributes #[[ATTR11:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} -- GitLab From 0e47dfede468a292dd8cd893d6d0179052501383 Mon Sep 17 00:00:00 2001 From: Fangrui Song <i@maskray.me> Date: Wed, 20 Mar 2024 09:58:56 -0700 Subject: [PATCH 277/307] [ELF] Add isStaticRelSecType to simplify SHT_REL/SHT_RELA testing. NFC and make it easier to introduce a new relocation format. https://discourse.llvm.org/t/rfc-relleb-a-compact-relocation-format-for-elf/77600 Pull Request: https://github.com/llvm/llvm-project/pull/85893 --- lld/ELF/InputFiles.cpp | 4 ++-- lld/ELF/InputSection.cpp | 2 +- lld/ELF/InputSection.h | 4 ++++ lld/ELF/LinkerScript.cpp | 7 +++---- lld/ELF/MarkLive.cpp | 3 +-- lld/ELF/OutputSections.cpp | 4 ++-- lld/ELF/Writer.cpp | 8 ++++---- 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 4a6e691938cf..4c614c865d24 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -835,7 +835,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats, // We have a second loop. It is used to: // 1) handle SHF_LINK_ORDER sections. - // 2) create SHT_REL[A] sections. In some cases the section header index of a + // 2) create relocation sections. In some cases the section header index of a // relocation section may be smaller than that of the relocated section. In // such cases, the relocation section would attempt to reference a target // section that has not yet been created. For simplicity, delay creation of @@ -845,7 +845,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats, continue; const Elf_Shdr &sec = objSections[i]; - if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA) { + if (isStaticRelSecType(sec.sh_type)) { // Find a relocation target section and associate this section with that. // Target may have been discarded if it is in a different section group // and the group is discarded, even though it's a violation of the spec. diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 082e840adde4..c34bf08757b1 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -348,7 +348,7 @@ template <class ELFT> void InputSection::copyShtGroup(uint8_t *buf) { } InputSectionBase *InputSection::getRelocatedSection() const { - if (file->isInternal() || (type != SHT_RELA && type != SHT_REL)) + if (file->isInternal() || !isStaticRelSecType(type)) return nullptr; ArrayRef<InputSectionBase *> sections = file->getSections(); return sections[info]; diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index b8af962877b4..1fb7077ca435 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -448,6 +448,10 @@ public: } }; +inline bool isStaticRelSecType(uint32_t type) { + return type == llvm::ELF::SHT_RELA || type == llvm::ELF::SHT_REL; +} + inline bool isDebugSection(const InputSectionBase &sec) { return (sec.flags & llvm::ELF::SHF_ALLOC) == 0 && sec.name.starts_with(".debug"); diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 9e7647f63ca5..3af09a32b651 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -740,13 +740,12 @@ static OutputDesc *addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map, // should combine these relocation sections into single output. // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any // other REL[A] sections created by linker itself. - if (!isa<SyntheticSection>(isec) && - (isec->type == SHT_REL || isec->type == SHT_RELA)) { + if (!isa<SyntheticSection>(isec) && isStaticRelSecType(isec->type)) { auto *sec = cast<InputSection>(isec); OutputSection *out = sec->getRelocatedSection()->getOutputSection(); - if (out->relocationSection) { - out->relocationSection->recordSection(sec); + if (auto *relSec = out->relocationSection) { + relSec->recordSection(sec); return nullptr; } diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index 93c66e81d2fa..45431e44a6c8 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -276,8 +276,7 @@ template <class ELFT> void MarkLive<ELFT>::run() { // collection. // - Groups members are retained or discarded as a unit. if (!(sec->flags & SHF_ALLOC)) { - bool isRel = sec->type == SHT_REL || sec->type == SHT_RELA; - if (!isRel && !sec->nextInSectionGroup) { + if (!isStaticRelSecType(sec->type) && !sec->nextInSectionGroup) { sec->markLive(); for (InputSection *isec : sec->dependentSections) isec->markLive(); diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index f986aa5f6757..eadab9d745d6 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -615,7 +615,7 @@ void OutputSection::finalize() { return; } - if (!config->copyRelocs || (type != SHT_RELA && type != SHT_REL)) + if (!config->copyRelocs || !isStaticRelSecType(type)) return; // Skip if 'first' is synthetic, i.e. not a section created by --emit-relocs. @@ -750,7 +750,7 @@ std::array<uint8_t, 4> OutputSection::getFiller() { void OutputSection::checkDynRelAddends(const uint8_t *bufStart) { assert(config->writeAddends && config->checkDynamicRelocs); - assert(type == SHT_REL || type == SHT_RELA); + assert(isStaticRelSecType(type)); SmallVector<InputSection *, 0> storage; ArrayRef<InputSection *> sections = getInputSections(*this, storage); parallelFor(0, sections.size(), [&](size_t i) { diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index d8782affe879..4eca7b22e90b 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -796,7 +796,7 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() { continue; for (InputSectionBase *s : isd->sections) { // Relocations are not using REL[A] section symbols. - if (s->type == SHT_REL || s->type == SHT_RELA) + if (isStaticRelSecType(s->type)) continue; // Unlike other synthetic sections, mergeable output sections contain @@ -3045,20 +3045,20 @@ template <class ELFT> void Writer<ELFT>::writeSections() { // section while doing it. parallel::TaskGroup tg; for (OutputSection *sec : outputSections) - if (sec->type == SHT_REL || sec->type == SHT_RELA) + if (isStaticRelSecType(sec->type)) sec->writeTo<ELFT>(Out::bufferStart + sec->offset, tg); } { parallel::TaskGroup tg; for (OutputSection *sec : outputSections) - if (sec->type != SHT_REL && sec->type != SHT_RELA) + if (!isStaticRelSecType(sec->type)) sec->writeTo<ELFT>(Out::bufferStart + sec->offset, tg); } // Finally, check that all dynamic relocation addends were written correctly. if (config->checkDynamicRelocs && config->writeAddends) { for (OutputSection *sec : outputSections) - if (sec->type == SHT_REL || sec->type == SHT_RELA) + if (isStaticRelSecType(sec->type)) sec->checkDynRelAddends(Out::bufferStart); } } -- GitLab From 25d61be8a5e563988661709c5d01f67c06b388e2 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <llvm-dev@redking.me.uk> Date: Wed, 20 Mar 2024 16:59:01 +0000 Subject: [PATCH 278/307] [X86] avx-shuffle-builtins.c - limit to x86 targets Attempt to fix issue with non-x86 buildbots (sorry its blind but I can't test this) --- clang/test/CodeGen/X86/avx-shuffle-builtins.c | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/test/CodeGen/X86/avx-shuffle-builtins.c b/clang/test/CodeGen/X86/avx-shuffle-builtins.c index 82be43bc0504..49a56e73230d 100644 --- a/clang/test/CodeGen/X86/avx-shuffle-builtins.c +++ b/clang/test/CodeGen/X86/avx-shuffle-builtins.c @@ -1,3 +1,4 @@ +// REQUIRES: x86-registered-target // RUN: %clang_cc1 -ffreestanding %s -O3 -triple=x86_64-apple-darwin -target-feature +avx -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,X64 // RUN: %clang_cc1 -ffreestanding %s -O3 -triple=i386-apple-darwin -target-feature +avx -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,X86 // FIXME: This is testing optimized generation of shuffle instructions and should be fixed. -- GitLab From decd88ef0538504707c5d1f0fd8b9de60a5b9b4c Mon Sep 17 00:00:00 2001 From: Stephen Tozer <stephen.tozer@sony.com> Date: Wed, 20 Mar 2024 16:01:54 +0000 Subject: [PATCH 279/307] [RemoveDIs][NFC] Delete a now-redundant comment Submitted without review for being a trivial comment-only change, deletes a line that requests the DbgLabelRecord class be renamed to DbgLabelRecord in the future. --- llvm/include/llvm/IR/DebugProgramInstruction.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h index 7214d7ad65da..c9477131c09c 100644 --- a/llvm/include/llvm/IR/DebugProgramInstruction.h +++ b/llvm/include/llvm/IR/DebugProgramInstruction.h @@ -220,8 +220,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DbgRecord &R) { /// Records a position in IR for a source label (DILabel). Corresponds to the /// llvm.dbg.label intrinsic. -/// FIXME: Rename DbgLabelRecord when DbgVariableRecord is renamed to -/// DbgVariableRecord. class DbgLabelRecord : public DbgRecord { DbgRecordParamRef<DILabel> Label; -- GitLab From b754e6f6900e8c4205567fb2a13ff3c90811f5bc Mon Sep 17 00:00:00 2001 From: Job Henandez Lara <jobhdezlara93@gmail.com> Date: Wed, 20 Mar 2024 10:13:45 -0700 Subject: [PATCH 280/307] Fix typo (#85869) --- libc/test/src/math/smoke/FMaxTest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/test/src/math/smoke/FMaxTest.h b/libc/test/src/math/smoke/FMaxTest.h index 98fae06ee2a0..b8781a85d10f 100644 --- a/libc/test/src/math/smoke/FMaxTest.h +++ b/libc/test/src/math/smoke/FMaxTest.h @@ -1,4 +1,4 @@ -//===-- Utility class to test fmin[f|l] -------------------------*- C++ -*-===// +//===-- Utility class to test fmax[f|l] -------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. -- GitLab From b20360abeb3a80281dc082f1e093abd13cb1ee4c Mon Sep 17 00:00:00 2001 From: AdityaK <hiraditya@msn.com> Date: Wed, 20 Mar 2024 10:15:23 -0700 Subject: [PATCH 281/307] clang driver: enable fast unaligned access for Android on RISCV64 (#85704) Android CTS test already requires fast unaligned access https://android-review.googlesource.com/c/platform/cts/+/2675633 --- clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 4 ++++ clang/test/Driver/riscv-features.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index 5165bccc6d7e..b1dd7c4372d4 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -167,6 +167,10 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, Features.push_back("-relax"); } + // Android requires fast unaligned access on RISCV64. + if (Triple.isAndroid()) + Features.push_back("+fast-unaligned-access"); + // -mstrict-align is default, unless -mno-strict-align is specified. AddTargetFeature(Args, Features, options::OPT_mno_strict_align, options::OPT_mstrict_align, "fast-unaligned-access"); diff --git a/clang/test/Driver/riscv-features.c b/clang/test/Driver/riscv-features.c index fe74ac773ef8..052956dfa2dc 100644 --- a/clang/test/Driver/riscv-features.c +++ b/clang/test/Driver/riscv-features.c @@ -1,7 +1,9 @@ // RUN: %clang --target=riscv32-unknown-elf -### %s -fsyntax-only 2>&1 | FileCheck %s // RUN: %clang --target=riscv64-unknown-elf -### %s -fsyntax-only 2>&1 | FileCheck %s -// RUN: %clang --target=riscv64-linux-android -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ANDROID,DEFAULT -// RUN: %clang -mabi=lp64d --target=riscv64-linux-android -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ANDROID,DEFAULT +// RUN: %clang --target=riscv64-linux-android -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ANDROID,DEFAULT,FAST-UNALIGNED-ACCESS +// RUN: %clang -mabi=lp64d --target=riscv64-linux-android -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=ANDROID,DEFAULT,FAST-UNALIGNED-ACCESS +// RUN: %clang -mabi=lp64d --target=riscv64-linux-android -mstrict-align -### %s -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=NO-FAST-UNALIGNED-ACCESS + // CHECK: fno-signed-char -- GitLab From 721e8f366f8665468f69dd8e29f97c6da1614a8f Mon Sep 17 00:00:00 2001 From: Fangrui Song <i@maskray.me> Date: Wed, 20 Mar 2024 10:26:15 -0700 Subject: [PATCH 282/307] [ELF] Improve unknown -z test --- lld/test/ELF/driver.test | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lld/test/ELF/driver.test b/lld/test/ELF/driver.test index 260be8e8f883..b8f4584a3267 100644 --- a/lld/test/ELF/driver.test +++ b/lld/test/ELF/driver.test @@ -53,12 +53,13 @@ # RUN: not ld.lld %t -output=/no/such/file 2>&1 | FileCheck -check-prefix=ERR9 %s # ERR9: cannot open output file utput=/no/such/file -# RUN: ld.lld %t -z foo -o /dev/null 2>&1 | FileCheck -check-prefix=ERR10 %s -# RUN: ld.lld %t -z foo -o /dev/null --version 2>&1 | FileCheck -check-prefix=ERR10 %s +# RUN: ld.lld %t -z foo -o /dev/null 2>&1 | FileCheck -check-prefix=ERR10 %s --implicit-check-not=warning: +# RUN: ld.lld %t -z foo -z rel -z rela -z max-page-size=1 -z common-page-size=1 -o /dev/null --version 2>&1 | \ +# RUN: FileCheck -check-prefix=ERR10 %s --implicit-check-not=warning: # ERR10: warning: unknown -z value: foo ## Check we report "unknown -z value" error even with -v. -# RUN: ld.lld %t -z foo -o /dev/null -v 2>&1 | FileCheck -check-prefix=ERR10 %s +# RUN: ld.lld %t -z foo -z rel -o /dev/null -v 2>&1 | FileCheck -check-prefix=ERR10 %s --implicit-check-not=warning: ## Note: in GNU ld, --fatal-warning still leads to a warning. # RUN: not ld.lld %t -z foo --fatal-warnings 2>&1 | FileCheck --check-prefix=ERR10-FATAL %s -- GitLab From 49c3e78961f841717c0aeec0c04b6e5401ddd6ce Mon Sep 17 00:00:00 2001 From: Augie Fackler <augie@google.com> Date: Wed, 20 Mar 2024 13:33:35 -0400 Subject: [PATCH 283/307] [bazel] add missing dependency for 2137894a6f5475e51c541b6d16e8902125a8f002 --- utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index c4f6eab06221..12fbe0dd6025 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -513,6 +513,7 @@ libc_support_library( name = "__support_uint128", hdrs = ["src/__support/UInt128.h"], deps = [ + ":__support_macros_attributes", ":__support_macros_properties_types", ":__support_uint", ], -- GitLab From 66a2ed50ccb6de64fdf82957ca0d4b55ef76f3cd Mon Sep 17 00:00:00 2001 From: Alex Langford <alangford@apple.com> Date: Wed, 20 Mar 2024 10:43:40 -0700 Subject: [PATCH 284/307] [lldb] Remove process restart prompt from TestSourceManager (#85861) In TestSourceManager, test_artificial_source_location will give the process restart prompt if you run the test individually. The reason is that we run the process twice: first using a convenience function to run to a specific breakpoint and then again to check for a specific message emitted when you hit the breakpoint. Instead of running twice and making the test difficult to run individually, we can just check for the specific messages using other commands. --- lldb/test/API/source-manager/TestSourceManager.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lldb/test/API/source-manager/TestSourceManager.py b/lldb/test/API/source-manager/TestSourceManager.py index eab8924d1081..ad7c85aac70e 100644 --- a/lldb/test/API/source-manager/TestSourceManager.py +++ b/lldb/test/API/source-manager/TestSourceManager.py @@ -323,13 +323,12 @@ class SourceManagerTestCase(TestBase): ) self.expect( - "run", - RUN_SUCCEEDED, + "process status", substrs=[ "stop reason = breakpoint", - "%s:%d" % (src_file, 0), - "Note: this address is compiler-generated code in " "function", - "that has no source code associated " "with it.", + f"{src_file}:0", + "Note: this address is compiler-generated code in function", + "that has no source code associated with it.", ], ) -- GitLab From d42992e71c660d57c89056f6ee4a5be74fa4d1f4 Mon Sep 17 00:00:00 2001 From: Craig Topper <craig.topper@sifive.com> Date: Wed, 20 Mar 2024 09:33:37 -0700 Subject: [PATCH 285/307] [RISCV] Cleanup setOperationAction for ISD::BITCAST with Zfa and D extension. NFC We only need Custom handling for i64 on RV32. This will be used by type legalization. We don't need to make it custom for f64 to get type legalization to custom split i64. If f64 and i64 are legal types, then ISD::BITCAST should be legal. --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 25f035e6dd9d..3aa28215efc2 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -562,8 +562,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, if (Subtarget.hasStdExtZfa()) { setOperationAction(FPRndMode, MVT::f64, Legal); setOperationAction(ISD::FNEARBYINT, MVT::f64, Legal); - setOperationAction(ISD::BITCAST, MVT::i64, Custom); - setOperationAction(ISD::BITCAST, MVT::f64, Custom); + if (!Subtarget.is64Bit()) + setOperationAction(ISD::BITCAST, MVT::i64, Custom); } else { if (Subtarget.is64Bit()) setOperationAction(FPRndMode, MVT::f64, Custom); -- GitLab From 10b0e355372fab1f4d585555536525545eef8523 Mon Sep 17 00:00:00 2001 From: Alex Langford <alangford@apple.com> Date: Wed, 20 Mar 2024 10:46:06 -0700 Subject: [PATCH 286/307] [lldb] Invert relationship between Process and AddressableBits (#85858) AddressableBits is in the Utility module of LLDB. It currently directly refers to Process, which is from the Target LLDB module. This is a layering violation which concretely means that it is impossible to link anything that uses Utility without it also using Target as well. This is generally not an issue for LLDB (since everything is built together) but it may make it difficult to write unit tests for AddressableBits later on. --- lldb/include/lldb/Target/Process.h | 3 ++ lldb/include/lldb/Utility/AddressableBits.h | 6 ++-- .../Process/gdb-remote/ProcessGDBRemote.cpp | 4 +-- .../Process/mach-core/ProcessMachCore.cpp | 2 +- lldb/source/Target/Process.cpp | 23 +++++++++++++++ lldb/source/Utility/AddressableBits.cpp | 28 +++++++------------ 6 files changed, 43 insertions(+), 23 deletions(-) diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index e260e1b4b797..2f3a3c22422e 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -43,6 +43,7 @@ #include "lldb/Target/ThreadList.h" #include "lldb/Target/ThreadPlanStack.h" #include "lldb/Target/Trace.h" +#include "lldb/Utility/AddressableBits.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Event.h" @@ -3219,6 +3220,8 @@ protected: void LoadOperatingSystemPlugin(bool flush); + void SetAddressableBitMasks(AddressableBits bit_masks); + private: Status DestroyImpl(bool force_kill); diff --git a/lldb/include/lldb/Utility/AddressableBits.h b/lldb/include/lldb/Utility/AddressableBits.h index 75752fcf840a..0d27c3561ec2 100644 --- a/lldb/include/lldb/Utility/AddressableBits.h +++ b/lldb/include/lldb/Utility/AddressableBits.h @@ -32,11 +32,13 @@ public: void SetLowmemAddressableBits(uint32_t lowmem_addressing_bits); + uint32_t GetLowmemAddressableBits() const; + void SetHighmemAddressableBits(uint32_t highmem_addressing_bits); - static lldb::addr_t AddressableBitToMask(uint32_t addressable_bits); + uint32_t GetHighmemAddressableBits() const; - void SetProcessMasks(lldb_private::Process &process); + static lldb::addr_t AddressableBitToMask(uint32_t addressable_bits); private: uint32_t m_low_memory_addr_bits; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 5b9a9d71802f..871683a60568 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -900,7 +900,7 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { } AddressableBits addressable_bits = m_gdb_comm.GetAddressableBits(); - addressable_bits.SetProcessMasks(*this); + SetAddressableBitMasks(addressable_bits); if (process_arch.IsValid()) { const ArchSpec &target_arch = GetTarget().GetArchitecture(); @@ -2337,7 +2337,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { } } - addressable_bits.SetProcessMasks(*this); + SetAddressableBitMasks(addressable_bits); ThreadSP thread_sp = SetThreadStopInfo( tid, expedited_register_map, signo, thread_name, reason, description, diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index 7b9938d4f020..1da7696c9a35 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -574,7 +574,7 @@ Status ProcessMachCore::DoLoadCore() { CleanupMemoryRegionPermissions(); AddressableBits addressable_bits = core_objfile->GetAddressableBits(); - addressable_bits.SetProcessMasks(*this); + SetAddressableBitMasks(addressable_bits); return error; } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 6d58873b54a3..f02ec37cb0f0 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -63,6 +63,7 @@ #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Target/ThreadPlanStack.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/AddressableBits.h" #include "lldb/Utility/Event.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" @@ -6453,3 +6454,25 @@ Status Process::CalculateCoreFileSaveRanges(lldb::SaveCoreStyle core_style, return Status(); // Success! } + +void Process::SetAddressableBitMasks(AddressableBits bit_masks) { + uint32_t low_memory_addr_bits = bit_masks.GetLowmemAddressableBits(); + uint32_t high_memory_addr_bits = bit_masks.GetHighmemAddressableBits(); + + if (low_memory_addr_bits == 0 && high_memory_addr_bits == 0) + return; + + if (low_memory_addr_bits != 0) { + addr_t low_addr_mask = + AddressableBits::AddressableBitToMask(low_memory_addr_bits); + SetCodeAddressMask(low_addr_mask); + SetDataAddressMask(low_addr_mask); + } + + if (high_memory_addr_bits != 0) { + addr_t high_addr_mask = + AddressableBits::AddressableBitToMask(high_memory_addr_bits); + SetHighmemCodeAddressMask(high_addr_mask); + SetHighmemDataAddressMask(high_addr_mask); + } +} diff --git a/lldb/source/Utility/AddressableBits.cpp b/lldb/source/Utility/AddressableBits.cpp index 7f9d7ec6c134..4c98addc1f07 100644 --- a/lldb/source/Utility/AddressableBits.cpp +++ b/lldb/source/Utility/AddressableBits.cpp @@ -7,9 +7,10 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/AddressableBits.h" -#include "lldb/Target/Process.h" #include "lldb/lldb-types.h" +#include <cassert> + using namespace lldb; using namespace lldb_private; @@ -28,11 +29,19 @@ void AddressableBits::SetLowmemAddressableBits( m_low_memory_addr_bits = lowmem_addressing_bits; } +uint32_t AddressableBits::GetLowmemAddressableBits() const { + return m_low_memory_addr_bits; +} + void AddressableBits::SetHighmemAddressableBits( uint32_t highmem_addressing_bits) { m_high_memory_addr_bits = highmem_addressing_bits; } +uint32_t AddressableBits::GetHighmemAddressableBits() const { + return m_high_memory_addr_bits; +} + addr_t AddressableBits::AddressableBitToMask(uint32_t addressable_bits) { assert(addressable_bits <= sizeof(addr_t) * 8); if (addressable_bits == 64) @@ -40,20 +49,3 @@ addr_t AddressableBits::AddressableBitToMask(uint32_t addressable_bits) { else return ~((1ULL << addressable_bits) - 1); } - -void AddressableBits::SetProcessMasks(Process &process) { - if (m_low_memory_addr_bits == 0 && m_high_memory_addr_bits == 0) - return; - - if (m_low_memory_addr_bits != 0) { - addr_t low_addr_mask = AddressableBitToMask(m_low_memory_addr_bits); - process.SetCodeAddressMask(low_addr_mask); - process.SetDataAddressMask(low_addr_mask); - } - - if (m_high_memory_addr_bits != 0) { - addr_t hi_addr_mask = AddressableBitToMask(m_high_memory_addr_bits); - process.SetHighmemCodeAddressMask(hi_addr_mask); - process.SetHighmemDataAddressMask(hi_addr_mask); - } -} -- GitLab From 5ea152033ee99ac7ccde791009c372a0983b4eaf Mon Sep 17 00:00:00 2001 From: Vinayak Dev <104419489+vinayakdsci@users.noreply.github.com> Date: Wed, 20 Mar 2024 23:17:35 +0530 Subject: [PATCH 287/307] [libc]: Implement strfromf() and shared utilities (#85438) Fixes #84244. Implements the function `strfromf()` introduced in C23, and adds shared utilities for implementation of other `strfrom*()` functions, including `strfromd()` and `strfroml()`. --- libc/config/linux/x86_64/entrypoints.txt | 1 + libc/spec/stdc.td | 2 + libc/src/stdlib/CMakeLists.txt | 22 ++++ libc/src/stdlib/str_from_util.h | 138 +++++++++++++++++++++++ libc/src/stdlib/strfromf.cpp | 42 +++++++ libc/src/stdlib/strfromf.h | 21 ++++ libc/test/src/stdlib/CMakeLists.txt | 11 +- libc/test/src/stdlib/strfromf_test.cpp | 107 ++++++++++++++++++ 8 files changed, 343 insertions(+), 1 deletion(-) create mode 100644 libc/src/stdlib/str_from_util.h create mode 100644 libc/src/stdlib/strfromf.cpp create mode 100644 libc/src/stdlib/strfromf.h create mode 100644 libc/test/src/stdlib/strfromf_test.cpp diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index e8cf11266624..c216f4349627 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -180,6 +180,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdlib.qsort_r libc.src.stdlib.rand libc.src.stdlib.srand + libc.src.stdlib.strfromf libc.src.stdlib.strtod libc.src.stdlib.strtof libc.src.stdlib.strtol diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index 84d28cc33503..920036adfed5 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -956,6 +956,8 @@ def StdC : StandardSpec<"stdc"> { FunctionSpec<"rand", RetValSpec<IntType>, [ArgSpec<VoidType>]>, FunctionSpec<"srand", RetValSpec<VoidType>, [ArgSpec<UnsignedIntType>]>, + FunctionSpec<"strfromf", RetValSpec<IntType>, [ArgSpec<CharRestrictedPtr>, ArgSpec<SizeTType>, ArgSpec<ConstCharRestrictedPtr>, ArgSpec<FloatType>]>, + FunctionSpec<"strtof", RetValSpec<FloatType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>]>, FunctionSpec<"strtod", RetValSpec<DoubleType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>]>, FunctionSpec<"strtold", RetValSpec<LongDoubleType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>]>, diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt index bd0bcffe0045..22f7f990fb08 100644 --- a/libc/src/stdlib/CMakeLists.txt +++ b/libc/src/stdlib/CMakeLists.txt @@ -52,6 +52,28 @@ add_entrypoint_object( libc.config.linux.app_h ) +add_entrypoint_object( + strfromf + SRCS + strfromf.cpp + HDRS + strfromf.h + DEPENDS + .str_from_util +) + +add_header_library( + str_from_util + HDRS + str_from_util.h + DEPENDS + libc.src.stdio.printf_core.converter + libc.src.stdio.printf_core.core_structs + libc.src.stdio.printf_core.writer + libc.src.__support.str_to_integer + libc.src.__support.CPP.type_traits +) + add_entrypoint_object( strtof SRCS diff --git a/libc/src/stdlib/str_from_util.h b/libc/src/stdlib/str_from_util.h new file mode 100644 index 000000000000..c4c1c0a0ba4e --- /dev/null +++ b/libc/src/stdlib/str_from_util.h @@ -0,0 +1,138 @@ +//===-- Implementation header for strfromx() utilitites -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// According to the C23 standard, any input character sequences except a +// precision specifier and the usual floating point formats, namely +// %{a,A,e,E,f,F,g,G}, are not allowed and any code that does otherwise results +// in undefined behaviour(including use of a '%%' conversion specifier); which +// in this case is that the buffer string is simply populated with the format +// string. The case of the input being NULL should be handled in the calling +// function (strfromf, strfromd, strfroml) itself. + +#ifndef LLVM_LIBC_SRC_STDLIB_STRFROM_UTIL_H +#define LLVM_LIBC_SRC_STDLIB_STRFROM_UTIL_H + +#include "src/__support/CPP/type_traits.h" +#include "src/__support/str_to_integer.h" +#include "src/stdio/printf_core/converter_atlas.h" +#include "src/stdio/printf_core/core_structs.h" +#include "src/stdio/printf_core/writer.h" + +#include <stddef.h> + +namespace LIBC_NAMESPACE::internal { + +template <typename T> +using storage_type = typename fputil::FPBits<T>::StorageType; + +template <typename T> +printf_core::FormatSection parse_format_string(const char *__restrict format, + T fp) { + printf_core::FormatSection section; + size_t cur_pos = 0; + + // There is no typed conversion function to convert single precision float + // to hex exponential format, and the function convert_float_hex_exp() + // requires a double or long double value to work correctly. + // To work around this, we convert fp to double if it is single precision, and + // then use that double precision value in the %{A, a} conversion specifiers. + [[maybe_unused]] double new_fp; + bool t_is_single_prec_type = cpp::is_same<T, float>::value; + if (t_is_single_prec_type) + new_fp = (double)fp; + + if (format[cur_pos] == '%') { + section.has_conv = true; + ++cur_pos; + + // handle precision + section.precision = -1; + if (format[cur_pos] == '.') { + ++cur_pos; + section.precision = 0; + + // The standard does not allow the '*' (asterisk) operator for strfromx() + // functions + if (internal::isdigit(format[cur_pos])) { + auto result = internal::strtointeger<int>(format + cur_pos, 10); + section.precision += result.value; + cur_pos += result.parsed_len; + } + } + + section.conv_name = format[cur_pos]; + switch (format[cur_pos]) { + case 'a': + case 'A': + if (t_is_single_prec_type) + section.conv_val_raw = cpp::bit_cast<storage_type<double>>(new_fp); + else + section.conv_val_raw = cpp::bit_cast<storage_type<T>>(fp); + break; + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + section.conv_val_raw = cpp::bit_cast<storage_type<T>>(fp); + break; + default: + section.has_conv = false; + while (format[cur_pos] != '\0') + ++cur_pos; + break; + } + + if (format[cur_pos] != '\0') + ++cur_pos; + } else { + section.has_conv = false; + // We are looking for exactly one section, so no more '%' + while (format[cur_pos] != '\0') + ++cur_pos; + } + + section.raw_string = {format, cur_pos}; + return section; +} + +template <typename T> +int strfromfloat_convert(printf_core::Writer *writer, + const printf_core::FormatSection §ion) { + if (!section.has_conv) + return writer->write(section.raw_string); + + auto res = static_cast<storage_type<T>>(section.conv_val_raw); + + fputil::FPBits<T> strfromfloat_bits(res); + if (strfromfloat_bits.is_inf_or_nan()) + return convert_inf_nan(writer, section); + + switch (section.conv_name) { + case 'f': + case 'F': + return convert_float_decimal_typed(writer, section, strfromfloat_bits); + case 'e': + case 'E': + return convert_float_dec_exp_typed(writer, section, strfromfloat_bits); + case 'a': + case 'A': + return convert_float_hex_exp(writer, section); + case 'g': + case 'G': + return convert_float_dec_auto_typed(writer, section, strfromfloat_bits); + default: + return writer->write(section.raw_string); + } + return -1; +} + +} // namespace LIBC_NAMESPACE::internal + +#endif // LLVM_LIBC_SRC_STDLIB_STRFROM_UTIL_H diff --git a/libc/src/stdlib/strfromf.cpp b/libc/src/stdlib/strfromf.cpp new file mode 100644 index 000000000000..40eff87eb454 --- /dev/null +++ b/libc/src/stdlib/strfromf.cpp @@ -0,0 +1,42 @@ +//===-- Implementation of strfromf ------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdlib/strfromf.h" +#include "src/stdlib/str_from_util.h" + +#include <stdarg.h> +#include <stddef.h> + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, strfromf, + (char *__restrict s, size_t n, const char *__restrict format, + float fp)) { + LIBC_ASSERT(s != nullptr); + + printf_core::FormatSection section = + internal::parse_format_string(format, fp); + printf_core::WriteBuffer wb(s, (n > 0 ? n - 1 : 0)); + printf_core::Writer writer(&wb); + + int result = 0; + if (section.has_conv) + result = internal::strfromfloat_convert<float>(&writer, section); + else + result = writer.write(section.raw_string); + + if (result < 0) + return result; + + if (n > 0) + wb.buff[wb.buff_cur] = '\0'; + + return writer.get_chars_written(); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/stdlib/strfromf.h b/libc/src/stdlib/strfromf.h new file mode 100644 index 000000000000..b551a58af05a --- /dev/null +++ b/libc/src/stdlib/strfromf.h @@ -0,0 +1,21 @@ +//===-- Implementation header for strfromf ------------------------*- C++--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STDLIB_STRFROMF_H +#define LLVM_LIBC_SRC_STDLIB_STRFROMF_H + +#include <stddef.h> + +namespace LIBC_NAMESPACE { + +int strfromf(char *__restrict s, size_t n, const char *__restrict format, + float fp); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_STDLIB_STRTOF_H diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt index 5488a61c4ef1..cb42bc56f51c 100644 --- a/libc/test/src/stdlib/CMakeLists.txt +++ b/libc/test/src/stdlib/CMakeLists.txt @@ -168,6 +168,16 @@ add_libc_test( .strtol_test_support ) +add_libc_test( + strfromf_test + SUITE + libc-stdlib-tests + SRCS + strfromf_test.cpp + DEPENDS + libc.src.stdlib.strfromf +) + add_libc_test( abs_test SUITE @@ -259,7 +269,6 @@ add_libc_test( libc.src.stdlib.qsort ) - add_libc_test( qsort_r_test SUITE diff --git a/libc/test/src/stdlib/strfromf_test.cpp b/libc/test/src/stdlib/strfromf_test.cpp new file mode 100644 index 000000000000..c5489f5f3af2 --- /dev/null +++ b/libc/test/src/stdlib/strfromf_test.cpp @@ -0,0 +1,107 @@ +//===-- Unittests for strfromf --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdlib/strfromf.h" +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcStrfromfTest, DecimalFloatFormat) { + char buff[100]; + int written; + + written = LIBC_NAMESPACE::strfromf(buff, 16, "%f", 1.0); + EXPECT_EQ(written, 8); + ASSERT_STREQ(buff, "1.000000"); + + written = LIBC_NAMESPACE::strfromf(buff, 20, "%f", 1234567890.0); + EXPECT_EQ(written, 17); + ASSERT_STREQ(buff, "1234567936.000000"); + + written = LIBC_NAMESPACE::strfromf(buff, 5, "%f", 1234567890.0); + EXPECT_EQ(written, 17); + ASSERT_STREQ(buff, "1234"); + + written = LIBC_NAMESPACE::strfromf(buff, 67, "%.3f", 1.0); + EXPECT_EQ(written, 5); + ASSERT_STREQ(buff, "1.000"); + + written = LIBC_NAMESPACE::strfromf(buff, 20, "%1f", 1234567890.0); + EXPECT_EQ(written, 3); + ASSERT_STREQ(buff, "%1f"); +} + +TEST(LlvmLibcStrfromfTest, HexExpFloatFormat) { + char buff[100]; + int written; + + written = LIBC_NAMESPACE::strfromf(buff, 0, "%a", 1234567890.0); + EXPECT_EQ(written, 14); + + written = LIBC_NAMESPACE::strfromf(buff, 20, "%a", 1234567890.0); + EXPECT_EQ(written, 14); + ASSERT_STREQ(buff, "0x1.26580cp+30"); + + written = LIBC_NAMESPACE::strfromf(buff, 20, "%A", 1234567890.0); + EXPECT_EQ(written, 14); + ASSERT_STREQ(buff, "0X1.26580CP+30"); +} + +TEST(LlvmLibcStrfromfTest, DecimalExpFloatFormat) { + char buff[100]; + int written; + written = LIBC_NAMESPACE::strfromf(buff, 20, "%.9e", 1234567890.0); + EXPECT_EQ(written, 15); + ASSERT_STREQ(buff, "1.234567936e+09"); + + written = LIBC_NAMESPACE::strfromf(buff, 20, "%.9E", 1234567890.0); + EXPECT_EQ(written, 15); + ASSERT_STREQ(buff, "1.234567936E+09"); +} + +TEST(LlvmLibcStrfromfTest, AutoDecimalFloatFormat) { + char buff[100]; + int written; + + written = LIBC_NAMESPACE::strfromf(buff, 20, "%.9g", 1234567890.0); + EXPECT_EQ(written, 14); + ASSERT_STREQ(buff, "1.23456794e+09"); + + written = LIBC_NAMESPACE::strfromf(buff, 20, "%.9G", 1234567890.0); + EXPECT_EQ(written, 14); + ASSERT_STREQ(buff, "1.23456794E+09"); + + written = LIBC_NAMESPACE::strfromf(buff, 0, "%G", 1.0); + EXPECT_EQ(written, 1); +} + +TEST(LlvmLibcStrfromfTest, ImproperFormatString) { + + char buff[100]; + int retval; + retval = LIBC_NAMESPACE::strfromf( + buff, 37, "A simple string with no conversions.", 1.0); + EXPECT_EQ(retval, 36); + ASSERT_STREQ(buff, "A simple string with no conversions."); + + retval = LIBC_NAMESPACE::strfromf( + buff, 37, "%A simple string with one conversion, should overwrite.", 1.0); + EXPECT_EQ(retval, 6); + ASSERT_STREQ(buff, "0X1P+0"); + + retval = LIBC_NAMESPACE::strfromf(buff, 74, + "A simple string with one conversion in %A " + "between, writes string as it is", + 1.0); + EXPECT_EQ(retval, 73); + ASSERT_STREQ(buff, "A simple string with one conversion in %A between, " + "writes string as it is"); + + retval = LIBC_NAMESPACE::strfromf(buff, 36, + "A simple string with one conversion", 1.0); + EXPECT_EQ(retval, 35); + ASSERT_STREQ(buff, "A simple string with one conversion"); +} -- GitLab From 5e6bb1fb885abec2e8bc85422bbd83fe4ece6d3b Mon Sep 17 00:00:00 2001 From: Jason Eckhardt <jeckhardt@nvidia.com> Date: Wed, 20 Mar 2024 12:56:49 -0500 Subject: [PATCH 288/307] [TableGen][Target] Add documentation to `Constraints`. (#85951) This patch adds some basic documentation for `Constraints`, along with some "see also" pointers for backend writers to learn more. --- llvm/include/llvm/Target/Target.td | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td index 1e40cc49040d..cb1c0ed2513d 100644 --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -697,7 +697,20 @@ class Instruction : InstructionEncoding { // Scheduling information from TargetSchedule.td. list<SchedReadWrite> SchedRW; - string Constraints = ""; // OperandConstraint, e.g. $src = $dst. + /// Support for operand constraints. There are currently two kinds: + /// "$src = $dst" + /// Ensures that the operands are allocated to the same register. + /// + /// "@earlyclobber $rd" + /// Ensures that LLVM will not use the same register for any inputs (other + /// than an input tied to this output). + /// + /// See also: + /// - MC/MCInstrDesc.h:OperandConstraint::{TIED_TO, EARLY_CLOBBER}. + /// - CodeGen/MachineOperand.h:MachineOperand::{TiedTo, IsEarlyClobber}. + /// - The LLVM IR specification: Section `Output constraints` in the + /// discussion of inline assembly constraint strings. + string Constraints = ""; /// DisableEncoding - List of operand names (e.g. "$op1,$op2") that should not /// be encoded into the output machineinstr. -- GitLab From 4df099e447840bae24e88efca1ab4c03a5d7b21b Mon Sep 17 00:00:00 2001 From: Augie Fackler <augie@google.com> Date: Wed, 20 Mar 2024 13:59:43 -0400 Subject: [PATCH 289/307] [bazel] another BUILD fix for 2137894a6f5475e51c541b6d16e8902125a8f002 --- utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 12fbe0dd6025..40cfb1f470db 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -505,7 +505,7 @@ libc_support_library( name = "__support_sign", hdrs = ["src/__support/sign.h"], deps = [ - ":__support_macros_properties_types", + ":__support_macros_attributes", ], ) -- GitLab From 62ed009ce218897d7707144de54fa1e2beec59dc Mon Sep 17 00:00:00 2001 From: Thurston Dang <thurston@google.com> Date: Wed, 20 Mar 2024 11:04:52 -0700 Subject: [PATCH 290/307] [dfsan] Re-exec with no ASLR if memory layout is incompatible on Linux (#85674) DFSan's shadow mappings are incompatible with 32 bits of ASLR entropy ('sudo sysctl vm.mmap_rnd_bits=32; ninja check-dfsan') and it is difficult to fix this via increasing the size of the shadow mappings, due to the overhead of shadow memory. This patch works around the issue by detecting if the memory layout is incompatible, and if so, re-exec'ing without ASLR. DFSan and MSan share copy-pasted shadow memory code, hence this workaround is ported from MSan: - "[msan] Re-exec with no ASLR if memory layout is incompatible on Linux" (https://github.com/llvm/llvm-project/commit/58f7251820b14c93168726a24816d8a094599be5) - "[msan] Add 'MappingDesc::ALLOCATOR' type and check it is available" (https://github.com/llvm/llvm-project/commit/af2bf86a372cacf5f536bae06e2f2d3886eefb7b) (which in turn are inspired by TSan: "Re-exec TSan with no ASLR if memory layout is incompatible on Linux" (https://github.com/llvm/llvm-project/commit/0784b1eefa36d4acbb0dacd2d18796e26313b6c5 )) aeubanks had remarked in https://github.com/llvm/llvm-project/pull/85142#issuecomment-2004442883 that this issue occurs in Chromium: https://ci.chromium.org/ui/p/chromium/builders/try/linux_upload_clang/5066/overview --- compiler-rt/lib/dfsan/dfsan.cpp | 70 ++++++++++++++++++----- compiler-rt/lib/dfsan/dfsan_allocator.cpp | 3 + compiler-rt/lib/dfsan/dfsan_platform.h | 24 ++++++-- 3 files changed, 78 insertions(+), 19 deletions(-) diff --git a/compiler-rt/lib/dfsan/dfsan.cpp b/compiler-rt/lib/dfsan/dfsan.cpp index 5e85c8fda3e2..302e3c3032ac 100644 --- a/compiler-rt/lib/dfsan/dfsan.cpp +++ b/compiler-rt/lib/dfsan/dfsan.cpp @@ -33,6 +33,9 @@ #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_report_decorator.h" #include "sanitizer_common/sanitizer_stacktrace.h" +#if SANITIZER_LINUX +# include <sys/personality.h> +#endif using namespace __dfsan; @@ -1127,11 +1130,12 @@ static void CheckMemoryLayoutSanity() { // TODO: CheckMemoryRangeAvailability is based on msan. // Consider refactoring these into a shared implementation. -static bool CheckMemoryRangeAvailability(uptr beg, uptr size) { +static bool CheckMemoryRangeAvailability(uptr beg, uptr size, bool verbose) { if (size > 0) { uptr end = beg + size - 1; if (!MemoryRangeIsAvailable(beg, end)) { - Printf("FATAL: Memory range %p - %p is not available.\n", beg, end); + if (verbose) + Printf("FATAL: Memory range %p - %p is not available.\n", beg, end); return false; } } @@ -1163,7 +1167,7 @@ static bool ProtectMemoryRange(uptr beg, uptr size, const char *name) { // TODO: InitShadow is based on msan. // Consider refactoring these into a shared implementation. -bool InitShadow(bool init_origins) { +bool InitShadow(bool init_origins, bool dry_run) { // Let user know mapping parameters first. VPrintf(1, "dfsan_init %p\n", (void *)&__dfsan::dfsan_init); for (unsigned i = 0; i < kMemoryLayoutSize; ++i) @@ -1173,8 +1177,9 @@ bool InitShadow(bool init_origins) { CheckMemoryLayoutSanity(); if (!MEM_IS_APP(&__dfsan::dfsan_init)) { - Printf("FATAL: Code %p is out of application range. Non-PIE build?\n", - (uptr)&__dfsan::dfsan_init); + if (!dry_run) + Printf("FATAL: Code %p is out of application range. Non-PIE build?\n", + (uptr)&__dfsan::dfsan_init); return false; } @@ -1195,20 +1200,26 @@ bool InitShadow(bool init_origins) { bool protect = type == MappingDesc::INVALID || (!init_origins && type == MappingDesc::ORIGIN); CHECK(!(map && protect)); - if (!map && !protect) - CHECK(type == MappingDesc::APP); + if (!map && !protect) { + CHECK(type == MappingDesc::APP || type == MappingDesc::ALLOCATOR); + + if (dry_run && type == MappingDesc::ALLOCATOR && + !CheckMemoryRangeAvailability(start, size, !dry_run)) + return false; + } if (map) { - if (!CheckMemoryRangeAvailability(start, size)) + if (dry_run && !CheckMemoryRangeAvailability(start, size, !dry_run)) return false; - if (!MmapFixedSuperNoReserve(start, size, kMemoryLayout[i].name)) + if (!dry_run && + !MmapFixedSuperNoReserve(start, size, kMemoryLayout[i].name)) return false; - if (common_flags()->use_madv_dontdump) + if (!dry_run && common_flags()->use_madv_dontdump) DontDumpShadowMemory(start, size); } if (protect) { - if (!CheckMemoryRangeAvailability(start, size)) + if (dry_run && !CheckMemoryRangeAvailability(start, size, !dry_run)) return false; - if (!ProtectMemoryRange(start, size, kMemoryLayout[i].name)) + if (!dry_run && !ProtectMemoryRange(start, size, kMemoryLayout[i].name)) return false; } } @@ -1216,6 +1227,35 @@ bool InitShadow(bool init_origins) { return true; } +bool InitShadowWithReExec(bool init_origins) { + // Start with dry run: check layout is ok, but don't print warnings because + // warning messages will cause tests to fail (even if we successfully re-exec + // after the warning). + bool success = InitShadow(init_origins, true); + if (!success) { +#if SANITIZER_LINUX + // Perhaps ASLR entropy is too high. If ASLR is enabled, re-exec without it. + int old_personality = personality(0xffffffff); + bool aslr_on = + (old_personality != -1) && ((old_personality & ADDR_NO_RANDOMIZE) == 0); + + if (aslr_on) { + VReport(1, + "WARNING: DataflowSanitizer: memory layout is incompatible, " + "possibly due to high-entropy ASLR.\n" + "Re-execing with fixed virtual address space.\n" + "N.B. reducing ASLR entropy is preferable.\n"); + CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1); + ReExec(); + } +#endif + } + + // The earlier dry run didn't actually map or protect anything. Run again in + // non-dry run mode. + return success && InitShadow(init_origins, false); +} + static void DFsanInit(int argc, char **argv, char **envp) { CHECK(!dfsan_init_is_running); if (dfsan_inited) @@ -1229,7 +1269,11 @@ static void DFsanInit(int argc, char **argv, char **envp) { CheckASLR(); - InitShadow(dfsan_get_track_origins()); + if (!InitShadowWithReExec(dfsan_get_track_origins())) { + Printf("FATAL: DataflowSanitizer can not mmap the shadow memory.\n"); + DumpProcessMap(); + Die(); + } initialize_interceptors(); diff --git a/compiler-rt/lib/dfsan/dfsan_allocator.cpp b/compiler-rt/lib/dfsan/dfsan_allocator.cpp index df8be2cf5ae0..63475f434cd1 100644 --- a/compiler-rt/lib/dfsan/dfsan_allocator.cpp +++ b/compiler-rt/lib/dfsan/dfsan_allocator.cpp @@ -37,6 +37,9 @@ struct DFsanMapUnmapCallback { void OnUnmap(uptr p, uptr size) const { dfsan_set_label(0, (void *)p, size); } }; +// Note: to ensure that the allocator is compatible with the application memory +// layout (especially with high-entropy ASLR), kSpaceBeg and kSpaceSize must be +// duplicated as MappingDesc::ALLOCATOR in dfsan_platform.h. #if defined(__aarch64__) const uptr kAllocatorSpace = 0xE00000000000ULL; #else diff --git a/compiler-rt/lib/dfsan/dfsan_platform.h b/compiler-rt/lib/dfsan/dfsan_platform.h index b849b4b528ad..01f0de47d960 100644 --- a/compiler-rt/lib/dfsan/dfsan_platform.h +++ b/compiler-rt/lib/dfsan/dfsan_platform.h @@ -27,10 +27,19 @@ using __sanitizer::uptr; struct MappingDesc { uptr start; uptr end; - enum Type { INVALID, APP, SHADOW, ORIGIN } type; + enum Type { + INVALID = 1, + ALLOCATOR = 2, + APP = 4, + SHADOW = 8, + ORIGIN = 16, + } type; const char *name; }; +// Note: MappingDesc::ALLOCATOR entries are only used to check for memory +// layout compatibility. The actual allocation settings are in +// dfsan_allocator.cpp, which need to be kept in sync. #if SANITIZER_LINUX && SANITIZER_WORDSIZE == 64 # if defined(__aarch64__) @@ -53,7 +62,8 @@ const MappingDesc kMemoryLayout[] = { {0X0B00000000000, 0X0C00000000000, MappingDesc::SHADOW, "shadow-10-13"}, {0X0C00000000000, 0X0D00000000000, MappingDesc::INVALID, "invalid"}, {0X0D00000000000, 0X0E00000000000, MappingDesc::ORIGIN, "origin-10-13"}, - {0X0E00000000000, 0X1000000000000, MappingDesc::APP, "app-15"}, + {0X0E00000000000, 0X0E40000000000, MappingDesc::ALLOCATOR, "allocator"}, + {0X0E40000000000, 0X1000000000000, MappingDesc::APP, "app-15"}, }; # define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0xB00000000000ULL) # define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x200000000000ULL) @@ -76,7 +86,8 @@ const MappingDesc kMemoryLayout[] = { {0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"}, {0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"}, {0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"}, - {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}}; + {0x700000000000ULL, 0x740000000000ULL, MappingDesc::ALLOCATOR, "allocator"}, + {0x740000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}}; # define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL) # define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL) # endif @@ -93,20 +104,21 @@ const uptr kMemoryLayoutSize = sizeof(kMemoryLayout) / sizeof(kMemoryLayout[0]); __attribute__((optimize("unroll-loops"))) #endif inline bool -addr_is_type(uptr addr, MappingDesc::Type mapping_type) { +addr_is_type(uptr addr, int mapping_types) { // It is critical for performance that this loop is unrolled (because then it is // simplified into just a few constant comparisons). #ifdef __clang__ # pragma unroll #endif for (unsigned i = 0; i < kMemoryLayoutSize; ++i) - if (kMemoryLayout[i].type == mapping_type && + if ((kMemoryLayout[i].type & mapping_types) && addr >= kMemoryLayout[i].start && addr < kMemoryLayout[i].end) return true; return false; } -#define MEM_IS_APP(mem) addr_is_type((uptr)(mem), MappingDesc::APP) +#define MEM_IS_APP(mem) \ + (addr_is_type((uptr)(mem), MappingDesc::APP | MappingDesc::ALLOCATOR)) #define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW) #define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN) -- GitLab From 5231005193afb8db01afe9a8a1aa308d25f60ba1 Mon Sep 17 00:00:00 2001 From: Sirraide <aeternalmail@gmail.com> Date: Wed, 20 Mar 2024 19:19:30 +0100 Subject: [PATCH 291/307] [Clang] Update missing varargs arg extension warnings (#84520) This updates a few warnings that were diagnosing no arguments for a `...` variadic macro parameter as a GNU extension when it actually is a C++20/C23 extension now. This fixes #84495. --- clang/docs/ReleaseNotes.rst | 3 +++ .../include/clang/Basic/DiagnosticLexKinds.td | 13 ++++++++++--- clang/lib/Lex/PPMacroExpansion.cpp | 19 ++++++++++++++----- clang/test/C/C2x/n2975.c | 4 ++-- clang/test/Lexer/gnu-flags.c | 2 -- clang/test/Preprocessor/empty_va_arg.cpp | 18 +++++++++++------- clang/test/Preprocessor/macro_fn.c | 4 ++-- 7 files changed, 42 insertions(+), 21 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a10e942615ff..c0b0c8a8a3ea 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -263,6 +263,9 @@ Improvements to Clang's diagnostics operands, distinguishing it from potential typographical errors or unintended bitwise operations. Fixes #GH77601. +- Clang now correctly diagnoses no arguments to a variadic macro parameter as a C23/C++20 extension. + Fixes #GH84495. + Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index d7c172e65463..ad6bacfb118d 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -465,9 +465,16 @@ def err_embedded_directive : Error< def ext_embedded_directive : Extension< "embedding a directive within macro arguments has undefined behavior">, InGroup<DiagGroup<"embedded-directive">>; -def ext_missing_varargs_arg : Extension< - "must specify at least one argument for '...' parameter of variadic macro">, - InGroup<GNUZeroVariadicMacroArguments>; +def ext_c_missing_varargs_arg : Extension< + "passing no argument for the '...' parameter of a variadic macro is " + "a C23 extension">, InGroup<C23>; +def ext_cxx_missing_varargs_arg : Extension< + "passing no argument for the '...' parameter of a variadic macro is " + "a C++20 extension">, InGroup<CXX20>; +def warn_c17_compat_missing_varargs_arg : Warning< + "passing no argument for the '...' parameter of a variadic macro is " + "incompatible with C standards before C23">, + InGroup<CPre23Compat>, DefaultIgnore; def warn_cxx17_compat_missing_varargs_arg : Warning< "passing no argument for the '...' parameter of a variadic macro is " "incompatible with C++ standards before C++20">, diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 3017461dc66e..516269c0c601 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -993,11 +993,20 @@ MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName, // If the macro contains the comma pasting extension, the diagnostic // is suppressed; we know we'll get another diagnostic later. if (!MI->hasCommaPasting()) { - // C++20 allows this construct, but standards before C++20 and all C - // standards do not allow the construct (we allow it as an extension). - Diag(Tok, getLangOpts().CPlusPlus20 - ? diag::warn_cxx17_compat_missing_varargs_arg - : diag::ext_missing_varargs_arg); + // C++20 [cpp.replace]p15, C23 6.10.5p12 + // + // C++20 and C23 allow this construct, but standards before that + // do not (we allow it as an extension). + unsigned ID; + if (getLangOpts().CPlusPlus20) + ID = diag::warn_cxx17_compat_missing_varargs_arg; + else if (getLangOpts().CPlusPlus) + ID = diag::ext_cxx_missing_varargs_arg; + else if (getLangOpts().C23) + ID = diag::warn_c17_compat_missing_varargs_arg; + else + ID = diag::ext_c_missing_varargs_arg; + Diag(Tok, ID); Diag(MI->getDefinitionLoc(), diag::note_macro_here) << MacroName.getIdentifierInfo(); } diff --git a/clang/test/C/C2x/n2975.c b/clang/test/C/C2x/n2975.c index 5fc641dd66e7..2269400fe47c 100644 --- a/clang/test/C/C2x/n2975.c +++ b/clang/test/C/C2x/n2975.c @@ -11,7 +11,7 @@ void func(...) { // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}} // Show that va_start doesn't require the second argument in C23 mode. va_list list; - va_start(list); // FIXME: it would be nice to issue a portability warning to C17 and earlier here. + va_start(list); // expected-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C standards before C23}} expected-note@* {{macro 'va_start' defined here}} va_end(list); // Show that va_start doesn't expand or evaluate the second argument. @@ -26,7 +26,7 @@ void func(...) { // expected-warning {{'...' as the only parameter of a function __builtin_va_start(list); // expected-error {{too few arguments to function call, expected 2, have 1}} // Verify that the return type of a call to va_start is 'void'. - _Static_assert(__builtin_types_compatible_p(__typeof__(va_start(list)), void), ""); + _Static_assert(__builtin_types_compatible_p(__typeof__(va_start(list)), void), ""); // expected-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C standards before C23}} expected-note@* {{macro 'va_start' defined here}} _Static_assert(__builtin_types_compatible_p(__typeof__(__builtin_va_start(list, 0)), void), ""); } diff --git a/clang/test/Lexer/gnu-flags.c b/clang/test/Lexer/gnu-flags.c index 384339fc8594..4d6d216b101f 100644 --- a/clang/test/Lexer/gnu-flags.c +++ b/clang/test/Lexer/gnu-flags.c @@ -17,8 +17,6 @@ #if ALL || ZEROARGS -// expected-warning@+9 {{must specify at least one argument for '...' parameter of variadic macro}} -// expected-note@+4 {{macro 'efoo' defined here}} // expected-warning@+3 {{token pasting of ',' and __VA_ARGS__ is a GNU extension}} #endif diff --git a/clang/test/Preprocessor/empty_va_arg.cpp b/clang/test/Preprocessor/empty_va_arg.cpp index 2ee431f6bde8..7c7d49d8fb16 100644 --- a/clang/test/Preprocessor/empty_va_arg.cpp +++ b/clang/test/Preprocessor/empty_va_arg.cpp @@ -1,12 +1,16 @@ -// RUN: %clang_cc1 -Eonly -std=c++17 -pedantic -verify %s -// RUN: %clang_cc1 -Eonly -std=c17 -pedantic -verify -x c %s -// RUN: %clang_cc1 -Eonly -std=c++20 -pedantic -Wpre-c++20-compat -verify=compat %s +// RUN: %clang_cc1 -Eonly -std=c17 -pedantic -verify=c17,expected -x c %s +// RUN: %clang_cc1 -Eonly -std=c23 -pedantic -Wpre-c23-compat -verify=c23,expected -x c %s +// RUN: %clang_cc1 -Eonly -std=c++17 -pedantic -verify=cxx17,expected %s +// RUN: %clang_cc1 -Eonly -std=c++20 -pedantic -Wpre-c++20-compat -verify=cxx20,expected %s -#define FOO(x, ...) // expected-note {{macro 'FOO' defined here}} \ - // compat-note {{macro 'FOO' defined here}} +// silent-no-diagnostics + +#define FOO(x, ...) // expected-note {{macro 'FOO' defined here}} int main() { - FOO(42) // expected-warning {{must specify at least one argument for '...' parameter of variadic macro}} \ - // compat-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C++ standards before C++20}} + FOO(42) // c17-warning {{passing no argument for the '...' parameter of a variadic macro is a C23 extension}} \ + // cxx17-warning {{passing no argument for the '...' parameter of a variadic macro is a C++20 extension}} \ + // c23-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C standards before C23}} \ + // cxx20-warning {{passing no argument for the '...' parameter of a variadic macro is incompatible with C++ standards before C++20}} } diff --git a/clang/test/Preprocessor/macro_fn.c b/clang/test/Preprocessor/macro_fn.c index 5f4ea0e26d5d..81d836321407 100644 --- a/clang/test/Preprocessor/macro_fn.c +++ b/clang/test/Preprocessor/macro_fn.c @@ -37,8 +37,8 @@ e(x) e() zero_dot() -one_dot(x) /* empty ... argument: expected-warning {{must specify at least one argument for '...' parameter of variadic macro}} */ -one_dot() /* empty first argument, elided ...: expected-warning {{must specify at least one argument for '...' parameter of variadic macro}} */ +one_dot(x) /* empty ... argument: expected-warning {{passing no argument for the '...' parameter of a variadic macro is a C23 extension}} */ +one_dot() /* empty first argument, elided ...: expected-warning {{passing no argument for the '...' parameter of a variadic macro is a C23 extension}} */ /* Crash with function-like macro test at end of directive. */ -- GitLab From cc9186060ad75c68a052bbcf43d7d1ee93143a60 Mon Sep 17 00:00:00 2001 From: Guray Ozen <guray.ozen@gmail.com> Date: Wed, 20 Mar 2024 19:21:19 +0100 Subject: [PATCH 292/307] [mlir][nvgpu][nvvm] Add myself as a primary reviewer for nvgpu and nvvm dialects (#85414) --- .github/CODEOWNERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 561da6a588c0..c246c42b0904 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -106,6 +106,14 @@ clang/test/AST/Interp/ @tbaederr # MLIR Sparsifier. /mlir/**/*SparseTensor*/ @aartbik @PeimingLiu @yinying-lisa-li @matthias-springer +# MLIR NVGPU Dialect +/mlir/**/NVGPU*/ @grypp +/mlir/test/**/CUDA/ @grypp + +# MLIR NVVM Dialect in MLIR +/mlir/**/LLVMIR/**/BasicPtxBuilderInterface* @grypp +/mlir/**/NVVM*/ @grypp + # BOLT /bolt/ @aaupov @maksfb @rafaelauler @ayermolo @dcci -- GitLab From 949d70d5e023b34b741b7d577c61a7ef60c3316f Mon Sep 17 00:00:00 2001 From: Vyacheslav Levytskyy <vyacheslav.levytskyy@intel.com> Date: Wed, 20 Mar 2024 19:23:12 +0100 Subject: [PATCH 293/307] [SPIR-V] Fix incorrect bitwise instructions applied to the bool type (#85929) This PR ensures that LLVM IR bitwise instructions result in logical SPIR-V instructions when applied to i1 type. --- llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp | 20 ++++++ .../CodeGen/SPIRV/instructions/bitwise-i1.ll | 69 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 llvm/test/CodeGen/SPIRV/instructions/bitwise-i1.ll diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp index e6e9131d8dc2..55b4c47c197d 100644 --- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp @@ -145,6 +145,26 @@ void SPIRVTargetLowering::finalizeLowering(MachineFunction &MF) const { validatePtrTypes(STI, MRI, GR, MI, GR.getSPIRVTypeForVReg(MI.getOperand(1).getReg()), 0); break; + // ensure that LLVM IR bitwise instructions result in logical SPIR-V + // instructions when applied to bool type + case SPIRV::OpBitwiseOrS: + case SPIRV::OpBitwiseOrV: + if (GR.isScalarOrVectorOfType(MI.getOperand(1).getReg(), + SPIRV::OpTypeBool)) + MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalOr)); + break; + case SPIRV::OpBitwiseAndS: + case SPIRV::OpBitwiseAndV: + if (GR.isScalarOrVectorOfType(MI.getOperand(1).getReg(), + SPIRV::OpTypeBool)) + MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalAnd)); + break; + case SPIRV::OpBitwiseXorS: + case SPIRV::OpBitwiseXorV: + if (GR.isScalarOrVectorOfType(MI.getOperand(1).getReg(), + SPIRV::OpTypeBool)) + MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalNotEqual)); + break; } } } diff --git a/llvm/test/CodeGen/SPIRV/instructions/bitwise-i1.ll b/llvm/test/CodeGen/SPIRV/instructions/bitwise-i1.ll new file mode 100644 index 000000000000..8d3657b36454 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/instructions/bitwise-i1.ll @@ -0,0 +1,69 @@ +; This test ensures that LLVM IR bitwise instructions result in logical SPIR-V instructions +; when applied to i1 type + +; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: %[[#Char:]] = OpTypeInt 8 0 +; CHECK-DAG: %[[#Vec2Char:]] = OpTypeVector %[[#Char]] 2 +; CHECK-DAG: %[[#Bool:]] = OpTypeBool +; CHECK-DAG: %[[#Vec2Bool:]] = OpTypeVector %[[#Bool]] 2 + +; CHECK: OpBitwiseAnd %[[#Char]] +; CHECK: OpBitwiseOr %[[#Char]] +; CHECK: OpBitwiseXor %[[#Char]] +; CHECK: OpBitwiseAnd %[[#Vec2Char]] +; CHECK: OpBitwiseOr %[[#Vec2Char]] +; CHECK: OpBitwiseXor %[[#Vec2Char]] + +; CHECK: OpLogicalAnd %[[#Bool]] + +; CHECK: OpLogicalAnd %[[#Bool]] +; CHECK: OpLogicalOr %[[#Bool]] +; CHECK: OpLogicalNotEqual %[[#Bool]] +; CHECK: OpLogicalAnd %[[#Vec2Bool]] +; CHECK: OpLogicalOr %[[#Vec2Bool]] +; CHECK: OpLogicalNotEqual %[[#Vec2Bool]] + +define void @test1(i8 noundef %arg1, i8 noundef %arg2) { + %cond1 = and i8 %arg1, %arg2 + %cond2 = or i8 %arg1, %arg2 + %cond3 = xor i8 %arg1, %arg2 + ret void +} + +define void @test1v(<2 x i8> noundef %arg1, <2 x i8> noundef %arg2) { + %cond1 = and <2 x i8> %arg1, %arg2 + %cond2 = or <2 x i8> %arg1, %arg2 + %cond3 = xor <2 x i8> %arg1, %arg2 + ret void +} + +define void @test2(float noundef %real, float noundef %imag) { +entry: + %realabs = tail call spir_func noundef float @_Z16__spirv_ocl_fabsf(float noundef %real) + %cond1 = fcmp oeq float %realabs, 1.000000e+00 + %cond2 = fcmp oeq float %imag, 0.000000e+00 + %cond3 = and i1 %cond1, %cond2 + br i1 %cond3, label %midlbl, label %cleanup +midlbl: + br label %cleanup +cleanup: + ret void +} + +define void @test3(i1 noundef %arg1, i1 noundef %arg2) { + %cond1 = and i1 %arg1, %arg2 + %cond2 = or i1 %arg1, %arg2 + %cond3 = xor i1 %arg1, %arg2 + ret void +} + +define void @test3v(<2 x i1> noundef %arg1, <2 x i1> noundef %arg2) { + %cond1 = and <2 x i1> %arg1, %arg2 + %cond2 = or <2 x i1> %arg1, %arg2 + %cond3 = xor <2 x i1> %arg1, %arg2 + ret void +} + +declare dso_local spir_func noundef float @_Z16__spirv_ocl_fabsf(float noundef) -- GitLab From c2483ed52d6f600a91663a49e35bab1dff2ed977 Mon Sep 17 00:00:00 2001 From: Vyacheslav Levytskyy <vyacheslav.levytskyy@intel.com> Date: Wed, 20 Mar 2024 19:28:29 +0100 Subject: [PATCH 294/307] [SPIRV] Add __spirv_ builtins for existing instructions (#85654) This PR: * adds __spirv_ builtins for existing instructions; * fixes parsing of "syncscope" values in atomic instructions; * fix a special case of binary header emision. --- llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp | 30 +++---- llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 68 ++++++++++++--- llvm/lib/Target/SPIRV/SPIRVBuiltins.td | 24 ++++++ .../Target/SPIRV/SPIRVInstructionSelector.cpp | 85 ++++++++++++++++--- llvm/test/CodeGen/SPIRV/empty-logical.ll | 1 + llvm/test/CodeGen/SPIRV/empty-module.ll | 1 + llvm/test/CodeGen/SPIRV/empty-opencl32.ll | 1 + llvm/test/CodeGen/SPIRV/empty-opencl64.ll | 1 + llvm/test/CodeGen/SPIRV/empty.ll | 1 + llvm/test/CodeGen/SPIRV/fence.ll | 54 ++++++++++++ 10 files changed, 226 insertions(+), 40 deletions(-) create mode 100644 llvm/test/CodeGen/SPIRV/fence.ll diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp index 30c67d3fde63..4eee8062f282 100644 --- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp @@ -103,22 +103,22 @@ void SPIRVAsmPrinter::emitEndOfAsmFile(Module &M) { if (ModuleSectionsEmitted == false) { outputModuleSections(); ModuleSectionsEmitted = true; - } else { - ST = static_cast<const SPIRVTargetMachine &>(TM).getSubtargetImpl(); - uint32_t DecSPIRVVersion = ST->getSPIRVVersion(); - uint32_t Major = DecSPIRVVersion / 10; - uint32_t Minor = DecSPIRVVersion - Major * 10; - // TODO: calculate Bound more carefully from maximum used register number, - // accounting for generated OpLabels and other related instructions if - // needed. - unsigned Bound = 2 * (ST->getBound() + 1); - bool FlagToRestore = OutStreamer->getUseAssemblerInfoForParsing(); - OutStreamer->setUseAssemblerInfoForParsing(true); - if (MCAssembler *Asm = OutStreamer->getAssemblerPtr()) - Asm->setBuildVersion(static_cast<MachO::PlatformType>(0), Major, Minor, - Bound, VersionTuple(Major, Minor, 0, Bound)); - OutStreamer->setUseAssemblerInfoForParsing(FlagToRestore); } + + ST = static_cast<const SPIRVTargetMachine &>(TM).getSubtargetImpl(); + uint32_t DecSPIRVVersion = ST->getSPIRVVersion(); + uint32_t Major = DecSPIRVVersion / 10; + uint32_t Minor = DecSPIRVVersion - Major * 10; + // TODO: calculate Bound more carefully from maximum used register number, + // accounting for generated OpLabels and other related instructions if + // needed. + unsigned Bound = 2 * (ST->getBound() + 1); + bool FlagToRestore = OutStreamer->getUseAssemblerInfoForParsing(); + OutStreamer->setUseAssemblerInfoForParsing(true); + if (MCAssembler *Asm = OutStreamer->getAssemblerPtr()) + Asm->setBuildVersion(static_cast<MachO::PlatformType>(0), Major, Minor, + Bound, VersionTuple(Major, Minor, 0, Bound)); + OutStreamer->setUseAssemblerInfoForParsing(FlagToRestore); } void SPIRVAsmPrinter::emitFunctionHeader() { diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp index 07be0b34b182..0478fc33cedc 100644 --- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp @@ -53,6 +53,8 @@ struct IncomingCall { : BuiltinName(BuiltinName), Builtin(Builtin), ReturnRegister(ReturnRegister), ReturnType(ReturnType), Arguments(Arguments) {} + + bool isSpirvOp() const { return BuiltinName.rfind("__spirv_", 0) == 0; } }; struct NativeBuiltin { @@ -485,9 +487,27 @@ static Register buildMemSemanticsReg(Register SemanticsRegister, return buildConstantIntReg(Semantics, MIRBuilder, GR); } +static bool buildOpFromWrapper(MachineIRBuilder &MIRBuilder, unsigned Opcode, + const SPIRV::IncomingCall *Call, + Register TypeReg = Register(0)) { + MachineRegisterInfo *MRI = MIRBuilder.getMRI(); + auto MIB = MIRBuilder.buildInstr(Opcode); + if (TypeReg.isValid()) + MIB.addDef(Call->ReturnRegister).addUse(TypeReg); + for (Register ArgReg : Call->Arguments) { + if (!MRI->getRegClassOrNull(ArgReg)) + MRI->setRegClass(ArgReg, &SPIRV::IDRegClass); + MIB.addUse(ArgReg); + } + return true; +} + /// Helper function for translating atomic init to OpStore. static bool buildAtomicInitInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder) { + if (Call->isSpirvOp()) + return buildOpFromWrapper(MIRBuilder, SPIRV::OpStore, Call); + assert(Call->Arguments.size() == 2 && "Need 2 arguments for atomic init translation"); MIRBuilder.getMRI()->setRegClass(Call->Arguments[0], &SPIRV::IDRegClass); @@ -502,6 +522,10 @@ static bool buildAtomicInitInst(const SPIRV::IncomingCall *Call, static bool buildAtomicLoadInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR) { + Register TypeReg = GR->getSPIRVTypeID(Call->ReturnType); + if (Call->isSpirvOp()) + return buildOpFromWrapper(MIRBuilder, SPIRV::OpAtomicLoad, Call, TypeReg); + Register PtrRegister = Call->Arguments[0]; MIRBuilder.getMRI()->setRegClass(PtrRegister, &SPIRV::IDRegClass); // TODO: if true insert call to __translate_ocl_memory_sccope before @@ -528,7 +552,7 @@ static bool buildAtomicLoadInst(const SPIRV::IncomingCall *Call, MIRBuilder.buildInstr(SPIRV::OpAtomicLoad) .addDef(Call->ReturnRegister) - .addUse(GR->getSPIRVTypeID(Call->ReturnType)) + .addUse(TypeReg) .addUse(PtrRegister) .addUse(ScopeRegister) .addUse(MemSemanticsReg); @@ -539,6 +563,9 @@ static bool buildAtomicLoadInst(const SPIRV::IncomingCall *Call, static bool buildAtomicStoreInst(const SPIRV::IncomingCall *Call, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR) { + if (Call->isSpirvOp()) + return buildOpFromWrapper(MIRBuilder, SPIRV::OpAtomicStore, Call); + Register ScopeRegister = buildConstantIntReg(SPIRV::Scope::Device, MIRBuilder, GR); Register PtrRegister = Call->Arguments[0]; @@ -557,12 +584,13 @@ static bool buildAtomicStoreInst(const SPIRV::IncomingCall *Call, } /// Helper function for building an atomic compare-exchange instruction. -static bool buildAtomicCompareExchangeInst(const SPIRV::IncomingCall *Call, - MachineIRBuilder &MIRBuilder, - SPIRVGlobalRegistry *GR) { - const SPIRV::DemangledBuiltin *Builtin = Call->Builtin; - unsigned Opcode = - SPIRV::lookupNativeBuiltin(Builtin->Name, Builtin->Set)->Opcode; +static bool buildAtomicCompareExchangeInst( + const SPIRV::IncomingCall *Call, const SPIRV::DemangledBuiltin *Builtin, + unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR) { + if (Call->isSpirvOp()) + return buildOpFromWrapper(MIRBuilder, Opcode, Call, + GR->getSPIRVTypeID(Call->ReturnType)); + bool IsCmpxchg = Call->Builtin->Name.contains("cmpxchg"); MachineRegisterInfo *MRI = MIRBuilder.getMRI(); @@ -667,6 +695,10 @@ static bool buildAtomicCompareExchangeInst(const SPIRV::IncomingCall *Call, static bool buildAtomicRMWInst(const SPIRV::IncomingCall *Call, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR) { + if (Call->isSpirvOp()) + return buildOpFromWrapper(MIRBuilder, Opcode, Call, + GR->getSPIRVTypeID(Call->ReturnType)); + MachineRegisterInfo *MRI = MIRBuilder.getMRI(); Register ScopeRegister = Call->Arguments.size() >= 4 ? Call->Arguments[3] : Register(); @@ -731,6 +763,12 @@ static bool buildAtomicFloatingRMWInst(const SPIRV::IncomingCall *Call, static bool buildAtomicFlagInst(const SPIRV::IncomingCall *Call, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR) { + bool IsSet = Opcode == SPIRV::OpAtomicFlagTestAndSet; + Register TypeReg = GR->getSPIRVTypeID(Call->ReturnType); + if (Call->isSpirvOp()) + return buildOpFromWrapper(MIRBuilder, Opcode, Call, + IsSet ? TypeReg : Register(0)); + MachineRegisterInfo *MRI = MIRBuilder.getMRI(); Register PtrRegister = Call->Arguments[0]; unsigned Semantics = SPIRV::MemorySemantics::SequentiallyConsistent; @@ -750,9 +788,8 @@ static bool buildAtomicFlagInst(const SPIRV::IncomingCall *Call, buildScopeReg(ScopeRegister, SPIRV::Scope::Device, MIRBuilder, GR, MRI); auto MIB = MIRBuilder.buildInstr(Opcode); - if (Opcode == SPIRV::OpAtomicFlagTestAndSet) - MIB.addDef(Call->ReturnRegister) - .addUse(GR->getSPIRVTypeID(Call->ReturnType)); + if (IsSet) + MIB.addDef(Call->ReturnRegister).addUse(TypeReg); MIB.addUse(PtrRegister).addUse(ScopeRegister).addUse(MemSemanticsReg); return true; @@ -763,6 +800,9 @@ static bool buildAtomicFlagInst(const SPIRV::IncomingCall *Call, static bool buildBarrierInst(const SPIRV::IncomingCall *Call, unsigned Opcode, MachineIRBuilder &MIRBuilder, SPIRVGlobalRegistry *GR) { + if (Call->isSpirvOp()) + return buildOpFromWrapper(MIRBuilder, Opcode, Call); + MachineRegisterInfo *MRI = MIRBuilder.getMRI(); unsigned MemFlags = getIConstVal(Call->Arguments[0], MRI); unsigned MemSemantics = SPIRV::MemorySemantics::None; @@ -1240,7 +1280,8 @@ static bool generateAtomicInst(const SPIRV::IncomingCall *Call, return buildAtomicStoreInst(Call, MIRBuilder, GR); case SPIRV::OpAtomicCompareExchange: case SPIRV::OpAtomicCompareExchangeWeak: - return buildAtomicCompareExchangeInst(Call, MIRBuilder, GR); + return buildAtomicCompareExchangeInst(Call, Builtin, Opcode, MIRBuilder, + GR); case SPIRV::OpAtomicIAdd: case SPIRV::OpAtomicISub: case SPIRV::OpAtomicOr: @@ -1815,14 +1856,15 @@ static bool buildEnqueueKernel(const SPIRV::IncomingCall *Call, SPIRVGlobalRegistry *GR) { MachineRegisterInfo *MRI = MIRBuilder.getMRI(); const DataLayout &DL = MIRBuilder.getDataLayout(); - bool HasEvents = Call->Builtin->Name.contains("events"); + bool IsSpirvOp = Call->isSpirvOp(); + bool HasEvents = Call->Builtin->Name.contains("events") || IsSpirvOp; const SPIRVType *Int32Ty = GR->getOrCreateSPIRVIntegerType(32, MIRBuilder); // Make vararg instructions before OpEnqueueKernel. // Local sizes arguments: Sizes of block invoke arguments. Clang generates // local size operands as an array, so we need to unpack them. SmallVector<Register, 16> LocalSizes; - if (Call->Builtin->Name.find("_varargs") != StringRef::npos) { + if (Call->Builtin->Name.find("_varargs") != StringRef::npos || IsSpirvOp) { const unsigned LocalSizeArrayIdx = HasEvents ? 9 : 6; Register GepReg = Call->Arguments[LocalSizeArrayIdx]; MachineInstr *GepMI = MRI->getUniqueVRegDef(GepReg); diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td index eb26f70b1861..ee4f13d89c3c 100644 --- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td +++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td @@ -500,27 +500,38 @@ defm : DemangledNativeBuiltin<"__spirv_All", OpenCL_std, Relational, 1, 1, OpAll defm : DemangledNativeBuiltin<"atomic_init", OpenCL_std, Atomic, 2, 2, OpStore>; defm : DemangledNativeBuiltin<"atomic_load", OpenCL_std, Atomic, 1, 1, OpAtomicLoad>; defm : DemangledNativeBuiltin<"atomic_load_explicit", OpenCL_std, Atomic, 2, 3, OpAtomicLoad>; +defm : DemangledNativeBuiltin<"__spirv_AtomicLoad", OpenCL_std, Atomic, 3, 3, OpAtomicLoad>; defm : DemangledNativeBuiltin<"atomic_store", OpenCL_std, Atomic, 2, 2, OpAtomicStore>; defm : DemangledNativeBuiltin<"atomic_store_explicit", OpenCL_std, Atomic, 2, 4, OpAtomicStore>; +defm : DemangledNativeBuiltin<"__spirv_AtomicStore", OpenCL_std, Atomic, 4, 4, OpAtomicStore>; defm : DemangledNativeBuiltin<"atomic_compare_exchange_strong", OpenCL_std, Atomic, 3, 6, OpAtomicCompareExchange>; +defm : DemangledNativeBuiltin<"__spirv_AtomicCompareExchange", OpenCL_std, Atomic, 6, 6, OpAtomicCompareExchange>; defm : DemangledNativeBuiltin<"atomic_compare_exchange_strong_explicit", OpenCL_std, Atomic, 5, 6, OpAtomicCompareExchange>; defm : DemangledNativeBuiltin<"atomic_compare_exchange_weak", OpenCL_std, Atomic, 3, 6, OpAtomicCompareExchangeWeak>; defm : DemangledNativeBuiltin<"atomic_compare_exchange_weak_explicit", OpenCL_std, Atomic, 5, 6, OpAtomicCompareExchangeWeak>; +defm : DemangledNativeBuiltin<"__spirv_AtomicCompareExchangeWeak", OpenCL_std, Atomic, 6, 6, OpAtomicCompareExchangeWeak>; defm : DemangledNativeBuiltin<"atom_cmpxchg", OpenCL_std, Atomic, 3, 6, OpAtomicCompareExchange>; defm : DemangledNativeBuiltin<"atomic_cmpxchg", OpenCL_std, Atomic, 3, 6, OpAtomicCompareExchange>; defm : DemangledNativeBuiltin<"atom_add", OpenCL_std, Atomic, 2, 4, OpAtomicIAdd>; defm : DemangledNativeBuiltin<"atomic_add", OpenCL_std, Atomic, 2, 4, OpAtomicIAdd>; +defm : DemangledNativeBuiltin<"__spirv_AtomicIAdd", OpenCL_std, Atomic, 4, 4, OpAtomicIAdd>; defm : DemangledNativeBuiltin<"atom_sub", OpenCL_std, Atomic, 2, 4, OpAtomicISub>; defm : DemangledNativeBuiltin<"atomic_sub", OpenCL_std, Atomic, 2, 4, OpAtomicISub>; +defm : DemangledNativeBuiltin<"__spirv_AtomicISub", OpenCL_std, Atomic, 4, 4, OpAtomicISub>; defm : DemangledNativeBuiltin<"atom_or", OpenCL_std, Atomic, 2, 4, OpAtomicOr>; defm : DemangledNativeBuiltin<"atomic_or", OpenCL_std, Atomic, 2, 4, OpAtomicOr>; +defm : DemangledNativeBuiltin<"__spirv_AtomicOr", OpenCL_std, Atomic, 4, 4, OpAtomicOr>; defm : DemangledNativeBuiltin<"atom_xor", OpenCL_std, Atomic, 2, 4, OpAtomicXor>; defm : DemangledNativeBuiltin<"atomic_xor", OpenCL_std, Atomic, 2, 4, OpAtomicXor>; +defm : DemangledNativeBuiltin<"__spirv_AtomicXor", OpenCL_std, Atomic, 4, 4, OpAtomicXor>; defm : DemangledNativeBuiltin<"atom_and", OpenCL_std, Atomic, 2, 4, OpAtomicAnd>; defm : DemangledNativeBuiltin<"atomic_and", OpenCL_std, Atomic, 2, 4, OpAtomicAnd>; +defm : DemangledNativeBuiltin<"__spirv_AtomicAnd", OpenCL_std, Atomic, 4, 4, OpAtomicAnd>; defm : DemangledNativeBuiltin<"atomic_exchange", OpenCL_std, Atomic, 2, 4, OpAtomicExchange>; defm : DemangledNativeBuiltin<"atomic_exchange_explicit", OpenCL_std, Atomic, 2, 4, OpAtomicExchange>; +defm : DemangledNativeBuiltin<"AtomicEx__spirv_change", OpenCL_std, Atomic, 2, 4, OpAtomicExchange>; defm : DemangledNativeBuiltin<"atomic_work_item_fence", OpenCL_std, Atomic, 1, 3, OpMemoryBarrier>; +defm : DemangledNativeBuiltin<"__spirv_MemoryBarrier", OpenCL_std, Atomic, 2, 2, OpMemoryBarrier>; defm : DemangledNativeBuiltin<"atomic_fetch_add", OpenCL_std, Atomic, 2, 4, OpAtomicIAdd>; defm : DemangledNativeBuiltin<"atomic_fetch_sub", OpenCL_std, Atomic, 2, 4, OpAtomicISub>; defm : DemangledNativeBuiltin<"atomic_fetch_or", OpenCL_std, Atomic, 2, 4, OpAtomicOr>; @@ -532,26 +543,37 @@ defm : DemangledNativeBuiltin<"atomic_fetch_or_explicit", OpenCL_std, Atomic, 4, defm : DemangledNativeBuiltin<"atomic_fetch_xor_explicit", OpenCL_std, Atomic, 4, 6, OpAtomicXor>; defm : DemangledNativeBuiltin<"atomic_fetch_and_explicit", OpenCL_std, Atomic, 4, 6, OpAtomicAnd>; defm : DemangledNativeBuiltin<"atomic_flag_test_and_set", OpenCL_std, Atomic, 1, 1, OpAtomicFlagTestAndSet>; +defm : DemangledNativeBuiltin<"__spirv_AtomicFlagTestAndSet", OpenCL_std, Atomic, 3, 3, OpAtomicFlagTestAndSet>; defm : DemangledNativeBuiltin<"atomic_flag_test_and_set_explicit", OpenCL_std, Atomic, 2, 3, OpAtomicFlagTestAndSet>; defm : DemangledNativeBuiltin<"atomic_flag_clear", OpenCL_std, Atomic, 1, 1, OpAtomicFlagClear>; +defm : DemangledNativeBuiltin<"__spirv_AtomicFlagClear", OpenCL_std, Atomic, 3, 3, OpAtomicFlagClear>; defm : DemangledNativeBuiltin<"atomic_flag_clear_explicit", OpenCL_std, Atomic, 2, 3, OpAtomicFlagClear>; // Barrier builtin records: defm : DemangledNativeBuiltin<"barrier", OpenCL_std, Barrier, 1, 3, OpControlBarrier>; defm : DemangledNativeBuiltin<"work_group_barrier", OpenCL_std, Barrier, 1, 3, OpControlBarrier>; +defm : DemangledNativeBuiltin<"__spirv_ControlBarrier", OpenCL_std, Barrier, 3, 3, OpControlBarrier>; // Kernel enqueue builtin records: defm : DemangledNativeBuiltin<"__enqueue_kernel_basic", OpenCL_std, Enqueue, 5, 5, OpEnqueueKernel>; defm : DemangledNativeBuiltin<"__enqueue_kernel_basic_events", OpenCL_std, Enqueue, 8, 8, OpEnqueueKernel>; defm : DemangledNativeBuiltin<"__enqueue_kernel_varargs", OpenCL_std, Enqueue, 7, 7, OpEnqueueKernel>; defm : DemangledNativeBuiltin<"__enqueue_kernel_events_varargs", OpenCL_std, Enqueue, 10, 10, OpEnqueueKernel>; +defm : DemangledNativeBuiltin<"__spirv_EnqueueKernel", OpenCL_std, Enqueue, 10, 0, OpEnqueueKernel>; defm : DemangledNativeBuiltin<"retain_event", OpenCL_std, Enqueue, 1, 1, OpRetainEvent>; +defm : DemangledNativeBuiltin<"__spirv_RetainEvent", OpenCL_std, Enqueue, 1, 1, OpRetainEvent>; defm : DemangledNativeBuiltin<"release_event", OpenCL_std, Enqueue, 1, 1, OpReleaseEvent>; +defm : DemangledNativeBuiltin<"__spirv_ReleaseEvent", OpenCL_std, Enqueue, 1, 1, OpReleaseEvent>; defm : DemangledNativeBuiltin<"create_user_event", OpenCL_std, Enqueue, 0, 0, OpCreateUserEvent>; +defm : DemangledNativeBuiltin<"__spirv_CreateUserEvent", OpenCL_std, Enqueue, 0, 0, OpCreateUserEvent>; defm : DemangledNativeBuiltin<"is_valid_event", OpenCL_std, Enqueue, 1, 1, OpIsValidEvent>; +defm : DemangledNativeBuiltin<"__spirv_IsValidEvent", OpenCL_std, Enqueue, 1, 1, OpIsValidEvent>; defm : DemangledNativeBuiltin<"set_user_event_status", OpenCL_std, Enqueue, 2, 2, OpSetUserEventStatus>; +defm : DemangledNativeBuiltin<"__spirv_SetUserEventStatus", OpenCL_std, Enqueue, 2, 2, OpSetUserEventStatus>; defm : DemangledNativeBuiltin<"capture_event_profiling_info", OpenCL_std, Enqueue, 3, 3, OpCaptureEventProfilingInfo>; +defm : DemangledNativeBuiltin<"__spirv_CaptureEventProfilingInfo", OpenCL_std, Enqueue, 3, 3, OpCaptureEventProfilingInfo>; defm : DemangledNativeBuiltin<"get_default_queue", OpenCL_std, Enqueue, 0, 0, OpGetDefaultQueue>; +defm : DemangledNativeBuiltin<"__spirv_GetDefaultQueue", OpenCL_std, Enqueue, 0, 0, OpGetDefaultQueue>; defm : DemangledNativeBuiltin<"ndrange_1D", OpenCL_std, Enqueue, 1, 3, OpBuildNDRange>; defm : DemangledNativeBuiltin<"ndrange_2D", OpenCL_std, Enqueue, 1, 3, OpBuildNDRange>; defm : DemangledNativeBuiltin<"ndrange_3D", OpenCL_std, Enqueue, 1, 3, OpBuildNDRange>; @@ -562,7 +584,9 @@ defm : DemangledNativeBuiltin<"__spirv_SpecConstantComposite", OpenCL_std, SpecC // Async Copy and Prefetch builtin records: defm : DemangledNativeBuiltin<"async_work_group_copy", OpenCL_std, AsyncCopy, 4, 4, OpGroupAsyncCopy>; +defm : DemangledNativeBuiltin<"__spirv_GroupAsyncCopy", OpenCL_std, AsyncCopy, 4, 4, OpGroupAsyncCopy>; defm : DemangledNativeBuiltin<"wait_group_events", OpenCL_std, AsyncCopy, 2, 2, OpGroupWaitEvents>; +defm : DemangledNativeBuiltin<"__spirv_GroupWaitEvents", OpenCL_std, AsyncCopy, 2, 2, OpGroupWaitEvents>; // Load and store builtin records: defm : DemangledNativeBuiltin<"__spirv_Load", OpenCL_std, LoadStore, 1, 3, OpLoad>; diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 0fef19c2d534..5bb8f6084f96 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -26,10 +26,33 @@ #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/IR/IntrinsicsSPIRV.h" #include "llvm/Support/Debug.h" +namespace llvm { + +class SPIRVMachineModuleInfo : public MachineModuleInfoImpl { +public: + SyncScope::ID Work_ItemSSID; + SyncScope::ID WorkGroupSSID; + SyncScope::ID DeviceSSID; + SyncScope::ID AllSVMDevicesSSID; + SyncScope::ID SubGroupSSID; + + SPIRVMachineModuleInfo(const MachineModuleInfo &MMI) { + LLVMContext &CTX = MMI.getModule()->getContext(); + Work_ItemSSID = CTX.getOrInsertSyncScopeID("work_item"); + WorkGroupSSID = CTX.getOrInsertSyncScopeID("workgroup"); + DeviceSSID = CTX.getOrInsertSyncScopeID("device"); + AllSVMDevicesSSID = CTX.getOrInsertSyncScopeID("all_svm_devices"); + SubGroupSSID = CTX.getOrInsertSyncScopeID("sub_group"); + } +}; + +} // end namespace llvm + #define DEBUG_TYPE "spirv-isel" using namespace llvm; @@ -52,6 +75,7 @@ class SPIRVInstructionSelector : public InstructionSelector { const RegisterBankInfo &RBI; SPIRVGlobalRegistry &GR; MachineRegisterInfo *MRI; + SPIRVMachineModuleInfo *MMI = nullptr; /// We need to keep track of the number we give to anonymous global values to /// generate the same name every time when this is needed. @@ -233,6 +257,7 @@ void SPIRVInstructionSelector::setupMF(MachineFunction &MF, GISelKnownBits *KB, CodeGenCoverage *CoverageInfo, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) { + MMI = &MF.getMMI().getObjFileInfo<SPIRVMachineModuleInfo>(); MRI = &MF.getRegInfo(); GR.setCurrentFunc(MF); InstructionSelector::setupMF(MF, KB, CoverageInfo, PSI, BFI); @@ -613,15 +638,27 @@ bool SPIRVInstructionSelector::selectBitcast(Register ResVReg, return selectUnOp(ResVReg, ResType, I, SPIRV::OpBitcast); } -static SPIRV::Scope::Scope getScope(SyncScope::ID Ord) { - switch (Ord) { - case SyncScope::SingleThread: +static SPIRV::Scope::Scope getScope(SyncScope::ID Ord, + SPIRVMachineModuleInfo *MMI) { + if (Ord == SyncScope::SingleThread || Ord == MMI->Work_ItemSSID) return SPIRV::Scope::Invocation; - case SyncScope::System: + else if (Ord == SyncScope::System || Ord == MMI->DeviceSSID) + return SPIRV::Scope::Device; + else if (Ord == MMI->WorkGroupSSID) + return SPIRV::Scope::Workgroup; + else if (Ord == MMI->AllSVMDevicesSSID) + return SPIRV::Scope::CrossDevice; + else if (Ord == MMI->SubGroupSSID) + return SPIRV::Scope::Subgroup; + else + // OpenCL approach is: "The functions that do not have memory_scope argument + // have the same semantics as the corresponding functions with the + // memory_scope argument set to memory_scope_device." See ref.: // + // https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_C.html#atomic-functions + // In our case if the scope is unknown, assuming that SPIR-V code is to be + // consumed in an OpenCL environment, we use the same approach and set the + // scope to memory_scope_device. return SPIRV::Scope::Device; - default: - llvm_unreachable("Unsupported synchronization Scope ID."); - } } static void addMemoryOperands(MachineMemOperand *MemOp, @@ -773,7 +810,8 @@ bool SPIRVInstructionSelector::selectAtomicRMW(Register ResVReg, unsigned NegateOpcode) const { assert(I.hasOneMemOperand()); const MachineMemOperand *MemOp = *I.memoperands_begin(); - uint32_t Scope = static_cast<uint32_t>(getScope(MemOp->getSyncScopeID())); + uint32_t Scope = + static_cast<uint32_t>(getScope(MemOp->getSyncScopeID(), MMI)); Register ScopeReg = buildI32Constant(Scope, I); Register Ptr = I.getOperand(1).getReg(); @@ -844,7 +882,7 @@ bool SPIRVInstructionSelector::selectFence(MachineInstr &I) const { uint32_t MemSem = static_cast<uint32_t>(getMemSemantics(AO)); Register MemSemReg = buildI32Constant(MemSem, I); SyncScope::ID Ord = SyncScope::ID(I.getOperand(1).getImm()); - uint32_t Scope = static_cast<uint32_t>(getScope(Ord)); + uint32_t Scope = static_cast<uint32_t>(getScope(Ord, MMI)); Register ScopeReg = buildI32Constant(Scope, I); MachineBasicBlock &BB = *I.getParent(); return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpMemoryBarrier)) @@ -863,7 +901,8 @@ bool SPIRVInstructionSelector::selectAtomicCmpXchg(Register ResVReg, if (!isa<GIntrinsic>(I)) { assert(I.hasOneMemOperand()); const MachineMemOperand *MemOp = *I.memoperands_begin(); - unsigned Scope = static_cast<uint32_t>(getScope(MemOp->getSyncScopeID())); + unsigned Scope = + static_cast<uint32_t>(getScope(MemOp->getSyncScopeID(), MMI)); ScopeReg = buildI32Constant(Scope, I); unsigned ScSem = static_cast<uint32_t>( @@ -1189,12 +1228,34 @@ bool SPIRVInstructionSelector::selectConstVector(Register ResVReg, return MIB.constrainAllUses(TII, TRI, RBI); } +static unsigned getArrayComponentCount(MachineRegisterInfo *MRI, + const SPIRVType *ResType) { + Register OpReg = ResType->getOperand(2).getReg(); + SPIRVType *OpDef = MRI->getVRegDef(OpReg); + if (!OpDef) + return 0; + if (OpDef->getOpcode() == SPIRV::ASSIGN_TYPE && + OpDef->getOperand(1).isReg()) { + if (SPIRVType *RefDef = MRI->getVRegDef(OpDef->getOperand(1).getReg())) + OpDef = RefDef; + } + unsigned N = OpDef->getOpcode() == TargetOpcode::G_CONSTANT + ? OpDef->getOperand(1).getCImm()->getValue().getZExtValue() + : 0; + return N; +} + bool SPIRVInstructionSelector::selectSplatVector(Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const { - if (ResType->getOpcode() != SPIRV::OpTypeVector) + unsigned N = 0; + if (ResType->getOpcode() == SPIRV::OpTypeVector) + N = GR.getScalarOrVectorComponentCount(ResType); + else if (ResType->getOpcode() == SPIRV::OpTypeArray) + N = getArrayComponentCount(MRI, ResType); + else report_fatal_error("Cannot select G_SPLAT_VECTOR with a non-vector result"); - unsigned N = GR.getScalarOrVectorComponentCount(ResType); + unsigned OpIdx = I.getNumExplicitDefs(); if (!I.getOperand(OpIdx).isReg()) report_fatal_error("Unexpected argument in G_SPLAT_VECTOR"); diff --git a/llvm/test/CodeGen/SPIRV/empty-logical.ll b/llvm/test/CodeGen/SPIRV/empty-logical.ll index a99df5f7eaaa..1c6604006e2c 100644 --- a/llvm/test/CodeGen/SPIRV/empty-logical.ll +++ b/llvm/test/CodeGen/SPIRV/empty-logical.ll @@ -1,4 +1,5 @@ ; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} ;; Ensure the required Capabilities are listed. ; CHECK-DAG: OpCapability Shader diff --git a/llvm/test/CodeGen/SPIRV/empty-module.ll b/llvm/test/CodeGen/SPIRV/empty-module.ll index f220176a4099..b56e58ccaf8f 100644 --- a/llvm/test/CodeGen/SPIRV/empty-module.ll +++ b/llvm/test/CodeGen/SPIRV/empty-module.ll @@ -1,4 +1,5 @@ ; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} ; CHECK-DAG: OpCapability Addresses ; CHECK-DAG: OpCapability Linkage diff --git a/llvm/test/CodeGen/SPIRV/empty-opencl32.ll b/llvm/test/CodeGen/SPIRV/empty-opencl32.ll index a373781e290b..8e826ec35f37 100644 --- a/llvm/test/CodeGen/SPIRV/empty-opencl32.ll +++ b/llvm/test/CodeGen/SPIRV/empty-opencl32.ll @@ -1,4 +1,5 @@ ; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} ;; FIXME: ensure Magic Number, version number, generator's magic number, "bound" and "schema" are at least present diff --git a/llvm/test/CodeGen/SPIRV/empty-opencl64.ll b/llvm/test/CodeGen/SPIRV/empty-opencl64.ll index d10196525368..4eaa2e4af0fc 100644 --- a/llvm/test/CodeGen/SPIRV/empty-opencl64.ll +++ b/llvm/test/CodeGen/SPIRV/empty-opencl64.ll @@ -1,4 +1,5 @@ ; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} ;; FIXME: ensure Magic Number, version number, generator's magic number, "bound" and "schema" are at least present diff --git a/llvm/test/CodeGen/SPIRV/empty.ll b/llvm/test/CodeGen/SPIRV/empty.ll index fdcf316b0256..390ab329aea3 100644 --- a/llvm/test/CodeGen/SPIRV/empty.ll +++ b/llvm/test/CodeGen/SPIRV/empty.ll @@ -1,4 +1,5 @@ ; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} ; CHECK: OpCapability Addresses ; CHECK: "foo" diff --git a/llvm/test/CodeGen/SPIRV/fence.ll b/llvm/test/CodeGen/SPIRV/fence.ll new file mode 100644 index 000000000000..5da58667f24f --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/fence.ll @@ -0,0 +1,54 @@ +; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: OpName %[[#GetScope:]] "_Z8getScopev" +; CHECK-DAG: %[[#Long:]] = OpTypeInt 32 0 +; CHECK-DAG: %[[#ScopeDevice:]] = OpConstant %[[#Long]] 1 +; CHECK-DAG: %[[#WrkGrpConst2:]] = OpConstant %[[#Long]] 2 +; CHECK-DAG: %[[#Const3:]] = OpConstant %[[#Long]] 3 +; CHECK-DAG: %[[#InvocationConst4:]] = OpConstant %[[#Long]] 4 +; CHECK-DAG: %[[#Const8:]] = OpConstant %[[#Long]] 8 +; CHECK-DAG: %[[#Const16:]] = OpConstant %[[#Long]] 16 +; CHECK-DAG: %[[#Const912:]] = OpConstant %[[#Long]] 912 +; CHECK: OpMemoryBarrier %[[#ScopeDevice]] %[[#WrkGrpConst2]] +; CHECK: OpMemoryBarrier %[[#ScopeDevice]] %[[#InvocationConst4]] +; CHECK: OpMemoryBarrier %[[#ScopeDevice]] %[[#Const8]] +; CHECK: OpMemoryBarrier %[[#InvocationConst4]] %[[#Const16]] +; CHECK: OpMemoryBarrier %[[#WrkGrpConst2]] %[[#InvocationConst4]] +; CHECK: OpFunctionEnd +; CHECK: %[[#ScopeId:]] = OpFunctionCall %[[#Long]] %[[#GetScope]] +; CHECK: OpControlBarrier %[[#Const3]] %[[#ScopeId:]] %[[#Const912]] + +define spir_kernel void @fence_test_kernel1(ptr addrspace(1) noalias %s.ascast) { + fence acquire + ret void +} + +define spir_kernel void @fence_test_kernel2(ptr addrspace(1) noalias %s.ascast) { + fence release + ret void +} + +define spir_kernel void @fence_test_kernel3(ptr addrspace(1) noalias %s.ascast) { + fence acq_rel + ret void +} + +define spir_kernel void @fence_test_kernel4(ptr addrspace(1) noalias %s.ascast) { + fence syncscope("singlethread") seq_cst + ret void +} + +define spir_kernel void @fence_test_kernel5(ptr addrspace(1) noalias %s.ascast) { + fence syncscope("workgroup") release + ret void +} + +define spir_func void @barrier_test1() { + %scope = call noundef i32 @_Z8getScopev() + call void @_Z22__spirv_ControlBarrieriii(i32 noundef 3, i32 noundef %scope, i32 noundef 912) + ret void +} + +declare spir_func void @_Z22__spirv_ControlBarrieriii(i32 noundef, i32 noundef, i32 noundef) +declare spir_func i32 @_Z8getScopev() -- GitLab From f676e84bba016157f5879fa66d86737ac8920c4b Mon Sep 17 00:00:00 2001 From: Jason Eckhardt <jeckhardt@nvidia.com> Date: Wed, 20 Mar 2024 13:32:38 -0500 Subject: [PATCH 295/307] [TableGen] Fix operand constraint checking problem. (#85859) Currently operand constraint checks on "$dest = $src" are inadvertently accepting any token that contains "=". This has surprising results, e.g, "$dest != $src" is accepted as a constraint but then treated as "=". This patch ensures that only exactly the token "=" is accepted. --- llvm/test/TableGen/ConstraintChecking3.td | 2 +- llvm/test/TableGen/ConstraintChecking8.td | 34 ++++++++++++++++++++++ llvm/utils/TableGen/CodeGenInstruction.cpp | 4 ++- 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 llvm/test/TableGen/ConstraintChecking8.td diff --git a/llvm/test/TableGen/ConstraintChecking3.td b/llvm/test/TableGen/ConstraintChecking3.td index 2d5fe6b7ef96..886e6d52a039 100644 --- a/llvm/test/TableGen/ConstraintChecking3.td +++ b/llvm/test/TableGen/ConstraintChecking3.td @@ -4,5 +4,5 @@ include "ConstraintChecking.inc" // (This is illegal because the '=' has to be surrounded by whitespace) -// CHECK: [[FILE]]:[[@LINE+1]]:5: error: Illegal format for tied-to constraint in 'Foo' +// CHECK: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '$dest1=$dest2' in 'Foo' def Foo : TestInstructionWithConstraints<"$dest1=$dest2">; diff --git a/llvm/test/TableGen/ConstraintChecking8.td b/llvm/test/TableGen/ConstraintChecking8.td new file mode 100644 index 000000000000..37d35150911e --- /dev/null +++ b/llvm/test/TableGen/ConstraintChecking8.td @@ -0,0 +1,34 @@ +// RUN: not llvm-tblgen -gen-asm-writer -DT0 -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s +// RUN: not llvm-tblgen -gen-asm-writer -DT1 -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s --check-prefix=CHECK1 +// RUN: not llvm-tblgen -gen-asm-writer -DT2 -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s --check-prefix=CHECK2 +// RUN: not llvm-tblgen -gen-asm-writer -DT3 -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s --check-prefix=CHECK3 +// RUN: not llvm-tblgen -gen-asm-writer -DT4 -I %p -I %p/../../include %s 2>&1 | FileCheck %s -DFILE=%s --check-prefix=CHECK4 + +include "ConstraintChecking.inc" + +// Make sure exactly the token "=" appears. + +#ifdef T0 +// CHECK: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '$dest1 != $src2' in 'Foo' +def Foo : TestInstructionWithConstraints<"$dest1 != $src2">; +#endif + +#ifdef T1 +// CHECK1: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '$dest1 == $src2' in 'Foo' +def Foo : TestInstructionWithConstraints<"$dest1 == $src2">; +#endif + +#ifdef T2 +// CHECK2: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '= $rhs' in 'Foo' +def Foo : TestInstructionWithConstraints<"= $rhs">; +#endif + +#ifdef T3 +// CHECK3: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '$lhs =' in 'Foo' +def Foo : TestInstructionWithConstraints<"$lhs =">; +#endif + +#ifdef T4 +// CHECK4: [[FILE]]:[[@LINE+1]]:5: error: Unrecognized constraint '=' in 'Foo' +def Foo : TestInstructionWithConstraints<"=">; +#endif diff --git a/llvm/utils/TableGen/CodeGenInstruction.cpp b/llvm/utils/TableGen/CodeGenInstruction.cpp index b00b95da5fc2..18a4e7b0f18b 100644 --- a/llvm/utils/TableGen/CodeGenInstruction.cpp +++ b/llvm/utils/TableGen/CodeGenInstruction.cpp @@ -325,7 +325,9 @@ static void ParseConstraint(StringRef CStr, CGIOperandList &Ops, Record *Rec) { // Only other constraint is "TIED_TO" for now. StringRef::size_type pos = CStr.find_first_of('='); - if (pos == StringRef::npos) + if (pos == StringRef::npos || pos == 0 || + CStr.find_first_of(" \t", pos) != (pos + 1) || + CStr.find_last_of(" \t", pos) != (pos - 1)) PrintFatalError(Rec->getLoc(), "Unrecognized constraint '" + CStr + "' in '" + Rec->getName() + "'"); start = CStr.find_first_not_of(" \t"); -- GitLab From 891172d9be01dd7c7e5298f2d8fdb143add448da Mon Sep 17 00:00:00 2001 From: Craig Topper <craig.topper@sifive.com> Date: Wed, 20 Mar 2024 11:35:19 -0700 Subject: [PATCH 296/307] [RISCV] Use 'riscv-isa' module flag to set ELF flags and attributes. (#85155) Walk all the ISA strings and set the subtarget bits for any extension we find in any string. This allows LTO output to have a ELF attributes from the union of all of the files used to compile it. --- llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 32 ++++++++++++++++--- .../CodeGen/RISCV/attributes-module-flag.ll | 17 ++++++++++ llvm/test/CodeGen/RISCV/module-elf-flags.ll | 13 ++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/RISCV/attributes-module-flag.ll create mode 100644 llvm/test/CodeGen/RISCV/module-elf-flags.ll diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index cb82e74b1efa..5bf594c0b5ea 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -100,7 +100,7 @@ public: bool emitDirectiveOptionArch(); private: - void emitAttributes(); + void emitAttributes(const MCSubtargetInfo &SubtargetInfo); void emitNTLHint(const MachineInstr *MI); @@ -385,8 +385,32 @@ void RISCVAsmPrinter::emitStartOfAsmFile(Module &M) { if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(M.getModuleFlag("target-abi"))) RTS.setTargetABI(RISCVABI::getTargetABI(ModuleTargetABI->getString())); + + MCSubtargetInfo SubtargetInfo = *TM.getMCSubtargetInfo(); + + // Use module flag to update feature bits. + if (auto *MD = dyn_cast_or_null<MDNode>(M.getModuleFlag("riscv-isa"))) { + for (auto &ISA : MD->operands()) { + if (auto *ISAString = dyn_cast_or_null<MDString>(ISA)) { + auto ParseResult = llvm::RISCVISAInfo::parseArchString( + ISAString->getString(), /*EnableExperimentalExtension=*/true, + /*ExperimentalExtensionVersionCheck=*/true); + if (!errorToBool(ParseResult.takeError())) { + auto &ISAInfo = *ParseResult; + for (const auto &Feature : RISCVFeatureKV) { + if (ISAInfo->hasExtension(Feature.Key) && + !SubtargetInfo.hasFeature(Feature.Value)) + SubtargetInfo.ToggleFeature(Feature.Key); + } + } + } + } + + RTS.setFlagsFromFeatures(SubtargetInfo); + } + if (TM.getTargetTriple().isOSBinFormatELF()) - emitAttributes(); + emitAttributes(SubtargetInfo); } void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) { @@ -398,13 +422,13 @@ void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) { EmitHwasanMemaccessSymbols(M); } -void RISCVAsmPrinter::emitAttributes() { +void RISCVAsmPrinter::emitAttributes(const MCSubtargetInfo &SubtargetInfo) { RISCVTargetStreamer &RTS = static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer()); // Use MCSubtargetInfo from TargetMachine. Individual functions may have // attributes that differ from other functions in the module and we have no // way to know which function is correct. - RTS.emitTargetAttributes(*TM.getMCSubtargetInfo(), /*EmitStackAlign*/ true); + RTS.emitTargetAttributes(SubtargetInfo, /*EmitStackAlign*/ true); } void RISCVAsmPrinter::emitFunctionEntryLabel() { diff --git a/llvm/test/CodeGen/RISCV/attributes-module-flag.ll b/llvm/test/CodeGen/RISCV/attributes-module-flag.ll new file mode 100644 index 000000000000..4580539fbb29 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/attributes-module-flag.ll @@ -0,0 +1,17 @@ +; RUN: llc -mtriple=riscv32 %s -o - | FileCheck %s --check-prefix=RV32 +; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s --check-prefix=RV64 + +; Test generation of ELF attribute from module metadata + +; RV32: .attribute 5, "rv32i2p1_m2p0_zba1p0" +; RV64: .attribute 5, "rv64i2p1_m2p0_zba1p0" + +define i32 @addi(i32 %a) { + %1 = add i32 %a, 1 + ret i32 %1 +} + +!llvm.module.flags = !{!0} + +!0 = !{i32 6, !"riscv-isa", !1} +!1 = !{!"rv64i2p1_m2p0", !"rv64i2p1_zba1p0"} diff --git a/llvm/test/CodeGen/RISCV/module-elf-flags.ll b/llvm/test/CodeGen/RISCV/module-elf-flags.ll new file mode 100644 index 000000000000..1b4bc9fd5466 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/module-elf-flags.ll @@ -0,0 +1,13 @@ +; RUN: llc -mtriple=riscv32 -filetype=obj < %s | llvm-readelf -h - | FileCheck -check-prefixes=FLAGS %s + +; FLAGS: Flags: 0x11, RVC, TSO + +define i32 @addi(i32 %a) { + %1 = add i32 %a, 1 + ret i32 %1 +} + +!llvm.module.flags = !{!0} + +!0 = !{i32 6, !"riscv-isa", !1} +!1 = !{!"rv64i2p1_c2p0_ztso0p1"} -- GitLab From 3f39571228fe2cf402e6ea5727cd5b32f9299356 Mon Sep 17 00:00:00 2001 From: "S. Bharadwaj Yadavalli" <Bharadwaj.Yadavalli@microsoft.com> Date: Wed, 20 Mar 2024 14:48:16 -0400 Subject: [PATCH 297/307] [DirectX][DXIL] Distinguish return type for overload type resolution. (#85646) Return type of DXIL Ops may be different from valid overload type of the parameters, if any. Such DXIL Ops are correctly represented in DXIL.td. However, DXILEmitter assumes the return type to be the same as parameter overload type, if one exists. This results in generation in incorrect overload index value in DXILOperation.inc for the DXIL Op and incorrect DXIL operation function call in DXILOpLowering pass. This change distinguishes return types correctly from parameter overload types in DXILEmitter backend to handle such DXIL ops. Add specification for DXIL Op `isinf` and corresponding tests to verify the above change. Fixes issue #85125 --- llvm/lib/Target/DirectX/DXIL.td | 3 ++ llvm/lib/Target/DirectX/DXILOpBuilder.cpp | 43 +++++++++++----------- llvm/lib/Target/DirectX/DXILOpBuilder.h | 8 +++- llvm/lib/Target/DirectX/DXILOpLowering.cpp | 7 +--- llvm/test/CodeGen/DirectX/isinf.ll | 25 +++++++++++++ llvm/test/CodeGen/DirectX/isinf_error.ll | 13 +++++++ llvm/utils/TableGen/DXILEmitter.cpp | 14 ++++++- 7 files changed, 83 insertions(+), 30 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/isinf.ll create mode 100644 llvm/test/CodeGen/DirectX/isinf_error.ll diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td index 216fa5b10c8f..36eb29d53766 100644 --- a/llvm/lib/Target/DirectX/DXIL.td +++ b/llvm/lib/Target/DirectX/DXIL.td @@ -255,6 +255,9 @@ class DXILOpMapping<int opCode, DXILOpClass opClass, } // Concrete definition of DXIL Operation mapping to corresponding LLVM intrinsic +def IsInf : DXILOpMapping<9, isSpecialFloat, int_dx_isinf, + "Determines if the specified value is infinite.", + [llvm_i1_ty, llvm_halforfloat_ty]>; def Sin : DXILOpMapping<13, unary, int_sin, "Returns sine(theta) for theta in radians.", [llvm_halforfloat_ty, LLVMMatchType<0>]>; diff --git a/llvm/lib/Target/DirectX/DXILOpBuilder.cpp b/llvm/lib/Target/DirectX/DXILOpBuilder.cpp index 11b24d044923..a1eacc2d4800 100644 --- a/llvm/lib/Target/DirectX/DXILOpBuilder.cpp +++ b/llvm/lib/Target/DirectX/DXILOpBuilder.cpp @@ -229,13 +229,13 @@ static Type *getTypeFromParameterKind(ParameterKind Kind, Type *OverloadTy) { /// its specification in DXIL.td. /// \param OverloadTy Return type to be used to construct DXIL function type. static FunctionType *getDXILOpFunctionType(const OpCodeProperty *Prop, - Type *OverloadTy) { + Type *ReturnTy, Type *OverloadTy) { SmallVector<Type *> ArgTys; auto ParamKinds = getOpCodeParameterKind(*Prop); - // Add OverloadTy as return type of the function - ArgTys.emplace_back(OverloadTy); + // Add ReturnTy as return type of the function + ArgTys.emplace_back(ReturnTy); // Add DXIL Opcode value type viz., Int32 as first argument ArgTys.emplace_back(Type::getInt32Ty(OverloadTy->getContext())); @@ -249,34 +249,33 @@ static FunctionType *getDXILOpFunctionType(const OpCodeProperty *Prop, ArgTys[0], ArrayRef<Type *>(&ArgTys[1], ArgTys.size() - 1), false); } -static FunctionCallee getOrCreateDXILOpFunction(dxil::OpCode DXILOp, - Type *OverloadTy, Module &M) { - const OpCodeProperty *Prop = getOpCodeProperty(DXILOp); +namespace llvm { +namespace dxil { + +CallInst *DXILOpBuilder::createDXILOpCall(dxil::OpCode OpCode, Type *ReturnTy, + Type *OverloadTy, + llvm::iterator_range<Use *> Args) { + const OpCodeProperty *Prop = getOpCodeProperty(OpCode); OverloadKind Kind = getOverloadKind(OverloadTy); if ((Prop->OverloadTys & (uint16_t)Kind) == 0) { report_fatal_error("Invalid Overload Type", /* gen_crash_diag=*/false); } - std::string FnName = constructOverloadName(Kind, OverloadTy, *Prop); - // Dependent on name to dedup. - if (auto *Fn = M.getFunction(FnName)) - return FunctionCallee(Fn); - - FunctionType *DXILOpFT = getDXILOpFunctionType(Prop, OverloadTy); - return M.getOrInsertFunction(FnName, DXILOpFT); -} - -namespace llvm { -namespace dxil { - -CallInst *DXILOpBuilder::createDXILOpCall(dxil::OpCode OpCode, Type *OverloadTy, - llvm::iterator_range<Use *> Args) { - auto Fn = getOrCreateDXILOpFunction(OpCode, OverloadTy, M); + std::string DXILFnName = constructOverloadName(Kind, OverloadTy, *Prop); + FunctionCallee DXILFn; + // Get the function with name DXILFnName, if one exists + if (auto *Func = M.getFunction(DXILFnName)) { + DXILFn = FunctionCallee(Func); + } else { + // Construct and add a function with name DXILFnName + FunctionType *DXILOpFT = getDXILOpFunctionType(Prop, ReturnTy, OverloadTy); + DXILFn = M.getOrInsertFunction(DXILFnName, DXILOpFT); + } SmallVector<Value *> FullArgs; FullArgs.emplace_back(B.getInt32((int32_t)OpCode)); FullArgs.append(Args.begin(), Args.end()); - return B.CreateCall(Fn, FullArgs); + return B.CreateCall(DXILFn, FullArgs); } Type *DXILOpBuilder::getOverloadTy(dxil::OpCode OpCode, FunctionType *FT) { diff --git a/llvm/lib/Target/DirectX/DXILOpBuilder.h b/llvm/lib/Target/DirectX/DXILOpBuilder.h index 1c15f109184a..f3abcc6e02a4 100644 --- a/llvm/lib/Target/DirectX/DXILOpBuilder.h +++ b/llvm/lib/Target/DirectX/DXILOpBuilder.h @@ -29,7 +29,13 @@ namespace dxil { class DXILOpBuilder { public: DXILOpBuilder(Module &M, IRBuilderBase &B) : M(M), B(B) {} - CallInst *createDXILOpCall(dxil::OpCode OpCode, Type *OverloadTy, + /// Create an instruction that calls DXIL Op with return type, specified + /// opcode, and call arguments. \param OpCode Opcode of the DXIL Op call + /// constructed \param ReturnTy Return type of the DXIL Op call constructed + /// \param OverloadTy Overload type of the DXIL Op call constructed + /// \return DXIL Op call constructed + CallInst *createDXILOpCall(dxil::OpCode OpCode, Type *ReturnTy, + Type *OverloadTy, llvm::iterator_range<Use *> Args); Type *getOverloadTy(dxil::OpCode OpCode, FunctionType *FT); static const char *getOpCodeName(dxil::OpCode DXILOp); diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp index e5c2042e7d16..3e334b0ec298 100644 --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -32,7 +32,6 @@ using namespace llvm::dxil; static void lowerIntrinsic(dxil::OpCode DXILOp, Function &F, Module &M) { IRBuilder<> B(M.getContext()); - Value *DXILOpArg = B.getInt32(static_cast<unsigned>(DXILOp)); DXILOpBuilder DXILB(M, B); Type *OverloadTy = DXILB.getOverloadTy(DXILOp, F.getFunctionType()); for (User *U : make_early_inc_range(F.users())) { @@ -40,11 +39,9 @@ static void lowerIntrinsic(dxil::OpCode DXILOp, Function &F, Module &M) { if (!CI) continue; - SmallVector<Value *> Args; - Args.emplace_back(DXILOpArg); - Args.append(CI->arg_begin(), CI->arg_end()); B.SetInsertPoint(CI); - CallInst *DXILCI = DXILB.createDXILOpCall(DXILOp, OverloadTy, CI->args()); + CallInst *DXILCI = DXILB.createDXILOpCall(DXILOp, F.getReturnType(), + OverloadTy, CI->args()); CI->replaceAllUsesWith(DXILCI); CI->eraseFromParent(); diff --git a/llvm/test/CodeGen/DirectX/isinf.ll b/llvm/test/CodeGen/DirectX/isinf.ll new file mode 100644 index 000000000000..e2975da90bfc --- /dev/null +++ b/llvm/test/CodeGen/DirectX/isinf.ll @@ -0,0 +1,25 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for isinf are generated for float and half. +; CHECK: call i1 @dx.op.isSpecialFloat.f32(i32 9, float %{{.*}}) +; CHECK: call i1 @dx.op.isSpecialFloat.f16(i32 9, half %{{.*}}) + +; Function Attrs: noinline nounwind optnone +define noundef i1 @isinf_float(float noundef %a) #0 { +entry: + %a.addr = alloca float, align 4 + store float %a, ptr %a.addr, align 4 + %0 = load float, ptr %a.addr, align 4 + %dx.isinf = call i1 @llvm.dx.isinf.f32(float %0) + ret i1 %dx.isinf +} + +; Function Attrs: noinline nounwind optnone +define noundef i1 @isinf_half(half noundef %p0) #0 { +entry: + %p0.addr = alloca half, align 2 + store half %p0, ptr %p0.addr, align 2 + %0 = load half, ptr %p0.addr, align 2 + %dx.isinf = call i1 @llvm.dx.isinf.f16(half %0) + ret i1 %dx.isinf +} diff --git a/llvm/test/CodeGen/DirectX/isinf_error.ll b/llvm/test/CodeGen/DirectX/isinf_error.ll new file mode 100644 index 000000000000..95b2d0cabcc4 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/isinf_error.ll @@ -0,0 +1,13 @@ +; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s + +; DXIL operation isinf does not support double overload type +; CHECK: LLVM ERROR: Invalid Overload Type + +define noundef i1 @isinf_double(double noundef %a) #0 { +entry: + %a.addr = alloca double, align 8 + store double %a, ptr %a.addr, align 8 + %0 = load double, ptr %a.addr, align 8 + %dx.isinf = call i1 @llvm.dx.isinf.f64(double %0) + ret i1 %dx.isinf +} diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp index 59089929837e..af1efb8aa99f 100644 --- a/llvm/utils/TableGen/DXILEmitter.cpp +++ b/llvm/utils/TableGen/DXILEmitter.cpp @@ -119,7 +119,7 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) { // Populate OpTypes with return type and parameter types // Parameter indices of overloaded parameters. - // This vector contains overload parameters in the order order used to + // This vector contains overload parameters in the order used to // resolve an LLVMMatchType in accordance with convention outlined in // the comment before the definition of class LLVMMatchType in // llvm/IR/Intrinsics.td @@ -398,10 +398,20 @@ static void emitDXILOperationTable(std::vector<DXILOperationDesc> &Ops, OS << " static const OpCodeProperty OpCodeProps[] = {\n"; for (auto &Op : Ops) { + // Consider Op.OverloadParamIndex as the overload parameter index, by + // default + auto OLParamIdx = Op.OverloadParamIndex; + // If no overload parameter index is set, treat first parameter type as + // overload type - unless the Op has no parameters, in which case treat the + // return type - as overload parameter to emit the appropriate overload kind + // enum. + if (OLParamIdx < 0) { + OLParamIdx = (Op.OpTypes.size() > 1) ? 1 : 0; + } OS << " { dxil::OpCode::" << Op.OpName << ", " << OpStrings.get(Op.OpName) << ", OpCodeClass::" << Op.OpClass << ", " << OpClassStrings.get(Op.OpClass.data()) << ", " - << getOverloadKindStr(Op.OpTypes[0]) << ", " + << getOverloadKindStr(Op.OpTypes[OLParamIdx]) << ", " << emitDXILOperationAttr(Op.OpAttributes) << ", " << Op.OverloadParamIndex << ", " << Op.OpTypes.size() - 1 << ", " << Parameters.get(ParameterMap[Op.OpClass]) << " },\n"; -- GitLab From 2e817bfb4890249d1f5c0e50827d1d742c4f3df4 Mon Sep 17 00:00:00 2001 From: Min-Yih Hsu <min.hsu@sifive.com> Date: Wed, 20 Mar 2024 12:03:01 -0700 Subject: [PATCH 298/307] [RISCV] Add missing feature predicates to some of the RVV pseudos (#85983) Some of the RVV pseudos are missing HasVInstructions. This is effectively a NFC. --- llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td index ae93bf694875..8be4c7741ca1 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td @@ -6698,6 +6698,7 @@ defm PseudoVFWREDOSUM : VPseudoVFWREDO_VS_RM; // 15. Vector Mask Instructions //===----------------------------------------------------------------------===// +let Predicates = [HasVInstructions] in { //===----------------------------------------------------------------------===// // 15.1 Vector Mask-Register Logical Instructions //===----------------------------------------------------------------------===// @@ -6718,7 +6719,6 @@ defm PseudoVMSET : VPseudoNullaryPseudoM<"VMXNOR">; //===----------------------------------------------------------------------===// // 15.2. Vector mask population count vcpop //===----------------------------------------------------------------------===// - let IsSignExtendingOpW = 1 in defm PseudoVCPOP: VPseudoVPOP_M; @@ -6753,6 +6753,7 @@ defm PseudoVIOTA_M: VPseudoVIOTA_M; // 15.9. Vector Element Index Instruction //===----------------------------------------------------------------------===// defm PseudoVID : VPseudoVID_V; +} // Predicates = [HasVInstructions] //===----------------------------------------------------------------------===// // 16. Vector Permutation Instructions @@ -6828,6 +6829,7 @@ let Predicates = [HasVInstructionsAnyF] in { //===----------------------------------------------------------------------===// // 16.4. Vector Register Gather Instructions //===----------------------------------------------------------------------===// +let Predicates = [HasVInstructions] in { defm PseudoVRGATHER : VPseudoVGTR_VV_VX_VI<uimm5, "@earlyclobber $rd">; defm PseudoVRGATHEREI16 : VPseudoVGTR_VV_EEW<eew=16, Constraint="@earlyclobber $rd">; @@ -6836,6 +6838,7 @@ defm PseudoVRGATHEREI16 : VPseudoVGTR_VV_EEW<eew=16, // 16.5. Vector Compress Instruction //===----------------------------------------------------------------------===// defm PseudoVCOMPRESS : VPseudoVCPR_V; +} // Predicates = [HasVInstructions] //===----------------------------------------------------------------------===// // Patterns. -- GitLab From 7955bde64ef9aebbcaf6b6308a25fac31041ea9a Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aaron@aaronballman.com> Date: Wed, 20 Mar 2024 15:07:23 -0400 Subject: [PATCH 299/307] [C11] Add test coverage for N1310 and claim conformance This is about the best I could do for testing that `signed char` does not have any padding bits. --- clang/test/C/C11/n1310.c | 31 +++++++++++++++++++++++++++++++ clang/www/c_status.html | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 clang/test/C/C11/n1310.c diff --git a/clang/test/C/C11/n1310.c b/clang/test/C/C11/n1310.c new file mode 100644 index 000000000000..7f8dd754f746 --- /dev/null +++ b/clang/test/C/C11/n1310.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -verify -std=c89 %s +// RUN: %clang_cc1 -verify -std=c99 %s +// RUN: %clang_cc1 -verify -std=c11 %s +// RUN: %clang_cc1 -verify -std=c17 %s +// RUN: %clang_cc1 -verify -std=c23 %s +// expected-no-diagnostics + +/* WG14 N1310: Yes + * Requiring signed char to have no padding bits + */ + +/* This is shockingly hard to test, but we're trying our best by checking that + * setting each bit of an unsigned char, then bit-casting it to signed char, + * results in a value we expect to see. If we have padding bits, then it's + * possible (but not mandatory) for the value to not be as we expect, so a + * failing assertion means the implementation is broken but a passing test does + * not *prove* there aren't padding bits. + */ +_Static_assert(__CHAR_BIT__ == 8, ""); +_Static_assert(sizeof(signed char) == 1, ""); + +#define TEST(Bit, Expected) __builtin_bit_cast(signed char, (unsigned char)(1 << Bit)) == Expected +_Static_assert(TEST(0, 1), ""); +_Static_assert(TEST(1, 2), ""); +_Static_assert(TEST(2, 4), ""); +_Static_assert(TEST(3, 8), ""); +_Static_assert(TEST(4, 16), ""); +_Static_assert(TEST(5, 32), ""); +_Static_assert(TEST(6, 64), ""); +_Static_assert(TEST(7, (signed char)128), ""); + diff --git a/clang/www/c_status.html b/clang/www/c_status.html index 9e4600b3e66a..b1f5ab4cbc4f 100644 --- a/clang/www/c_status.html +++ b/clang/www/c_status.html @@ -411,7 +411,7 @@ conformance.</p> <tr> <td>Requiring signed char to have no padding bits</td> <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1310.htm">N1310</a></td> - <td class="unknown" align="center">Unknown</td> + <td class="full" align="center">Yes</td> </tr> <tr> <td>Initializing static or external variables</td> -- GitLab From d9c4c312d81b4a2059d0ca2bb454c3452e52042e Mon Sep 17 00:00:00 2001 From: Zahira Ammarguellat <zahira.ammarguellat@intel.com> Date: Wed, 20 Mar 2024 12:14:09 -0700 Subject: [PATCH 300/307] [CLANG] Full support of complex multiplication and division. (#81514) In clang there are two options `-f[no]cx-limited-range` and `-f[no]cx-fortran-rules` that control the range of complex multiplication and division. However, it is unclear how these options interact with one another. For instance, what should happen when the users compile with `-fcx-fortran-rules -fno-cx-limited-range` or `-fcx-limited-range -fno-cx-fortran-rules`? In this patch we are introducing a new option to solve the issue and give a greater flexibility to the user to control the behavior of the compiler when performing multiplication and division of complex floating-point values. `-fcomplex-arihmetic=[full|improved|promoted|basic]` `full`: Implementation of complex division and multiplication using a call to runtime library functions (generally the case, but the BE might sometimes replace the library call if it knows enough about the potential range of the inputs). Overflow and non-finite values are handled by the library implementation. For the case of multiplication overflow will occur in accordance with normal floating-point rules. This is the default value. `improved`: Implementation of complex division using the Smith algorithm at source precision. Smith's algorithm for complex division. See SMITH, R. L. Algorithm 116: Complex division. Commun. ACM 5, 8 (1962). This value offers improved handling for overflow in intermediate calculations, but overflow may occur. NaN and infinite values are not handled in some cases. `promoted`: Implementation of complex division using algebraic formulas at higher precision. Overflow is handled. Non-finite values are handled in some cases. If the target does not have native support for a higher precision data type, the implementation for the complex operation using the Smith algorithm will be used. Overflow may still occur in some cases. NaN and infinite values are not handled. `basic`: Implementation of complex division and multiplication using algebraic formulas at source precision. No special handling to avoid overflow. NaN and infinite values are not handled. `fcx-limited-range` will alias `-fcomplex-arithmetic=basic` `-fcx-fortran-rules` will alias `-fcomplex-arithmetic=improved` `-fno-cx-limited-range` and `-fno-cx-fortran-rules` will alias `-fcomplex-arithmetic=full` The complex division and multiplication will be implemented as follows depending on the option used. <html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"> <head> <meta name=ProgId content=Word.Document> <meta name=Generator content="Microsoft Word 15"> <meta name=Originator content="Microsoft Word 15"> <link rel=File-List href="file:///C:/Users/zahiraam/AppData/Local/Temp/msohtmlclip1/01/clip_filelist.xml"> <!--[if gte mso 9]><xml> <o:OfficeDocumentSettings> <o:AllowPNG/> </o:OfficeDocumentSettings> </xml><![endif]--> <link rel=themeData href="file:///C:/Users/zahiraam/AppData/Local/Temp/msohtmlclip1/01/clip_themedata.thmx"> <link rel=colorSchemeMapping href="file:///C:/Users/zahiraam/AppData/Local/Temp/msohtmlclip1/01/clip_colorschememapping.xml"> <!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:TrackMoves/> <w:TrackFormatting/> <w:PunctuationKerning/> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:DoNotPromoteQF/> <w:LidThemeOther>EN-US</w:LidThemeOther> <w:LidThemeAsian>X-NONE</w:LidThemeAsian> <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> <w:Compatibility> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:SplitPgBreakAndParaMark/> <w:EnableOpenTypeKerning/> <w:DontFlipMirrorIndents/> <w:OverrideTableStyleHps/> </w:Compatibility> <m:mathPr> <m:mathFont m:val="Cambria Math"/> <m:brkBin m:val="before"/> <m:brkBinSub m:val="--"/> <m:smallFrac m:val="off"/> <m:dispDef/> <m:lMargin m:val="0"/> <m:rMargin m:val="0"/> <m:defJc m:val="centerGroup"/> <m:wrapIndent m:val="1440"/> <m:intLim m:val="subSup"/> <m:naryLim m:val="undOvr"/> </m:mathPr></w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="false" DefSemiHidden="false" DefQFormat="false" DefPriority="99" LatentStyleCount="376"> <w:LsdException Locked="false" Priority="0" QFormat="true" Name="Normal"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 1"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 2"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 3"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 4"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 5"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 6"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 7"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 8"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 9"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 6"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 7"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 8"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 9"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 1"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 2"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 3"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 4"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 5"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 6"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 7"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 8"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 9"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Normal Indent"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="footnote text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="annotation text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="header"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="footer"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index heading"/> <w:LsdException Locked="false" Priority="35" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="caption"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="table of figures"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="envelope address"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="envelope return"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="footnote reference"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="annotation reference"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="line number"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="page number"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="endnote reference"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="endnote text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="table of authorities"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="macro"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="toa heading"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 5"/> <w:LsdException Locked="false" Priority="10" QFormat="true" Name="Title"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Closing"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Signature"/> <w:LsdException Locked="false" Priority="1" SemiHidden="true" UnhideWhenUsed="true" Name="Default Paragraph Font"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text Indent"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Message Header"/> <w:LsdException Locked="false" Priority="11" QFormat="true" Name="Subtitle"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Salutation"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Date"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text First Indent"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text First Indent 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Note Heading"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text Indent 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text Indent 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Block Text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Hyperlink"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="FollowedHyperlink"/> <w:LsdException Locked="false" Priority="22" QFormat="true" Name="Strong"/> <w:LsdException Locked="false" Priority="20" QFormat="true" Name="Emphasis"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Document Map"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Plain Text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="E-mail Signature"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Top of Form"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Bottom of Form"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Normal (Web)"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Acronym"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Address"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Cite"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Code"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Definition"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Keyboard"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Preformatted"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Sample"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Typewriter"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Variable"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Normal Table"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="annotation subject"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="No List"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Outline List 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Outline List 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Outline List 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Simple 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Simple 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Simple 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Colorful 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Colorful 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Colorful 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 6"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 7"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 8"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 6"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 7"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 8"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table 3D effects 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table 3D effects 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table 3D effects 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Contemporary"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Elegant"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Professional"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Subtle 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Subtle 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Web 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Web 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Web 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Balloon Text"/> <w:LsdException Locked="false" Priority="39" Name="Table Grid"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Theme"/> <w:LsdException Locked="false" SemiHidden="true" Name="Placeholder Text"/> <w:LsdException Locked="false" Priority="1" QFormat="true" Name="No Spacing"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading"/> <w:LsdException Locked="false" Priority="61" Name="Light List"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3"/> <w:LsdException Locked="false" Priority="70" Name="Dark List"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 1"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 1"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 1"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 1"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 1"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 1"/> <w:LsdException Locked="false" SemiHidden="true" Name="Revision"/> <w:LsdException Locked="false" Priority="34" QFormat="true" Name="List Paragraph"/> <w:LsdException Locked="false" Priority="29" QFormat="true" Name="Quote"/> <w:LsdException Locked="false" Priority="30" QFormat="true" Name="Intense Quote"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 1"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 1"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 1"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 1"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 1"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 1"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 1"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 1"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 2"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 2"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 2"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 2"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 2"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 2"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 2"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 2"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 2"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 2"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 2"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 2"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 2"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 2"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 3"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 3"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 3"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 3"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 3"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 3"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 3"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 3"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 3"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 3"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 3"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 3"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 3"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 3"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 4"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 4"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 4"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 4"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 4"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 4"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 4"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 4"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 4"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 4"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 4"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 4"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 4"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 4"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 5"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 5"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 5"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 5"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 5"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 5"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 5"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 5"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 5"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 5"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 5"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 5"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 5"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 5"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 6"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 6"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 6"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 6"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 6"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 6"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 6"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 6"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 6"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 6"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 6"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 6"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 6"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 6"/> <w:LsdException Locked="false" Priority="19" QFormat="true" Name="Subtle Emphasis"/> <w:LsdException Locked="false" Priority="21" QFormat="true" Name="Intense Emphasis"/> <w:LsdException Locked="false" Priority="31" QFormat="true" Name="Subtle Reference"/> <w:LsdException Locked="false" Priority="32" QFormat="true" Name="Intense Reference"/> <w:LsdException Locked="false" Priority="33" QFormat="true" Name="Book Title"/> <w:LsdException Locked="false" Priority="37" SemiHidden="true" UnhideWhenUsed="true" Name="Bibliography"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="TOC Heading"/> <w:LsdException Locked="false" Priority="41" Name="Plain Table 1"/> <w:LsdException Locked="false" Priority="42" Name="Plain Table 2"/> <w:LsdException Locked="false" Priority="43" Name="Plain Table 3"/> <w:LsdException Locked="false" Priority="44" Name="Plain Table 4"/> <w:LsdException Locked="false" Priority="45" Name="Plain Table 5"/> <w:LsdException Locked="false" Priority="40" Name="Grid Table Light"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 1"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 1"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 1"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 1"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 1"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 1"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 1"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 2"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 2"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 2"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 2"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 2"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 2"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 2"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 3"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 3"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 3"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 3"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 3"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 3"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 3"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 4"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 4"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 4"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 4"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 4"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 4"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 4"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 5"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 5"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 5"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 5"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 5"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 5"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 5"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 6"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 6"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 6"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 6"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 6"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 6"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 6"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 1"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 1"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 1"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 1"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 1"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 1"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 1"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 2"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 2"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 2"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 2"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 2"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 2"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 2"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 3"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 3"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 3"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 3"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 3"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 3"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 3"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 4"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 4"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 4"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 4"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 4"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 4"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 4"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 5"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 5"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 5"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 5"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 5"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 5"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 5"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 6"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 6"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 6"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 6"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 6"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 6"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 6"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Mention"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Smart Hyperlink"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Hashtag"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Unresolved Mention"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Smart Link"/> </w:LatentStyles> </xml><![endif]--> <style> <!-- /* Font Definitions */ @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:-536869121 1107305727 33554432 0 415 0;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-469750017 -1040178053 9 0 511 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin-top:0in; margin-right:0in; margin-bottom:8.0pt; margin-left:0in; line-height:107%; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri",sans-serif; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:Calibri; mso-fareast-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt; mso-ligatures:standardcontextual;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; font-family:"Calibri",sans-serif; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:Calibri; mso-fareast-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;} .MsoPapDefault {mso-style-type:export-only; margin-bottom:8.0pt; line-height:107%;} @page WordSection1 {size:8.5in 11.0in; margin:1.0in 1.0in 1.0in 1.0in; mso-header-margin:.5in; mso-footer-margin:.5in; mso-paper-source:0;} div.WordSection1 {page:WordSection1;} --> </style> <!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin-top:0in; mso-para-margin-right:0in; mso-para-margin-bottom:8.0pt; mso-para-margin-left:0in; line-height:107%; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri",sans-serif; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt; mso-ligatures:standardcontextual;} </style> <![endif]--> </head> <body lang=EN-US style='tab-interval:.5in;word-wrap:break-word'> <!--StartFragment--> -fcomplex-arithmetic | div | mul -- | -- | -- basic | algebraic form | algebraic form improved | smith's algorithm | algebraic form full | libcall | libcall + nan processing promoted | algebraic form + higher precision | algebraic form <!--EndFragment--> </body> </html> --- clang/docs/UsersManual.rst | 45 +- .../clang/Basic/DiagnosticCommonKinds.td | 5 + clang/include/clang/Basic/LangOptions.h | 33 +- clang/include/clang/Driver/Options.td | 37 +- clang/lib/CodeGen/CGExprComplex.cpp | 83 +- clang/lib/Driver/ToolChains/Clang.cpp | 173 +- clang/lib/Parse/ParsePragma.cpp | 11 +- clang/test/CodeGen/X86/cx-complex-range.c | 1425 +++++++ clang/test/CodeGen/complex-math.c | 2 +- clang/test/CodeGen/cx-complex-range.c | 3519 ++++++++++++++++- clang/test/CodeGen/pragma-cx-limited-range.c | 224 +- clang/test/CodeGen/smiths-complex-div.c | 104 +- clang/test/Driver/range.c | 169 +- 13 files changed, 5518 insertions(+), 312 deletions(-) create mode 100644 clang/test/CodeGen/X86/cx-complex-range.c diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 7a63d720241a..129e75fc9a78 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1847,19 +1847,50 @@ floating point semantic models: precise (the default), strict, and fast. * ``16`` - Forces ``_Float16`` operations to be emitted without using excess precision arithmetic. +.. option:: -fcomplex-arithmetic=<value>: + + This option specifies the implementation for complex multiplication and division. + + Valid values are: ``basic``, ``improved``, ``full`` and ``promoted``. + + * ``basic`` Implementation of complex division and multiplication using + algebraic formulas at source precision. No special handling to avoid + overflow. NaN and infinite values are not handled. + * ``improved`` Implementation of complex division using the Smith algorithm + at source precision. Smith's algorithm for complex division. + See SMITH, R. L. Algorithm 116: Complex division. Commun. ACM 5, 8 (1962). + This value offers improved handling for overflow in intermediate + calculations, but overflow may occur. NaN and infinite values are not + handled in some cases. + * ``full`` Implementation of complex division and multiplication using a + call to runtime library functions (generally the case, but the BE might + sometimes replace the library call if it knows enough about the potential + range of the inputs). Overflow and non-finite values are handled by the + library implementation. For the case of multiplication overflow will occur in + accordance with normal floating-point rules. This is the default value. + * ``promoted`` Implementation of complex division using algebraic formulas at + higher precision. Overflow is handled. Non-finite values are handled in some + cases. If the target does not have native support for a higher precision + data type, the implementation for the complex operation using the Smith + algorithm will be used. Overflow may still occur in some cases. NaN and + infinite values are not handled. + .. option:: -fcx-limited-range: - This option enables the naive mathematical formulas for complex division and - multiplication with no NaN checking of results. The default is - ``-fno-cx-limited-range``, but this option is enabled by the ``-ffast-math`` + This option is aliased to ``-fcomplex-arithmetic=basic``. It enables the + naive mathematical formulas for complex division and multiplication with no + NaN checking of results. The default is ``-fno-cx-limited-range`` aliased to + ``-fcomplex-arithmetic=full``. This option is enabled by the ``-ffast-math`` option. .. option:: -fcx-fortran-rules: - This option enables the naive mathematical formulas for complex - multiplication and enables application of Smith's algorithm for complex - division. See SMITH, R. L. Algorithm 116: Complex division. Commun. - ACM 5, 8 (1962). The default is ``-fno-cx-fortran-rules``. + This option is aliased to ``-fcomplex-arithmetic=improved``. It enables the + naive mathematical formulas for complex multiplication and enables application + of Smith's algorithm for complex division. See SMITH, R. L. Algorithm 116: + Complex division. Commun. ACM 5, 8 (1962). + The default is ``-fno-cx-fortran-rules`` aliased to + ``-fcomplex-arithmetic=full``. .. _floating-point-environment: diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 43e132e56658..a52bf62e2420 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -45,6 +45,11 @@ def note_using : Note<"using">; def note_possibility : Note<"one possibility">; def note_also_found : Note<"also found">; +def warn_next_larger_fp_type_same_size_than_fp : Warning< + "higher precision floating-point type size has the same size than " + "floating-point type size">, + InGroup<DiagGroup<"higher-precision-fp">>; + // Parse && Lex let CategoryName = "Lexical or Preprocessor Issue" in { diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 08fc706e3cbf..24b109e32cdd 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -396,7 +396,38 @@ public: IncompleteOnly = 3, }; - enum ComplexRangeKind { CX_Full, CX_Limited, CX_Fortran, CX_None }; + /// Controls the various implementations for complex multiplication and + // division. + enum ComplexRangeKind { + /// Implementation of complex division and multiplication using a call to + /// runtime library functions(generally the case, but the BE might + /// sometimes replace the library call if it knows enough about the + /// potential range of the inputs). Overflow and non-finite values are + /// handled by the library implementation. This is the default value. + CX_Full, + + /// Implementation of complex division offering an improved handling + /// for overflow in intermediate calculations with no special handling for + /// NaN and infinite values. + CX_Improved, + + /// Implementation of complex division using algebraic formulas at + /// higher precision. Overflow is handled. Non-finite values are handled in + /// some cases. If the target hardware does not have native support for a + /// higher precision data type, an implementation for the complex operation + /// will be used to provide improved guards against intermediate overflow, + /// but overflow and underflow may still occur in some cases. NaN and + /// infinite values are not handled. + CX_Promoted, + + /// Implementation of complex division and multiplication using + /// algebraic formulas at source precision. No special handling to avoid + /// overflow. NaN and infinite values are not handled. + CX_Basic, + + /// No range rule is enabled. + CX_None + }; // Define simple language options (with no accessors). #define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 9b5125ecfed8..4a954258ce40 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1046,30 +1046,29 @@ defm offload_uniform_block : BoolFOption<"offload-uniform-block", NegFlag<SetFalse, [], [ClangOption, CC1Option], "Don't assume">, BothFlags<[], [ClangOption], " that kernels are launched with uniform block sizes (default true for CUDA/HIP and false otherwise)">>; -def fcx_limited_range : Joined<["-"], "fcx-limited-range">, - Group<f_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Basic algebraic expansions of complex arithmetic operations " - "involving are enabled.">; - -def fno_cx_limited_range : Joined<["-"], "fno-cx-limited-range">, - Group<f_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Basic algebraic expansions of complex arithmetic operations " - "involving are disabled.">; - -def fcx_fortran_rules : Joined<["-"], "fcx-fortran-rules">, - Group<f_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Range reduction is enabled for complex arithmetic operations.">; - -def fno_cx_fortran_rules : Joined<["-"], "fno-cx-fortran-rules">, - Group<f_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Range reduction is disabled for complex arithmetic operations.">; +def fcomplex_arithmetic_EQ : Joined<["-"], "fcomplex-arithmetic=">, Group<f_Group>, + Visibility<[ClangOption, CC1Option]>, + Values<"full,improved,promoted,basic">, NormalizedValuesScope<"LangOptions">, + NormalizedValues<["CX_Full", "CX_Improved", "CX_Promoted", "CX_Basic"]>; def complex_range_EQ : Joined<["-"], "complex-range=">, Group<f_Group>, Visibility<[CC1Option]>, - Values<"full,limited,fortran">, NormalizedValuesScope<"LangOptions">, - NormalizedValues<["CX_Full", "CX_Limited", "CX_Fortran"]>, + Values<"full,improved,promoted,basic">, NormalizedValuesScope<"LangOptions">, + NormalizedValues<["CX_Full", "CX_Improved", "CX_Promoted", "CX_Basic"]>, MarshallingInfoEnum<LangOpts<"ComplexRange">, "CX_Full">; +defm cx_limited_range: BoolOptionWithoutMarshalling<"f", "cx-limited-range", + PosFlag<SetTrue, [], [ClangOption, CC1Option], "Basic algebraic expansions of " + "complex arithmetic operations involving are enabled.">, + NegFlag<SetFalse, [], [ClangOption, CC1Option], "Basic algebraic expansions " + "of complex arithmetic operations involving are disabled.">>; + +defm cx_fortran_rules: BoolOptionWithoutMarshalling<"f", "cx-fortran-rules", + PosFlag<SetTrue, [], [ClangOption, CC1Option], "Range reduction is enabled for " + "complex arithmetic operations.">, + NegFlag<SetFalse, [], [ClangOption, CC1Option], "Range reduction is disabled " + "for complex arithmetic operations">>; + // OpenCL-only Options def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 0266ba934da6..27ddaacc28f5 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -51,11 +51,12 @@ class ComplexExprEmitter CGBuilderTy &Builder; bool IgnoreReal; bool IgnoreImag; -public: - ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false) - : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii) { - } + bool FPHasBeenPromoted; +public: + ComplexExprEmitter(CodeGenFunction &cgf, bool ir = false, bool ii = false) + : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii), + FPHasBeenPromoted(false) {} //===--------------------------------------------------------------------===// // Utilities @@ -287,9 +288,54 @@ public: ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName, const BinOpInfo &Op); - QualType getPromotionType(QualType Ty) { + QualType GetHigherPrecisionFPType(QualType ElementType) { + const auto *CurrentBT = dyn_cast<BuiltinType>(ElementType); + switch (CurrentBT->getKind()) { + case BuiltinType::Kind::Float16: + return CGF.getContext().FloatTy; + case BuiltinType::Kind::Float: + case BuiltinType::Kind::BFloat16: + return CGF.getContext().DoubleTy; + case BuiltinType::Kind::Double: + return CGF.getContext().LongDoubleTy; + default: + return ElementType; + } + } + + QualType HigherPrecisionTypeForComplexArithmetic(QualType ElementType, + bool IsDivOpCode) { + QualType HigherElementType = GetHigherPrecisionFPType(ElementType); + const llvm::fltSemantics &ElementTypeSemantics = + CGF.getContext().getFloatTypeSemantics(ElementType); + const llvm::fltSemantics &HigherElementTypeSemantics = + CGF.getContext().getFloatTypeSemantics(HigherElementType); + // Check that the promoted type can handle the intermediate values without + // overflowing. This can be interpreted as: + // (SmallerType.LargestFiniteVal * SmallerType.LargestFiniteVal) * 2 <= + // LargerType.LargestFiniteVal. + // In terms of exponent it gives this formula: + // (SmallerType.LargestFiniteVal * SmallerType.LargestFiniteVal + // doubles the exponent of SmallerType.LargestFiniteVal) + if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <= + llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) { + return CGF.getContext().getComplexType(HigherElementType); + } else { + FPHasBeenPromoted = true; + DiagnosticsEngine &Diags = CGF.CGM.getDiags(); + Diags.Report(diag::warn_next_larger_fp_type_same_size_than_fp); + return CGF.getContext().getComplexType(ElementType); + } + } + + QualType getPromotionType(QualType Ty, bool IsDivOpCode = false) { if (auto *CT = Ty->getAs<ComplexType>()) { QualType ElementType = CT->getElementType(); + if (IsDivOpCode && ElementType->isFloatingType() && + CGF.getLangOpts().getComplexRange() == + LangOptions::ComplexRangeKind::CX_Promoted) + return HigherPrecisionTypeForComplexArithmetic(ElementType, + IsDivOpCode); if (ElementType.UseExcessPrecision(CGF.getContext())) return CGF.getContext().getComplexType(CGF.getContext().FloatTy); } @@ -300,11 +346,12 @@ public: #define HANDLEBINOP(OP) \ ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \ - QualType promotionTy = getPromotionType(E->getType()); \ + QualType promotionTy = getPromotionType( \ + E->getType(), \ + (E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false); \ ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \ if (!promotionTy.isNull()) \ - result = \ - CGF.EmitUnPromotedValue(result, E->getType()); \ + result = CGF.EmitUnPromotedValue(result, E->getType()); \ return result; \ } @@ -794,8 +841,9 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { ResR = Builder.CreateFSub(AC, BD, "mul_r"); ResI = Builder.CreateFAdd(AD, BC, "mul_i"); - if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Limited || - Op.FPFeatures.getComplexRange() == LangOptions::CX_Fortran) + if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Basic || + Op.FPFeatures.getComplexRange() == LangOptions::CX_Improved || + Op.FPFeatures.getComplexRange() == LangOptions::CX_Promoted) return ComplexPairTy(ResR, ResI); // Emit the test for the real part becoming NaN and create a branch to @@ -986,14 +1034,17 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { llvm::Value *OrigLHSi = LHSi; if (!LHSi) LHSi = llvm::Constant::getNullValue(RHSi->getType()); - if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Fortran) + QualType ComplexElementTy = Op.Ty->castAs<ComplexType>()->getElementType(); + if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Improved || + (Op.FPFeatures.getComplexRange() == LangOptions::CX_Promoted && + FPHasBeenPromoted)) return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi); - else if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Limited) + else if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Basic || + Op.FPFeatures.getComplexRange() == LangOptions::CX_Promoted) return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi); - else if (!CGF.getLangOpts().FastMath || - // '-ffast-math' is used in the command line but followed by an - // '-fno-cx-limited-range'. - Op.FPFeatures.getComplexRange() == LangOptions::CX_Full) { + // '-ffast-math' is used in the command line but followed by an + // '-fno-cx-limited-range' or '-fcomplex-arithmetic=full'. + else if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Full) { LHSi = OrigLHSi; // If we have a complex operand on the RHS and FastMath is not allowed, we // delegate to a libcall to handle all of the complexities and minimize diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index bcdf2737bc7a..bc9cc8ce6cf5 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2687,60 +2687,43 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, } } -static StringRef EnumComplexRangeToStr(LangOptions::ComplexRangeKind Range, - StringRef Option) { +static std::string ComplexRangeKindToStr(LangOptions::ComplexRangeKind Range) { switch (Range) { - case LangOptions::ComplexRangeKind::CX_Limited: - return "-fcx-limited-range"; + case LangOptions::ComplexRangeKind::CX_Full: + return "full"; break; - case LangOptions::ComplexRangeKind::CX_Fortran: - return "-fcx-fortran-rules"; + case LangOptions::ComplexRangeKind::CX_Basic: + return "basic"; break; - default: - return Option; + case LangOptions::ComplexRangeKind::CX_Improved: + return "improved"; + break; + case LangOptions::ComplexRangeKind::CX_Promoted: + return "promoted"; break; + default: + return ""; } } -static void EmitComplexRangeDiag(const Driver &D, - LangOptions::ComplexRangeKind Range1, - LangOptions::ComplexRangeKind Range2, - StringRef Option = StringRef()) { - if (Range1 != Range2 && Range1 != LangOptions::ComplexRangeKind::CX_None) { - bool NegateFortranOption = false; - bool NegateLimitedOption = false; - if (!Option.empty()) { - NegateFortranOption = - Range1 == LangOptions::ComplexRangeKind::CX_Fortran && - Option == "-fno-cx-fortran-rules"; - NegateLimitedOption = - Range1 == LangOptions::ComplexRangeKind::CX_Limited && - Option == "-fno-cx-limited-range"; - } - if (Option.empty() || - (!Option.empty() && !NegateFortranOption && !NegateLimitedOption)) - D.Diag(clang::diag::warn_drv_overriding_option) - << EnumComplexRangeToStr(Range1, Option) - << EnumComplexRangeToStr(Range2, Option); +static std::string ComplexArithmeticStr(LangOptions::ComplexRangeKind Range) { + return (Range == LangOptions::ComplexRangeKind::CX_None) + ? "" + : "-fcomplex-arithmetic=" + ComplexRangeKindToStr(Range); +} + +static void EmitComplexRangeDiag(const Driver &D, std::string str1, + std::string str2) { + if ((str1.compare(str2) != 0) && !str2.empty() && !str1.empty()) { + D.Diag(clang::diag::warn_drv_overriding_option) << str1 << str2; } } static std::string RenderComplexRangeOption(LangOptions::ComplexRangeKind Range) { - std::string ComplexRangeStr = "-complex-range="; - switch (Range) { - case LangOptions::ComplexRangeKind::CX_Full: - ComplexRangeStr += "full"; - break; - case LangOptions::ComplexRangeKind::CX_Limited: - ComplexRangeStr += "limited"; - break; - case LangOptions::ComplexRangeKind::CX_Fortran: - ComplexRangeStr += "fortran"; - break; - default: - assert(0 && "Unexpected range option"); - } + std::string ComplexRangeStr = ComplexRangeKindToStr(Range); + if (!ComplexRangeStr.empty()) + return "-complex-range=" + ComplexRangeStr; return ComplexRangeStr; } @@ -2792,6 +2775,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, StringRef BFloat16ExcessPrecision = ""; LangOptions::ComplexRangeKind Range = LangOptions::ComplexRangeKind::CX_None; std::string ComplexRangeStr = ""; + std::string GccRangeComplexOption = ""; // Lambda to set fast-math options. This is also used by -ffp-model=fast auto applyFastMath = [&]() { @@ -2807,9 +2791,19 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, FPExceptionBehavior = ""; // If fast-math is set then set the fp-contract mode to fast. FPContract = "fast"; - // ffast-math enables limited range rules for complex multiplication and + // ffast-math enables basic range rules for complex multiplication and // division. - Range = LangOptions::ComplexRangeKind::CX_Limited; + // Warn if user expects to perform full implementation of complex + // multiplication or division in the presence of nan or ninf flags. + if (Range == LangOptions::ComplexRangeKind::CX_Full || + Range == LangOptions::ComplexRangeKind::CX_Improved || + Range == LangOptions::ComplexRangeKind::CX_Promoted) + EmitComplexRangeDiag( + D, ComplexArithmeticStr(Range), + !GccRangeComplexOption.empty() + ? GccRangeComplexOption + : ComplexArithmeticStr(LangOptions::ComplexRangeKind::CX_Basic)); + Range = LangOptions::ComplexRangeKind::CX_Basic; SeenUnsafeMathModeOption = true; }; @@ -2824,26 +2818,87 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, switch (optID) { default: break; - case options::OPT_fcx_limited_range: { - EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Limited); - Range = LangOptions::ComplexRangeKind::CX_Limited; + case options::OPT_fcx_limited_range: + if (GccRangeComplexOption.empty()) { + if (Range != LangOptions::ComplexRangeKind::CX_Basic) + EmitComplexRangeDiag(D, RenderComplexRangeOption(Range), + "-fcx-limited-range"); + } else { + if (GccRangeComplexOption != "-fno-cx-limited-range") + EmitComplexRangeDiag(D, GccRangeComplexOption, "-fcx-limited-range"); + } + GccRangeComplexOption = "-fcx-limited-range"; + Range = LangOptions::ComplexRangeKind::CX_Basic; break; - } case options::OPT_fno_cx_limited_range: - EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full, - "-fno-cx-limited-range"); + if (GccRangeComplexOption.empty()) { + EmitComplexRangeDiag(D, RenderComplexRangeOption(Range), + "-fno-cx-limited-range"); + } else { + if (GccRangeComplexOption.compare("-fcx-limited-range") != 0 && + GccRangeComplexOption.compare("-fno-cx-fortran-rules") != 0) + EmitComplexRangeDiag(D, GccRangeComplexOption, + "-fno-cx-limited-range"); + } + GccRangeComplexOption = "-fno-cx-limited-range"; Range = LangOptions::ComplexRangeKind::CX_Full; break; - case options::OPT_fcx_fortran_rules: { - EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Fortran); - Range = LangOptions::ComplexRangeKind::CX_Fortran; + case options::OPT_fcx_fortran_rules: + if (GccRangeComplexOption.empty()) + EmitComplexRangeDiag(D, RenderComplexRangeOption(Range), + "-fcx-fortran-rules"); + else + EmitComplexRangeDiag(D, GccRangeComplexOption, "-fcx-fortran-rules"); + GccRangeComplexOption = "-fcx-fortran-rules"; + Range = LangOptions::ComplexRangeKind::CX_Improved; break; - } case options::OPT_fno_cx_fortran_rules: - EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full, - "-fno-cx-fortran-rules"); + if (GccRangeComplexOption.empty()) { + EmitComplexRangeDiag(D, RenderComplexRangeOption(Range), + "-fno-cx-fortran-rules"); + } else { + if (GccRangeComplexOption != "-fno-cx-limited-range") + EmitComplexRangeDiag(D, GccRangeComplexOption, + "-fno-cx-fortran-rules"); + } + GccRangeComplexOption = "-fno-cx-fortran-rules"; Range = LangOptions::ComplexRangeKind::CX_Full; break; + case options::OPT_fcomplex_arithmetic_EQ: { + LangOptions::ComplexRangeKind RangeVal; + StringRef Val = A->getValue(); + if (Val.equals("full")) + RangeVal = LangOptions::ComplexRangeKind::CX_Full; + else if (Val.equals("improved")) + RangeVal = LangOptions::ComplexRangeKind::CX_Improved; + else if (Val.equals("promoted")) + RangeVal = LangOptions::ComplexRangeKind::CX_Promoted; + else if (Val.equals("basic")) + RangeVal = LangOptions::ComplexRangeKind::CX_Basic; + else { + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getSpelling() << Val; + break; + } + if (!GccRangeComplexOption.empty()) { + if (GccRangeComplexOption.compare("-fcx-limited-range") != 0) { + if (GccRangeComplexOption.compare("-fcx-fortran-rules") != 0) { + if (RangeVal != LangOptions::ComplexRangeKind::CX_Improved) + EmitComplexRangeDiag(D, GccRangeComplexOption, + ComplexArithmeticStr(RangeVal)); + } else { + EmitComplexRangeDiag(D, GccRangeComplexOption, + ComplexArithmeticStr(RangeVal)); + } + } else { + if (RangeVal != LangOptions::ComplexRangeKind::CX_Basic) + EmitComplexRangeDiag(D, GccRangeComplexOption, + ComplexArithmeticStr(RangeVal)); + } + } + Range = RangeVal; + break; + } case options::OPT_ffp_model_EQ: { // If -ffp-model= is seen, reset to fno-fast-math HonorINFs = true; @@ -3256,8 +3311,12 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, if (Range != LangOptions::ComplexRangeKind::CX_None) ComplexRangeStr = RenderComplexRangeOption(Range); - if (!ComplexRangeStr.empty()) + if (!ComplexRangeStr.empty()) { CmdArgs.push_back(Args.MakeArgString(ComplexRangeStr)); + if (Args.hasArg(options::OPT_fcomplex_arithmetic_EQ)) + CmdArgs.push_back(Args.MakeArgString("-fcomplex-arithmetic=" + + ComplexRangeKindToStr(Range))); + } if (Args.hasArg(options::OPT_fcx_limited_range)) CmdArgs.push_back("-fcx-limited-range"); if (Args.hasArg(options::OPT_fcx_fortran_rules)) diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 730ac1a0fee5..0f692e2146a4 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -844,6 +844,11 @@ void Parser::HandlePragmaFPContract() { FPC = LangOptions::FPM_Off; break; case tok::OOS_DEFAULT: + // According to ISO C99 standard chapter 7.3.4, the default value + // for the pragma is ``off'. '-fcomplex-arithmetic=basic', + // '-fcx-limited-range', '-fcx-fortran-rules' and + // '-fcomplex-arithmetic=improved' control the default value of these + // pragmas. FPC = getLangOpts().getDefaultFPContractMode(); break; } @@ -909,15 +914,15 @@ void Parser::HandlePragmaCXLimitedRange() { LangOptions::ComplexRangeKind Range; switch (OOS) { case tok::OOS_ON: - Range = LangOptions::CX_Limited; + Range = LangOptions::CX_Basic; break; case tok::OOS_OFF: Range = LangOptions::CX_Full; break; case tok::OOS_DEFAULT: // According to ISO C99 standard chapter 7.3.4, the default value - // for the pragma is ``off'. -fcx-limited-range and -fcx-fortran-rules - // control the default value of these pragmas. + // for the pragma is ``off'. -fcomplex-arithmetic controls the default value + // of these pragmas. Range = getLangOpts().getComplexRange(); break; } diff --git a/clang/test/CodeGen/X86/cx-complex-range.c b/clang/test/CodeGen/X86/cx-complex-range.c new file mode 100644 index 000000000000..fa46576266a2 --- /dev/null +++ b/clang/test/CodeGen/X86/cx-complex-range.c @@ -0,0 +1,1425 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -o - | FileCheck %s --check-prefix=FULL + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -complex-range=basic -o - | FileCheck %s --check-prefix=BASIC + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -fno-cx-limited-range -o - | FileCheck %s --check-prefix=FULL + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -complex-range=improved -o - | FileCheck %s --check-prefix=IMPRVD + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -complex-range=promoted -o - | FileCheck %s --check-prefix=PRMTD + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -complex-range=full -o - | FileCheck %s --check-prefix=FULL + +// RUN: %clang_cc1 -triple x86_64-windows-pc -complex-range=promoted \ +// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=X86WINPRMTD + +// Fast math +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ +// RUN: -ffast-math -complex-range=basic -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=BASIC_FAST + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ +// RUN: -ffast-math -complex-range=full -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=FULL_FAST + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -fno-cx-fortran-rules -o - | FileCheck %s --check-prefix=FULL + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ +// RUN: -ffast-math -complex-range=improved -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=IMPRVD_FAST + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ +// RUN: -ffast-math -complex-range=promoted -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=PRMTD_FAST + +// FULL-LABEL: define dso_local <2 x half> @divf16( +// FULL-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// FULL-NEXT: entry: +// FULL-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// FULL-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// FULL-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// FULL-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// FULL-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// FULL-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// FULL-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// FULL-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// FULL-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// FULL-NEXT: [[CALL:%.*]] = call <2 x float> @__divsc3(float noundef [[EXT]], float noundef [[EXT1]], float noundef [[EXT2]], float noundef [[EXT3]]) #[[ATTR1:[0-9]+]] +// FULL-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 +// FULL-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[COERCE_REAL]] to half +// FULL-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[COERCE_IMAG]] to half +// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// FULL-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// FULL-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// FULL-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// FULL-NEXT: ret <2 x half> [[TMP0]] +// +// BASIC-LABEL: define dso_local <2 x half> @divf16( +// BASIC-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// BASIC-NEXT: entry: +// BASIC-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// BASIC-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// BASIC-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// BASIC-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// BASIC-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// BASIC-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// BASIC-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// BASIC-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// BASIC-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// BASIC-NEXT: [[TMP0:%.*]] = fmul float [[EXT]], [[EXT2]] +// BASIC-NEXT: [[TMP1:%.*]] = fmul float [[EXT1]], [[EXT3]] +// BASIC-NEXT: [[TMP2:%.*]] = fadd float [[TMP0]], [[TMP1]] +// BASIC-NEXT: [[TMP3:%.*]] = fmul float [[EXT2]], [[EXT2]] +// BASIC-NEXT: [[TMP4:%.*]] = fmul float [[EXT3]], [[EXT3]] +// BASIC-NEXT: [[TMP5:%.*]] = fadd float [[TMP3]], [[TMP4]] +// BASIC-NEXT: [[TMP6:%.*]] = fmul float [[EXT1]], [[EXT2]] +// BASIC-NEXT: [[TMP7:%.*]] = fmul float [[EXT]], [[EXT3]] +// BASIC-NEXT: [[TMP8:%.*]] = fsub float [[TMP6]], [[TMP7]] +// BASIC-NEXT: [[TMP9:%.*]] = fdiv float [[TMP2]], [[TMP5]] +// BASIC-NEXT: [[TMP10:%.*]] = fdiv float [[TMP8]], [[TMP5]] +// BASIC-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP9]] to half +// BASIC-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[TMP10]] to half +// BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// BASIC-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// BASIC-NEXT: [[TMP11:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// BASIC-NEXT: ret <2 x half> [[TMP11]] +// +// IMPRVD-LABEL: define dso_local <2 x half> @divf16( +// IMPRVD-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// IMPRVD-NEXT: entry: +// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// IMPRVD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// IMPRVD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// IMPRVD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// IMPRVD-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// IMPRVD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// IMPRVD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// IMPRVD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// IMPRVD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// IMPRVD-NEXT: [[TMP0:%.*]] = call float @llvm.fabs.f32(float [[EXT2]]) +// IMPRVD-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[EXT3]]) +// IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP0]], [[TMP1]] +// IMPRVD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD-NEXT: [[TMP2:%.*]] = fdiv float [[EXT3]], [[EXT2]] +// IMPRVD-NEXT: [[TMP3:%.*]] = fmul float [[TMP2]], [[EXT3]] +// IMPRVD-NEXT: [[TMP4:%.*]] = fadd float [[EXT2]], [[TMP3]] +// IMPRVD-NEXT: [[TMP5:%.*]] = fmul float [[EXT1]], [[TMP2]] +// IMPRVD-NEXT: [[TMP6:%.*]] = fadd float [[EXT]], [[TMP5]] +// IMPRVD-NEXT: [[TMP7:%.*]] = fdiv float [[TMP6]], [[TMP4]] +// IMPRVD-NEXT: [[TMP8:%.*]] = fmul float [[EXT]], [[TMP2]] +// IMPRVD-NEXT: [[TMP9:%.*]] = fsub float [[EXT1]], [[TMP8]] +// IMPRVD-NEXT: [[TMP10:%.*]] = fdiv float [[TMP9]], [[TMP4]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD: abs_rhsr_less_than_abs_rhsi: +// IMPRVD-NEXT: [[TMP11:%.*]] = fdiv float [[EXT2]], [[EXT3]] +// IMPRVD-NEXT: [[TMP12:%.*]] = fmul float [[TMP11]], [[EXT2]] +// IMPRVD-NEXT: [[TMP13:%.*]] = fadd float [[EXT3]], [[TMP12]] +// IMPRVD-NEXT: [[TMP14:%.*]] = fmul float [[EXT]], [[TMP11]] +// IMPRVD-NEXT: [[TMP15:%.*]] = fadd float [[TMP14]], [[EXT1]] +// IMPRVD-NEXT: [[TMP16:%.*]] = fdiv float [[TMP15]], [[TMP13]] +// IMPRVD-NEXT: [[TMP17:%.*]] = fmul float [[EXT1]], [[TMP11]] +// IMPRVD-NEXT: [[TMP18:%.*]] = fsub float [[TMP17]], [[EXT]] +// IMPRVD-NEXT: [[TMP19:%.*]] = fdiv float [[TMP18]], [[TMP13]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD: complex_div: +// IMPRVD-NEXT: [[TMP20:%.*]] = phi float [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[TMP21:%.*]] = phi float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP20]] to half +// IMPRVD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[TMP21]] to half +// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// IMPRVD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// IMPRVD-NEXT: [[TMP22:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// IMPRVD-NEXT: ret <2 x half> [[TMP22]] +// +// PRMTD-LABEL: define dso_local <2 x half> @divf16( +// PRMTD-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// PRMTD-NEXT: entry: +// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// PRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// PRMTD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// PRMTD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// PRMTD-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// PRMTD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// PRMTD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// PRMTD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// PRMTD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// PRMTD-NEXT: [[TMP0:%.*]] = fmul float [[EXT]], [[EXT2]] +// PRMTD-NEXT: [[TMP1:%.*]] = fmul float [[EXT1]], [[EXT3]] +// PRMTD-NEXT: [[TMP2:%.*]] = fadd float [[TMP0]], [[TMP1]] +// PRMTD-NEXT: [[TMP3:%.*]] = fmul float [[EXT2]], [[EXT2]] +// PRMTD-NEXT: [[TMP4:%.*]] = fmul float [[EXT3]], [[EXT3]] +// PRMTD-NEXT: [[TMP5:%.*]] = fadd float [[TMP3]], [[TMP4]] +// PRMTD-NEXT: [[TMP6:%.*]] = fmul float [[EXT1]], [[EXT2]] +// PRMTD-NEXT: [[TMP7:%.*]] = fmul float [[EXT]], [[EXT3]] +// PRMTD-NEXT: [[TMP8:%.*]] = fsub float [[TMP6]], [[TMP7]] +// PRMTD-NEXT: [[TMP9:%.*]] = fdiv float [[TMP2]], [[TMP5]] +// PRMTD-NEXT: [[TMP10:%.*]] = fdiv float [[TMP8]], [[TMP5]] +// PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP9]] to half +// PRMTD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[TMP10]] to half +// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// PRMTD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// PRMTD-NEXT: [[TMP11:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// PRMTD-NEXT: ret <2 x half> [[TMP11]] +// +// X86WINPRMTD-LABEL: define dso_local i32 @divf16( +// X86WINPRMTD-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// X86WINPRMTD-NEXT: entry: +// X86WINPRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// X86WINPRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// X86WINPRMTD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// X86WINPRMTD-NEXT: store i32 [[A_COERCE]], ptr [[A]], align 2 +// X86WINPRMTD-NEXT: store i32 [[B_COERCE]], ptr [[B]], align 2 +// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// X86WINPRMTD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// X86WINPRMTD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// X86WINPRMTD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// X86WINPRMTD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// X86WINPRMTD-NEXT: [[TMP0:%.*]] = fmul float [[EXT]], [[EXT2]] +// X86WINPRMTD-NEXT: [[TMP1:%.*]] = fmul float [[EXT1]], [[EXT3]] +// X86WINPRMTD-NEXT: [[TMP2:%.*]] = fadd float [[TMP0]], [[TMP1]] +// X86WINPRMTD-NEXT: [[TMP3:%.*]] = fmul float [[EXT2]], [[EXT2]] +// X86WINPRMTD-NEXT: [[TMP4:%.*]] = fmul float [[EXT3]], [[EXT3]] +// X86WINPRMTD-NEXT: [[TMP5:%.*]] = fadd float [[TMP3]], [[TMP4]] +// X86WINPRMTD-NEXT: [[TMP6:%.*]] = fmul float [[EXT1]], [[EXT2]] +// X86WINPRMTD-NEXT: [[TMP7:%.*]] = fmul float [[EXT]], [[EXT3]] +// X86WINPRMTD-NEXT: [[TMP8:%.*]] = fsub float [[TMP6]], [[TMP7]] +// X86WINPRMTD-NEXT: [[TMP9:%.*]] = fdiv float [[TMP2]], [[TMP5]] +// X86WINPRMTD-NEXT: [[TMP10:%.*]] = fdiv float [[TMP8]], [[TMP5]] +// X86WINPRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP9]] to half +// X86WINPRMTD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[TMP10]] to half +// X86WINPRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// X86WINPRMTD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// X86WINPRMTD-NEXT: [[TMP11:%.*]] = load i32, ptr [[RETVAL]], align 2 +// X86WINPRMTD-NEXT: ret i32 [[TMP11]] +// +// BASIC_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @divf16( +// BASIC_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// BASIC_FAST-NEXT: entry: +// BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// BASIC_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// BASIC_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// BASIC_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// BASIC_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// BASIC_FAST-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// BASIC_FAST-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// BASIC_FAST-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// BASIC_FAST-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// BASIC_FAST-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] +// BASIC_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] +// BASIC_FAST-NEXT: [[TMP2:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP0]], [[TMP1]] +// BASIC_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT2]], [[EXT2]] +// BASIC_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT3]], [[EXT3]] +// BASIC_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP3]], [[TMP4]] +// BASIC_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] +// BASIC_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] +// BASIC_FAST-NEXT: [[TMP8:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP6]], [[TMP7]] +// BASIC_FAST-NEXT: [[TMP9:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP2]], [[TMP5]] +// BASIC_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP8]], [[TMP5]] +// BASIC_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP9]] to half +// BASIC_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[TMP10]] to half +// BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// BASIC_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// BASIC_FAST-NEXT: [[TMP11:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// BASIC_FAST-NEXT: ret <2 x half> [[TMP11]] +// +// FULL_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @divf16( +// FULL_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// FULL_FAST-NEXT: entry: +// FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// FULL_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// FULL_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// FULL_FAST-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// FULL_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// FULL_FAST-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// FULL_FAST-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// FULL_FAST-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// FULL_FAST-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// FULL_FAST-NEXT: [[CALL:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) <2 x float> @__divsc3(float noundef nofpclass(nan inf) [[EXT]], float noundef nofpclass(nan inf) [[EXT1]], float noundef nofpclass(nan inf) [[EXT2]], float noundef nofpclass(nan inf) [[EXT3]]) #[[ATTR1:[0-9]+]] +// FULL_FAST-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 +// FULL_FAST-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL_FAST-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL_FAST-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL_FAST-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[COERCE_REAL]] to half +// FULL_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[COERCE_IMAG]] to half +// FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// FULL_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// FULL_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// FULL_FAST-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// FULL_FAST-NEXT: ret <2 x half> [[TMP0]] +// +// IMPRVD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @divf16( +// IMPRVD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// IMPRVD_FAST-NEXT: entry: +// IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// IMPRVD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// IMPRVD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// IMPRVD_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// IMPRVD_FAST-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// IMPRVD_FAST-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// IMPRVD_FAST-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// IMPRVD_FAST-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[EXT2]]) +// IMPRVD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[EXT3]]) +// IMPRVD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt float [[TMP0]], [[TMP1]] +// IMPRVD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP2:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[EXT3]], [[EXT2]] +// IMPRVD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP2]], [[EXT3]] +// IMPRVD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT2]], [[TMP3]] +// IMPRVD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[TMP2]] +// IMPRVD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP5]] +// IMPRVD_FAST-NEXT: [[TMP7:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP6]], [[TMP4]] +// IMPRVD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP2]] +// IMPRVD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[EXT1]], [[TMP8]] +// IMPRVD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP9]], [[TMP4]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[EXT2]], [[EXT3]] +// IMPRVD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP11]], [[EXT2]] +// IMPRVD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT3]], [[TMP12]] +// IMPRVD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP11]] +// IMPRVD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP14]], [[EXT1]] +// IMPRVD_FAST-NEXT: [[TMP16:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP15]], [[TMP13]] +// IMPRVD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[TMP11]] +// IMPRVD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP17]], [[EXT]] +// IMPRVD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP18]], [[TMP13]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD_FAST: complex_div: +// IMPRVD_FAST-NEXT: [[TMP20:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP20]] to half +// IMPRVD_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[TMP21]] to half +// IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// IMPRVD_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// IMPRVD_FAST-NEXT: [[TMP22:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// IMPRVD_FAST-NEXT: ret <2 x half> [[TMP22]] +// +// PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @divf16( +// PRMTD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// PRMTD_FAST-NEXT: entry: +// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// PRMTD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// PRMTD_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// PRMTD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// PRMTD_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// PRMTD_FAST-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// PRMTD_FAST-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// PRMTD_FAST-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// PRMTD_FAST-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// PRMTD_FAST-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] +// PRMTD_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] +// PRMTD_FAST-NEXT: [[TMP2:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP0]], [[TMP1]] +// PRMTD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT2]], [[EXT2]] +// PRMTD_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT3]], [[EXT3]] +// PRMTD_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP3]], [[TMP4]] +// PRMTD_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] +// PRMTD_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] +// PRMTD_FAST-NEXT: [[TMP8:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP6]], [[TMP7]] +// PRMTD_FAST-NEXT: [[TMP9:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP2]], [[TMP5]] +// PRMTD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP8]], [[TMP5]] +// PRMTD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP9]] to half +// PRMTD_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[TMP10]] to half +// PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// PRMTD_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// PRMTD_FAST-NEXT: [[TMP11:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// PRMTD_FAST-NEXT: ret <2 x half> [[TMP11]] +// +_Complex _Float16 divf16(_Complex _Float16 a, _Complex _Float16 b) { + return a / b; +} + +// FULL-LABEL: define dso_local <2 x half> @mulf16( +// FULL-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { +// FULL-NEXT: entry: +// FULL-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// FULL-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// FULL-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// FULL-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// FULL-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// FULL-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// FULL-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// FULL-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// FULL-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// FULL-NEXT: [[MUL_AC:%.*]] = fmul float [[EXT]], [[EXT2]] +// FULL-NEXT: [[MUL_BD:%.*]] = fmul float [[EXT1]], [[EXT3]] +// FULL-NEXT: [[MUL_AD:%.*]] = fmul float [[EXT]], [[EXT3]] +// FULL-NEXT: [[MUL_BC:%.*]] = fmul float [[EXT1]], [[EXT2]] +// FULL-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// FULL-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// FULL-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno float [[MUL_R]], [[MUL_R]] +// FULL-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2:![0-9]+]] +// FULL: complex_mul_imag_nan: +// FULL-NEXT: [[ISNAN_CMP4:%.*]] = fcmp uno float [[MUL_I]], [[MUL_I]] +// FULL-NEXT: br i1 [[ISNAN_CMP4]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]] +// FULL: complex_mul_libcall: +// FULL-NEXT: [[CALL:%.*]] = call <2 x float> @__mulsc3(float noundef [[EXT]], float noundef [[EXT1]], float noundef [[EXT2]], float noundef [[EXT3]]) #[[ATTR1]] +// FULL-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 +// FULL-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL-NEXT: br label [[COMPLEX_MUL_CONT]] +// FULL: complex_mul_cont: +// FULL-NEXT: [[REAL_MUL_PHI:%.*]] = phi float [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_REAL]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL-NEXT: [[IMAG_MUL_PHI:%.*]] = phi float [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_IMAG]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[REAL_MUL_PHI]] to half +// FULL-NEXT: [[UNPROMOTION5:%.*]] = fptrunc float [[IMAG_MUL_PHI]] to half +// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// FULL-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// FULL-NEXT: store half [[UNPROMOTION5]], ptr [[RETVAL_IMAGP]], align 2 +// FULL-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// FULL-NEXT: ret <2 x half> [[TMP0]] +// +// BASIC-LABEL: define dso_local <2 x half> @mulf16( +// BASIC-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { +// BASIC-NEXT: entry: +// BASIC-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// BASIC-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// BASIC-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// BASIC-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// BASIC-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// BASIC-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// BASIC-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// BASIC-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// BASIC-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// BASIC-NEXT: [[MUL_AC:%.*]] = fmul float [[EXT]], [[EXT2]] +// BASIC-NEXT: [[MUL_BD:%.*]] = fmul float [[EXT1]], [[EXT3]] +// BASIC-NEXT: [[MUL_AD:%.*]] = fmul float [[EXT]], [[EXT3]] +// BASIC-NEXT: [[MUL_BC:%.*]] = fmul float [[EXT1]], [[EXT2]] +// BASIC-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// BASIC-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// BASIC-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half +// BASIC-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[MUL_I]] to half +// BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// BASIC-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// BASIC-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// BASIC-NEXT: ret <2 x half> [[TMP0]] +// +// IMPRVD-LABEL: define dso_local <2 x half> @mulf16( +// IMPRVD-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { +// IMPRVD-NEXT: entry: +// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// IMPRVD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// IMPRVD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// IMPRVD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// IMPRVD-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// IMPRVD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// IMPRVD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// IMPRVD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// IMPRVD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// IMPRVD-NEXT: [[MUL_AC:%.*]] = fmul float [[EXT]], [[EXT2]] +// IMPRVD-NEXT: [[MUL_BD:%.*]] = fmul float [[EXT1]], [[EXT3]] +// IMPRVD-NEXT: [[MUL_AD:%.*]] = fmul float [[EXT]], [[EXT3]] +// IMPRVD-NEXT: [[MUL_BC:%.*]] = fmul float [[EXT1]], [[EXT2]] +// IMPRVD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// IMPRVD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// IMPRVD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half +// IMPRVD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[MUL_I]] to half +// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// IMPRVD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// IMPRVD-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// IMPRVD-NEXT: ret <2 x half> [[TMP0]] +// +// PRMTD-LABEL: define dso_local <2 x half> @mulf16( +// PRMTD-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { +// PRMTD-NEXT: entry: +// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// PRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// PRMTD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// PRMTD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// PRMTD-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// PRMTD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// PRMTD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// PRMTD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// PRMTD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// PRMTD-NEXT: [[MUL_AC:%.*]] = fmul float [[EXT]], [[EXT2]] +// PRMTD-NEXT: [[MUL_BD:%.*]] = fmul float [[EXT1]], [[EXT3]] +// PRMTD-NEXT: [[MUL_AD:%.*]] = fmul float [[EXT]], [[EXT3]] +// PRMTD-NEXT: [[MUL_BC:%.*]] = fmul float [[EXT1]], [[EXT2]] +// PRMTD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// PRMTD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half +// PRMTD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[MUL_I]] to half +// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// PRMTD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// PRMTD-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// PRMTD-NEXT: ret <2 x half> [[TMP0]] +// +// X86WINPRMTD-LABEL: define dso_local i32 @mulf16( +// X86WINPRMTD-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[B_COERCE:%.*]]) #[[ATTR0]] { +// X86WINPRMTD-NEXT: entry: +// X86WINPRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// X86WINPRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// X86WINPRMTD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// X86WINPRMTD-NEXT: store i32 [[A_COERCE]], ptr [[A]], align 2 +// X86WINPRMTD-NEXT: store i32 [[B_COERCE]], ptr [[B]], align 2 +// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// X86WINPRMTD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// X86WINPRMTD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// X86WINPRMTD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// X86WINPRMTD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// X86WINPRMTD-NEXT: [[MUL_AC:%.*]] = fmul float [[EXT]], [[EXT2]] +// X86WINPRMTD-NEXT: [[MUL_BD:%.*]] = fmul float [[EXT1]], [[EXT3]] +// X86WINPRMTD-NEXT: [[MUL_AD:%.*]] = fmul float [[EXT]], [[EXT3]] +// X86WINPRMTD-NEXT: [[MUL_BC:%.*]] = fmul float [[EXT1]], [[EXT2]] +// X86WINPRMTD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// X86WINPRMTD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// X86WINPRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half +// X86WINPRMTD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[MUL_I]] to half +// X86WINPRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// X86WINPRMTD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// X86WINPRMTD-NEXT: [[TMP0:%.*]] = load i32, ptr [[RETVAL]], align 2 +// X86WINPRMTD-NEXT: ret i32 [[TMP0]] +// +// BASIC_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @mulf16( +// BASIC_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { +// BASIC_FAST-NEXT: entry: +// BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// BASIC_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// BASIC_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// BASIC_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// BASIC_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// BASIC_FAST-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// BASIC_FAST-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// BASIC_FAST-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// BASIC_FAST-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// BASIC_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] +// BASIC_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] +// BASIC_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] +// BASIC_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] +// BASIC_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] +// BASIC_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] +// BASIC_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half +// BASIC_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[MUL_I]] to half +// BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// BASIC_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// BASIC_FAST-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// BASIC_FAST-NEXT: ret <2 x half> [[TMP0]] +// +// FULL_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @mulf16( +// FULL_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { +// FULL_FAST-NEXT: entry: +// FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// FULL_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// FULL_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// FULL_FAST-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// FULL_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// FULL_FAST-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// FULL_FAST-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// FULL_FAST-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// FULL_FAST-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// FULL_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] +// FULL_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] +// FULL_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] +// FULL_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] +// FULL_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] +// FULL_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] +// FULL_FAST-NEXT: [[ISNAN_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno float [[MUL_R]], [[MUL_R]] +// FULL_FAST-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2:![0-9]+]] +// FULL_FAST: complex_mul_imag_nan: +// FULL_FAST-NEXT: [[ISNAN_CMP4:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno float [[MUL_I]], [[MUL_I]] +// FULL_FAST-NEXT: br i1 [[ISNAN_CMP4]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]] +// FULL_FAST: complex_mul_libcall: +// FULL_FAST-NEXT: [[CALL:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) <2 x float> @__mulsc3(float noundef nofpclass(nan inf) [[EXT]], float noundef nofpclass(nan inf) [[EXT1]], float noundef nofpclass(nan inf) [[EXT2]], float noundef nofpclass(nan inf) [[EXT3]]) #[[ATTR1]] +// FULL_FAST-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 +// FULL_FAST-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL_FAST-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL_FAST-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL_FAST-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL_FAST-NEXT: br label [[COMPLEX_MUL_CONT]] +// FULL_FAST: complex_mul_cont: +// FULL_FAST-NEXT: [[REAL_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_REAL]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL_FAST-NEXT: [[IMAG_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_IMAG]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[REAL_MUL_PHI]] to half +// FULL_FAST-NEXT: [[UNPROMOTION5:%.*]] = fptrunc float [[IMAG_MUL_PHI]] to half +// FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// FULL_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// FULL_FAST-NEXT: store half [[UNPROMOTION5]], ptr [[RETVAL_IMAGP]], align 2 +// FULL_FAST-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// FULL_FAST-NEXT: ret <2 x half> [[TMP0]] +// +// IMPRVD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @mulf16( +// IMPRVD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { +// IMPRVD_FAST-NEXT: entry: +// IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// IMPRVD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// IMPRVD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// IMPRVD_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// IMPRVD_FAST-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// IMPRVD_FAST-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// IMPRVD_FAST-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// IMPRVD_FAST-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// IMPRVD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] +// IMPRVD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] +// IMPRVD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] +// IMPRVD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] +// IMPRVD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] +// IMPRVD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] +// IMPRVD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half +// IMPRVD_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[MUL_I]] to half +// IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// IMPRVD_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// IMPRVD_FAST-NEXT: ret <2 x half> [[TMP0]] +// +// PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @mulf16( +// PRMTD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { +// PRMTD_FAST-NEXT: entry: +// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// PRMTD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// PRMTD_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 +// PRMTD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// PRMTD_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 +// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// PRMTD_FAST-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float +// PRMTD_FAST-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float +// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 +// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 +// PRMTD_FAST-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float +// PRMTD_FAST-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float +// PRMTD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] +// PRMTD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] +// PRMTD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] +// PRMTD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] +// PRMTD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] +// PRMTD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] +// PRMTD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half +// PRMTD_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[MUL_I]] to half +// PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// PRMTD_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 +// PRMTD_FAST-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// PRMTD_FAST-NEXT: ret <2 x half> [[TMP0]] +// +_Complex _Float16 mulf16(_Complex _Float16 a, _Complex _Float16 b) { + return a * b; +} + +// FULL-LABEL: define dso_local <2 x half> @f1( +// FULL-SAME: <2 x half> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { +// FULL-NEXT: entry: +// FULL-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// FULL-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// FULL-NEXT: [[C:%.*]] = alloca { half, half }, align 2 +// FULL-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// FULL-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 +// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// FULL-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 +// FULL-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 +// FULL-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 +// FULL-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 +// FULL-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 +// FULL-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 +// FULL-NEXT: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__divxc3(x86_fp80 noundef [[B_REAL]], x86_fp80 noundef [[B_IMAG]], x86_fp80 noundef [[CONV]], x86_fp80 noundef [[CONV1]]) #[[ATTR1]] +// FULL-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0 +// FULL-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1 +// FULL-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP0]] to half +// FULL-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP1]] to half +// FULL-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float +// FULL-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float +// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// FULL-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float +// FULL-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float +// FULL-NEXT: [[CALL7:%.*]] = call <2 x float> @__divsc3(float noundef [[EXT]], float noundef [[EXT4]], float noundef [[EXT5]], float noundef [[EXT6]]) #[[ATTR1]] +// FULL-NEXT: store <2 x float> [[CALL7]], ptr [[COERCE]], align 4 +// FULL-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[COERCE_REAL]] to half +// FULL-NEXT: [[UNPROMOTION8:%.*]] = fptrunc float [[COERCE_IMAG]] to half +// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// FULL-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// FULL-NEXT: store half [[UNPROMOTION8]], ptr [[RETVAL_IMAGP]], align 2 +// FULL-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// FULL-NEXT: ret <2 x half> [[TMP2]] +// +// BASIC-LABEL: define dso_local <2 x half> @f1( +// BASIC-SAME: <2 x half> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { +// BASIC-NEXT: entry: +// BASIC-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// BASIC-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// BASIC-NEXT: [[C:%.*]] = alloca { half, half }, align 2 +// BASIC-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// BASIC-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 +// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// BASIC-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 +// BASIC-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 +// BASIC-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 +// BASIC-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 +// BASIC-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 +// BASIC-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 +// BASIC-NEXT: [[TMP0:%.*]] = fmul x86_fp80 [[B_REAL]], [[CONV]] +// BASIC-NEXT: [[TMP1:%.*]] = fmul x86_fp80 [[B_IMAG]], [[CONV1]] +// BASIC-NEXT: [[TMP2:%.*]] = fadd x86_fp80 [[TMP0]], [[TMP1]] +// BASIC-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[CONV]], [[CONV]] +// BASIC-NEXT: [[TMP4:%.*]] = fmul x86_fp80 [[CONV1]], [[CONV1]] +// BASIC-NEXT: [[TMP5:%.*]] = fadd x86_fp80 [[TMP3]], [[TMP4]] +// BASIC-NEXT: [[TMP6:%.*]] = fmul x86_fp80 [[B_IMAG]], [[CONV]] +// BASIC-NEXT: [[TMP7:%.*]] = fmul x86_fp80 [[B_REAL]], [[CONV1]] +// BASIC-NEXT: [[TMP8:%.*]] = fsub x86_fp80 [[TMP6]], [[TMP7]] +// BASIC-NEXT: [[TMP9:%.*]] = fdiv x86_fp80 [[TMP2]], [[TMP5]] +// BASIC-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP8]], [[TMP5]] +// BASIC-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP9]] to half +// BASIC-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP10]] to half +// BASIC-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float +// BASIC-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float +// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// BASIC-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float +// BASIC-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float +// BASIC-NEXT: [[TMP11:%.*]] = fmul float [[EXT]], [[EXT5]] +// BASIC-NEXT: [[TMP12:%.*]] = fmul float [[EXT4]], [[EXT6]] +// BASIC-NEXT: [[TMP13:%.*]] = fadd float [[TMP11]], [[TMP12]] +// BASIC-NEXT: [[TMP14:%.*]] = fmul float [[EXT5]], [[EXT5]] +// BASIC-NEXT: [[TMP15:%.*]] = fmul float [[EXT6]], [[EXT6]] +// BASIC-NEXT: [[TMP16:%.*]] = fadd float [[TMP14]], [[TMP15]] +// BASIC-NEXT: [[TMP17:%.*]] = fmul float [[EXT4]], [[EXT5]] +// BASIC-NEXT: [[TMP18:%.*]] = fmul float [[EXT]], [[EXT6]] +// BASIC-NEXT: [[TMP19:%.*]] = fsub float [[TMP17]], [[TMP18]] +// BASIC-NEXT: [[TMP20:%.*]] = fdiv float [[TMP13]], [[TMP16]] +// BASIC-NEXT: [[TMP21:%.*]] = fdiv float [[TMP19]], [[TMP16]] +// BASIC-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP20]] to half +// BASIC-NEXT: [[UNPROMOTION7:%.*]] = fptrunc float [[TMP21]] to half +// BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// BASIC-NEXT: store half [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 2 +// BASIC-NEXT: [[TMP22:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// BASIC-NEXT: ret <2 x half> [[TMP22]] +// +// IMPRVD-LABEL: define dso_local <2 x half> @f1( +// IMPRVD-SAME: <2 x half> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { +// IMPRVD-NEXT: entry: +// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// IMPRVD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// IMPRVD-NEXT: [[C:%.*]] = alloca { half, half }, align 2 +// IMPRVD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// IMPRVD-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 +// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// IMPRVD-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 +// IMPRVD-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 +// IMPRVD-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 +// IMPRVD-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 +// IMPRVD-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 +// IMPRVD-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 +// IMPRVD-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) +// IMPRVD-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) +// IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt x86_fp80 [[TMP0]], [[TMP1]] +// IMPRVD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[CONV1]], [[CONV]] +// IMPRVD-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[TMP2]], [[CONV1]] +// IMPRVD-NEXT: [[TMP4:%.*]] = fadd x86_fp80 [[CONV]], [[TMP3]] +// IMPRVD-NEXT: [[TMP5:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP2]] +// IMPRVD-NEXT: [[TMP6:%.*]] = fadd x86_fp80 [[B_REAL]], [[TMP5]] +// IMPRVD-NEXT: [[TMP7:%.*]] = fdiv x86_fp80 [[TMP6]], [[TMP4]] +// IMPRVD-NEXT: [[TMP8:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP2]] +// IMPRVD-NEXT: [[TMP9:%.*]] = fsub x86_fp80 [[B_IMAG]], [[TMP8]] +// IMPRVD-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP9]], [[TMP4]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD: abs_rhsr_less_than_abs_rhsi: +// IMPRVD-NEXT: [[TMP11:%.*]] = fdiv x86_fp80 [[CONV]], [[CONV1]] +// IMPRVD-NEXT: [[TMP12:%.*]] = fmul x86_fp80 [[TMP11]], [[CONV]] +// IMPRVD-NEXT: [[TMP13:%.*]] = fadd x86_fp80 [[CONV1]], [[TMP12]] +// IMPRVD-NEXT: [[TMP14:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP11]] +// IMPRVD-NEXT: [[TMP15:%.*]] = fadd x86_fp80 [[TMP14]], [[B_IMAG]] +// IMPRVD-NEXT: [[TMP16:%.*]] = fdiv x86_fp80 [[TMP15]], [[TMP13]] +// IMPRVD-NEXT: [[TMP17:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP11]] +// IMPRVD-NEXT: [[TMP18:%.*]] = fsub x86_fp80 [[TMP17]], [[B_REAL]] +// IMPRVD-NEXT: [[TMP19:%.*]] = fdiv x86_fp80 [[TMP18]], [[TMP13]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD: complex_div: +// IMPRVD-NEXT: [[TMP20:%.*]] = phi x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP20]] to half +// IMPRVD-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP21]] to half +// IMPRVD-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float +// IMPRVD-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float +// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// IMPRVD-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float +// IMPRVD-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float +// IMPRVD-NEXT: [[TMP22:%.*]] = call float @llvm.fabs.f32(float [[EXT5]]) +// IMPRVD-NEXT: [[TMP23:%.*]] = call float @llvm.fabs.f32(float [[EXT6]]) +// IMPRVD-NEXT: [[ABS_CMP7:%.*]] = fcmp ugt float [[TMP22]], [[TMP23]] +// IMPRVD-NEXT: br i1 [[ABS_CMP7]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI9:%.*]] +// IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi8: +// IMPRVD-NEXT: [[TMP24:%.*]] = fdiv float [[EXT6]], [[EXT5]] +// IMPRVD-NEXT: [[TMP25:%.*]] = fmul float [[TMP24]], [[EXT6]] +// IMPRVD-NEXT: [[TMP26:%.*]] = fadd float [[EXT5]], [[TMP25]] +// IMPRVD-NEXT: [[TMP27:%.*]] = fmul float [[EXT4]], [[TMP24]] +// IMPRVD-NEXT: [[TMP28:%.*]] = fadd float [[EXT]], [[TMP27]] +// IMPRVD-NEXT: [[TMP29:%.*]] = fdiv float [[TMP28]], [[TMP26]] +// IMPRVD-NEXT: [[TMP30:%.*]] = fmul float [[EXT]], [[TMP24]] +// IMPRVD-NEXT: [[TMP31:%.*]] = fsub float [[EXT4]], [[TMP30]] +// IMPRVD-NEXT: [[TMP32:%.*]] = fdiv float [[TMP31]], [[TMP26]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV10:%.*]] +// IMPRVD: abs_rhsr_less_than_abs_rhsi9: +// IMPRVD-NEXT: [[TMP33:%.*]] = fdiv float [[EXT5]], [[EXT6]] +// IMPRVD-NEXT: [[TMP34:%.*]] = fmul float [[TMP33]], [[EXT5]] +// IMPRVD-NEXT: [[TMP35:%.*]] = fadd float [[EXT6]], [[TMP34]] +// IMPRVD-NEXT: [[TMP36:%.*]] = fmul float [[EXT]], [[TMP33]] +// IMPRVD-NEXT: [[TMP37:%.*]] = fadd float [[TMP36]], [[EXT4]] +// IMPRVD-NEXT: [[TMP38:%.*]] = fdiv float [[TMP37]], [[TMP35]] +// IMPRVD-NEXT: [[TMP39:%.*]] = fmul float [[EXT4]], [[TMP33]] +// IMPRVD-NEXT: [[TMP40:%.*]] = fsub float [[TMP39]], [[EXT]] +// IMPRVD-NEXT: [[TMP41:%.*]] = fdiv float [[TMP40]], [[TMP35]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV10]] +// IMPRVD: complex_div10: +// IMPRVD-NEXT: [[TMP42:%.*]] = phi float [ [[TMP29]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8]] ], [ [[TMP38]], [[ABS_RHSR_LESS_THAN_ABS_RHSI9]] ] +// IMPRVD-NEXT: [[TMP43:%.*]] = phi float [ [[TMP32]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8]] ], [ [[TMP41]], [[ABS_RHSR_LESS_THAN_ABS_RHSI9]] ] +// IMPRVD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP42]] to half +// IMPRVD-NEXT: [[UNPROMOTION11:%.*]] = fptrunc float [[TMP43]] to half +// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// IMPRVD-NEXT: store half [[UNPROMOTION11]], ptr [[RETVAL_IMAGP]], align 2 +// IMPRVD-NEXT: [[TMP44:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// IMPRVD-NEXT: ret <2 x half> [[TMP44]] +// +// PRMTD-LABEL: define dso_local <2 x half> @f1( +// PRMTD-SAME: <2 x half> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { +// PRMTD-NEXT: entry: +// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// PRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// PRMTD-NEXT: [[C:%.*]] = alloca { half, half }, align 2 +// PRMTD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// PRMTD-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 +// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// PRMTD-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 +// PRMTD-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 +// PRMTD-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 +// PRMTD-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 +// PRMTD-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 +// PRMTD-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 +// PRMTD-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) +// PRMTD-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) +// PRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt x86_fp80 [[TMP0]], [[TMP1]] +// PRMTD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// PRMTD: abs_rhsr_greater_or_equal_abs_rhsi: +// PRMTD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[CONV1]], [[CONV]] +// PRMTD-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[TMP2]], [[CONV1]] +// PRMTD-NEXT: [[TMP4:%.*]] = fadd x86_fp80 [[CONV]], [[TMP3]] +// PRMTD-NEXT: [[TMP5:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP2]] +// PRMTD-NEXT: [[TMP6:%.*]] = fadd x86_fp80 [[B_REAL]], [[TMP5]] +// PRMTD-NEXT: [[TMP7:%.*]] = fdiv x86_fp80 [[TMP6]], [[TMP4]] +// PRMTD-NEXT: [[TMP8:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP2]] +// PRMTD-NEXT: [[TMP9:%.*]] = fsub x86_fp80 [[B_IMAG]], [[TMP8]] +// PRMTD-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP9]], [[TMP4]] +// PRMTD-NEXT: br label [[COMPLEX_DIV:%.*]] +// PRMTD: abs_rhsr_less_than_abs_rhsi: +// PRMTD-NEXT: [[TMP11:%.*]] = fdiv x86_fp80 [[CONV]], [[CONV1]] +// PRMTD-NEXT: [[TMP12:%.*]] = fmul x86_fp80 [[TMP11]], [[CONV]] +// PRMTD-NEXT: [[TMP13:%.*]] = fadd x86_fp80 [[CONV1]], [[TMP12]] +// PRMTD-NEXT: [[TMP14:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP11]] +// PRMTD-NEXT: [[TMP15:%.*]] = fadd x86_fp80 [[TMP14]], [[B_IMAG]] +// PRMTD-NEXT: [[TMP16:%.*]] = fdiv x86_fp80 [[TMP15]], [[TMP13]] +// PRMTD-NEXT: [[TMP17:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP11]] +// PRMTD-NEXT: [[TMP18:%.*]] = fsub x86_fp80 [[TMP17]], [[B_REAL]] +// PRMTD-NEXT: [[TMP19:%.*]] = fdiv x86_fp80 [[TMP18]], [[TMP13]] +// PRMTD-NEXT: br label [[COMPLEX_DIV]] +// PRMTD: complex_div: +// PRMTD-NEXT: [[TMP20:%.*]] = phi x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP20]] to half +// PRMTD-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP21]] to half +// PRMTD-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float +// PRMTD-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float +// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// PRMTD-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float +// PRMTD-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float +// PRMTD-NEXT: [[TMP22:%.*]] = fmul float [[EXT]], [[EXT5]] +// PRMTD-NEXT: [[TMP23:%.*]] = fmul float [[EXT4]], [[EXT6]] +// PRMTD-NEXT: [[TMP24:%.*]] = fadd float [[TMP22]], [[TMP23]] +// PRMTD-NEXT: [[TMP25:%.*]] = fmul float [[EXT5]], [[EXT5]] +// PRMTD-NEXT: [[TMP26:%.*]] = fmul float [[EXT6]], [[EXT6]] +// PRMTD-NEXT: [[TMP27:%.*]] = fadd float [[TMP25]], [[TMP26]] +// PRMTD-NEXT: [[TMP28:%.*]] = fmul float [[EXT4]], [[EXT5]] +// PRMTD-NEXT: [[TMP29:%.*]] = fmul float [[EXT]], [[EXT6]] +// PRMTD-NEXT: [[TMP30:%.*]] = fsub float [[TMP28]], [[TMP29]] +// PRMTD-NEXT: [[TMP31:%.*]] = fdiv float [[TMP24]], [[TMP27]] +// PRMTD-NEXT: [[TMP32:%.*]] = fdiv float [[TMP30]], [[TMP27]] +// PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP31]] to half +// PRMTD-NEXT: [[UNPROMOTION7:%.*]] = fptrunc float [[TMP32]] to half +// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// PRMTD-NEXT: store half [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 2 +// PRMTD-NEXT: [[TMP33:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// PRMTD-NEXT: ret <2 x half> [[TMP33]] +// +// X86WINPRMTD-LABEL: define dso_local i32 @f1( +// X86WINPRMTD-SAME: i32 noundef [[A_COERCE:%.*]], ptr noundef [[B:%.*]], i32 noundef [[C_COERCE:%.*]]) #[[ATTR0]] { +// X86WINPRMTD-NEXT: entry: +// X86WINPRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// X86WINPRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// X86WINPRMTD-NEXT: [[C:%.*]] = alloca { half, half }, align 2 +// X86WINPRMTD-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: store i32 [[A_COERCE]], ptr [[A]], align 2 +// X86WINPRMTD-NEXT: store i32 [[C_COERCE]], ptr [[C]], align 2 +// X86WINPRMTD-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8 +// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 +// X86WINPRMTD-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 +// X86WINPRMTD-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to double +// X86WINPRMTD-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to double +// X86WINPRMTD-NEXT: [[TMP0:%.*]] = call double @llvm.fabs.f64(double [[CONV]]) +// X86WINPRMTD-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[CONV1]]) +// X86WINPRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP0]], [[TMP1]] +// X86WINPRMTD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// X86WINPRMTD: abs_rhsr_greater_or_equal_abs_rhsi: +// X86WINPRMTD-NEXT: [[TMP2:%.*]] = fdiv double [[CONV1]], [[CONV]] +// X86WINPRMTD-NEXT: [[TMP3:%.*]] = fmul double [[TMP2]], [[CONV1]] +// X86WINPRMTD-NEXT: [[TMP4:%.*]] = fadd double [[CONV]], [[TMP3]] +// X86WINPRMTD-NEXT: [[TMP5:%.*]] = fmul double [[B_IMAG]], [[TMP2]] +// X86WINPRMTD-NEXT: [[TMP6:%.*]] = fadd double [[B_REAL]], [[TMP5]] +// X86WINPRMTD-NEXT: [[TMP7:%.*]] = fdiv double [[TMP6]], [[TMP4]] +// X86WINPRMTD-NEXT: [[TMP8:%.*]] = fmul double [[B_REAL]], [[TMP2]] +// X86WINPRMTD-NEXT: [[TMP9:%.*]] = fsub double [[B_IMAG]], [[TMP8]] +// X86WINPRMTD-NEXT: [[TMP10:%.*]] = fdiv double [[TMP9]], [[TMP4]] +// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV:%.*]] +// X86WINPRMTD: abs_rhsr_less_than_abs_rhsi: +// X86WINPRMTD-NEXT: [[TMP11:%.*]] = fdiv double [[CONV]], [[CONV1]] +// X86WINPRMTD-NEXT: [[TMP12:%.*]] = fmul double [[TMP11]], [[CONV]] +// X86WINPRMTD-NEXT: [[TMP13:%.*]] = fadd double [[CONV1]], [[TMP12]] +// X86WINPRMTD-NEXT: [[TMP14:%.*]] = fmul double [[B_REAL]], [[TMP11]] +// X86WINPRMTD-NEXT: [[TMP15:%.*]] = fadd double [[TMP14]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[TMP16:%.*]] = fdiv double [[TMP15]], [[TMP13]] +// X86WINPRMTD-NEXT: [[TMP17:%.*]] = fmul double [[B_IMAG]], [[TMP11]] +// X86WINPRMTD-NEXT: [[TMP18:%.*]] = fsub double [[TMP17]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[TMP19:%.*]] = fdiv double [[TMP18]], [[TMP13]] +// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV]] +// X86WINPRMTD: complex_div: +// X86WINPRMTD-NEXT: [[TMP20:%.*]] = phi double [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// X86WINPRMTD-NEXT: [[TMP21:%.*]] = phi double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// X86WINPRMTD-NEXT: [[CONV2:%.*]] = fptrunc double [[TMP20]] to half +// X86WINPRMTD-NEXT: [[CONV3:%.*]] = fptrunc double [[TMP21]] to half +// X86WINPRMTD-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float +// X86WINPRMTD-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float +// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// X86WINPRMTD-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float +// X86WINPRMTD-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float +// X86WINPRMTD-NEXT: [[TMP22:%.*]] = fmul float [[EXT]], [[EXT5]] +// X86WINPRMTD-NEXT: [[TMP23:%.*]] = fmul float [[EXT4]], [[EXT6]] +// X86WINPRMTD-NEXT: [[TMP24:%.*]] = fadd float [[TMP22]], [[TMP23]] +// X86WINPRMTD-NEXT: [[TMP25:%.*]] = fmul float [[EXT5]], [[EXT5]] +// X86WINPRMTD-NEXT: [[TMP26:%.*]] = fmul float [[EXT6]], [[EXT6]] +// X86WINPRMTD-NEXT: [[TMP27:%.*]] = fadd float [[TMP25]], [[TMP26]] +// X86WINPRMTD-NEXT: [[TMP28:%.*]] = fmul float [[EXT4]], [[EXT5]] +// X86WINPRMTD-NEXT: [[TMP29:%.*]] = fmul float [[EXT]], [[EXT6]] +// X86WINPRMTD-NEXT: [[TMP30:%.*]] = fsub float [[TMP28]], [[TMP29]] +// X86WINPRMTD-NEXT: [[TMP31:%.*]] = fdiv float [[TMP24]], [[TMP27]] +// X86WINPRMTD-NEXT: [[TMP32:%.*]] = fdiv float [[TMP30]], [[TMP27]] +// X86WINPRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP31]] to half +// X86WINPRMTD-NEXT: [[UNPROMOTION7:%.*]] = fptrunc float [[TMP32]] to half +// X86WINPRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// X86WINPRMTD-NEXT: store half [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 2 +// X86WINPRMTD-NEXT: [[TMP33:%.*]] = load i32, ptr [[RETVAL]], align 2 +// X86WINPRMTD-NEXT: ret i32 [[TMP33]] +// +// BASIC_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @f1( +// BASIC_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { +// BASIC_FAST-NEXT: entry: +// BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// BASIC_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// BASIC_FAST-NEXT: [[C:%.*]] = alloca { half, half }, align 2 +// BASIC_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// BASIC_FAST-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 +// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// BASIC_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 +// BASIC_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 +// BASIC_FAST-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 +// BASIC_FAST-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 +// BASIC_FAST-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[CONV]] +// BASIC_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[CONV1]] +// BASIC_FAST-NEXT: [[TMP2:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP0]], [[TMP1]] +// BASIC_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[CONV]] +// BASIC_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[CONV1]] +// BASIC_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP3]], [[TMP4]] +// BASIC_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[CONV]] +// BASIC_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[CONV1]] +// BASIC_FAST-NEXT: [[TMP8:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP7]] +// BASIC_FAST-NEXT: [[TMP9:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[TMP5]] +// BASIC_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP8]], [[TMP5]] +// BASIC_FAST-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP9]] to half +// BASIC_FAST-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP10]] to half +// BASIC_FAST-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float +// BASIC_FAST-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float +// BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// BASIC_FAST-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float +// BASIC_FAST-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float +// BASIC_FAST-NEXT: [[TMP11:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT5]] +// BASIC_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[EXT6]] +// BASIC_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP11]], [[TMP12]] +// BASIC_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT5]], [[EXT5]] +// BASIC_FAST-NEXT: [[TMP15:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT6]], [[EXT6]] +// BASIC_FAST-NEXT: [[TMP16:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP14]], [[TMP15]] +// BASIC_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[EXT5]] +// BASIC_FAST-NEXT: [[TMP18:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT6]] +// BASIC_FAST-NEXT: [[TMP19:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP17]], [[TMP18]] +// BASIC_FAST-NEXT: [[TMP20:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP13]], [[TMP16]] +// BASIC_FAST-NEXT: [[TMP21:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP19]], [[TMP16]] +// BASIC_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP20]] to half +// BASIC_FAST-NEXT: [[UNPROMOTION7:%.*]] = fptrunc float [[TMP21]] to half +// BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// BASIC_FAST-NEXT: store half [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 2 +// BASIC_FAST-NEXT: [[TMP22:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// BASIC_FAST-NEXT: ret <2 x half> [[TMP22]] +// +// FULL_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @f1( +// FULL_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { +// FULL_FAST-NEXT: entry: +// FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// FULL_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// FULL_FAST-NEXT: [[C:%.*]] = alloca { half, half }, align 2 +// FULL_FAST-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// FULL_FAST-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 +// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// FULL_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 +// FULL_FAST-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 +// FULL_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 +// FULL_FAST-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 +// FULL_FAST-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 +// FULL_FAST-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 +// FULL_FAST-NEXT: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__divxc3(x86_fp80 noundef nofpclass(nan inf) [[B_REAL]], x86_fp80 noundef nofpclass(nan inf) [[B_IMAG]], x86_fp80 noundef nofpclass(nan inf) [[CONV]], x86_fp80 noundef nofpclass(nan inf) [[CONV1]]) #[[ATTR1]] +// FULL_FAST-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0 +// FULL_FAST-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1 +// FULL_FAST-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP0]] to half +// FULL_FAST-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP1]] to half +// FULL_FAST-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float +// FULL_FAST-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float +// FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// FULL_FAST-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float +// FULL_FAST-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float +// FULL_FAST-NEXT: [[CALL7:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) <2 x float> @__divsc3(float noundef nofpclass(nan inf) [[EXT]], float noundef nofpclass(nan inf) [[EXT4]], float noundef nofpclass(nan inf) [[EXT5]], float noundef nofpclass(nan inf) [[EXT6]]) #[[ATTR1]] +// FULL_FAST-NEXT: store <2 x float> [[CALL7]], ptr [[COERCE]], align 4 +// FULL_FAST-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL_FAST-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL_FAST-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL_FAST-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[COERCE_REAL]] to half +// FULL_FAST-NEXT: [[UNPROMOTION8:%.*]] = fptrunc float [[COERCE_IMAG]] to half +// FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// FULL_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// FULL_FAST-NEXT: store half [[UNPROMOTION8]], ptr [[RETVAL_IMAGP]], align 2 +// FULL_FAST-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// FULL_FAST-NEXT: ret <2 x half> [[TMP2]] +// +// IMPRVD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @f1( +// IMPRVD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { +// IMPRVD_FAST-NEXT: entry: +// IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// IMPRVD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// IMPRVD_FAST-NEXT: [[C:%.*]] = alloca { half, half }, align 2 +// IMPRVD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// IMPRVD_FAST-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 +// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// IMPRVD_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 +// IMPRVD_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 +// IMPRVD_FAST-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 +// IMPRVD_FAST-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 +// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) +// IMPRVD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) +// IMPRVD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt x86_fp80 [[TMP0]], [[TMP1]] +// IMPRVD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP2:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[CONV]] +// IMPRVD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[CONV1]] +// IMPRVD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[TMP3]] +// IMPRVD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP2]] +// IMPRVD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP5]] +// IMPRVD_FAST-NEXT: [[TMP7:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP4]] +// IMPRVD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP2]] +// IMPRVD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP8]] +// IMPRVD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP9]], [[TMP4]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[CONV1]] +// IMPRVD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP11]], [[CONV]] +// IMPRVD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[TMP12]] +// IMPRVD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP11]] +// IMPRVD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP14]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP16:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP15]], [[TMP13]] +// IMPRVD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP11]] +// IMPRVD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP17]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP18]], [[TMP13]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD_FAST: complex_div: +// IMPRVD_FAST-NEXT: [[TMP20:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP20]] to half +// IMPRVD_FAST-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP21]] to half +// IMPRVD_FAST-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float +// IMPRVD_FAST-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float +// IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// IMPRVD_FAST-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float +// IMPRVD_FAST-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float +// IMPRVD_FAST-NEXT: [[TMP22:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[EXT5]]) +// IMPRVD_FAST-NEXT: [[TMP23:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[EXT6]]) +// IMPRVD_FAST-NEXT: [[ABS_CMP7:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt float [[TMP22]], [[TMP23]] +// IMPRVD_FAST-NEXT: br i1 [[ABS_CMP7]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI9:%.*]] +// IMPRVD_FAST: abs_rhsr_greater_or_equal_abs_rhsi8: +// IMPRVD_FAST-NEXT: [[TMP24:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[EXT6]], [[EXT5]] +// IMPRVD_FAST-NEXT: [[TMP25:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP24]], [[EXT6]] +// IMPRVD_FAST-NEXT: [[TMP26:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT5]], [[TMP25]] +// IMPRVD_FAST-NEXT: [[TMP27:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[TMP24]] +// IMPRVD_FAST-NEXT: [[TMP28:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP27]] +// IMPRVD_FAST-NEXT: [[TMP29:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP28]], [[TMP26]] +// IMPRVD_FAST-NEXT: [[TMP30:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP24]] +// IMPRVD_FAST-NEXT: [[TMP31:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[EXT4]], [[TMP30]] +// IMPRVD_FAST-NEXT: [[TMP32:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP31]], [[TMP26]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV10:%.*]] +// IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi9: +// IMPRVD_FAST-NEXT: [[TMP33:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[EXT5]], [[EXT6]] +// IMPRVD_FAST-NEXT: [[TMP34:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP33]], [[EXT5]] +// IMPRVD_FAST-NEXT: [[TMP35:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT6]], [[TMP34]] +// IMPRVD_FAST-NEXT: [[TMP36:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP33]] +// IMPRVD_FAST-NEXT: [[TMP37:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP36]], [[EXT4]] +// IMPRVD_FAST-NEXT: [[TMP38:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP37]], [[TMP35]] +// IMPRVD_FAST-NEXT: [[TMP39:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[TMP33]] +// IMPRVD_FAST-NEXT: [[TMP40:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP39]], [[EXT]] +// IMPRVD_FAST-NEXT: [[TMP41:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP40]], [[TMP35]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV10]] +// IMPRVD_FAST: complex_div10: +// IMPRVD_FAST-NEXT: [[TMP42:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP29]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8]] ], [ [[TMP38]], [[ABS_RHSR_LESS_THAN_ABS_RHSI9]] ] +// IMPRVD_FAST-NEXT: [[TMP43:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP32]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8]] ], [ [[TMP41]], [[ABS_RHSR_LESS_THAN_ABS_RHSI9]] ] +// IMPRVD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP42]] to half +// IMPRVD_FAST-NEXT: [[UNPROMOTION11:%.*]] = fptrunc float [[TMP43]] to half +// IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// IMPRVD_FAST-NEXT: store half [[UNPROMOTION11]], ptr [[RETVAL_IMAGP]], align 2 +// IMPRVD_FAST-NEXT: [[TMP44:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// IMPRVD_FAST-NEXT: ret <2 x half> [[TMP44]] +// +// PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @f1( +// PRMTD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { +// PRMTD_FAST-NEXT: entry: +// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 +// PRMTD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 +// PRMTD_FAST-NEXT: [[C:%.*]] = alloca { half, half }, align 2 +// PRMTD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 +// PRMTD_FAST-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 +// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// PRMTD_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 +// PRMTD_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 +// PRMTD_FAST-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 +// PRMTD_FAST-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 +// PRMTD_FAST-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) +// PRMTD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) +// PRMTD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt x86_fp80 [[TMP0]], [[TMP1]] +// PRMTD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// PRMTD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: +// PRMTD_FAST-NEXT: [[TMP2:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[CONV]] +// PRMTD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[CONV1]] +// PRMTD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[TMP3]] +// PRMTD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP2]] +// PRMTD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP5]] +// PRMTD_FAST-NEXT: [[TMP7:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP4]] +// PRMTD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP2]] +// PRMTD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP8]] +// PRMTD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP9]], [[TMP4]] +// PRMTD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] +// PRMTD_FAST: abs_rhsr_less_than_abs_rhsi: +// PRMTD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[CONV1]] +// PRMTD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP11]], [[CONV]] +// PRMTD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[TMP12]] +// PRMTD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP11]] +// PRMTD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP14]], [[B_IMAG]] +// PRMTD_FAST-NEXT: [[TMP16:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP15]], [[TMP13]] +// PRMTD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP11]] +// PRMTD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP17]], [[B_REAL]] +// PRMTD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP18]], [[TMP13]] +// PRMTD_FAST-NEXT: br label [[COMPLEX_DIV]] +// PRMTD_FAST: complex_div: +// PRMTD_FAST-NEXT: [[TMP20:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD_FAST-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP20]] to half +// PRMTD_FAST-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP21]] to half +// PRMTD_FAST-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float +// PRMTD_FAST-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float +// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 +// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 +// PRMTD_FAST-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float +// PRMTD_FAST-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float +// PRMTD_FAST-NEXT: [[TMP22:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT5]] +// PRMTD_FAST-NEXT: [[TMP23:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[EXT6]] +// PRMTD_FAST-NEXT: [[TMP24:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP22]], [[TMP23]] +// PRMTD_FAST-NEXT: [[TMP25:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT5]], [[EXT5]] +// PRMTD_FAST-NEXT: [[TMP26:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT6]], [[EXT6]] +// PRMTD_FAST-NEXT: [[TMP27:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP25]], [[TMP26]] +// PRMTD_FAST-NEXT: [[TMP28:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[EXT5]] +// PRMTD_FAST-NEXT: [[TMP29:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT6]] +// PRMTD_FAST-NEXT: [[TMP30:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP28]], [[TMP29]] +// PRMTD_FAST-NEXT: [[TMP31:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP24]], [[TMP27]] +// PRMTD_FAST-NEXT: [[TMP32:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP30]], [[TMP27]] +// PRMTD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP31]] to half +// PRMTD_FAST-NEXT: [[UNPROMOTION7:%.*]] = fptrunc float [[TMP32]] to half +// PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 +// PRMTD_FAST-NEXT: store half [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 2 +// PRMTD_FAST-NEXT: [[TMP33:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 +// PRMTD_FAST-NEXT: ret <2 x half> [[TMP33]] +// +_Complex _Float16 f1(_Complex _Float16 a, _Complex long double b, _Complex _Float16 c) { + return (_Complex _Float16)(b / c) / a; +} diff --git a/clang/test/CodeGen/complex-math.c b/clang/test/CodeGen/complex-math.c index a44aa0014a65..ba00b9cbecd2 100644 --- a/clang/test/CodeGen/complex-math.c +++ b/clang/test/CodeGen/complex-math.c @@ -5,7 +5,7 @@ // RUN: %clang_cc1 %s -O0 -emit-llvm -triple armv7-none-linux-gnueabi -o - | FileCheck %s --check-prefix=ARM // RUN: %clang_cc1 %s -O0 -emit-llvm -triple armv7-none-linux-gnueabihf -o - | FileCheck %s --check-prefix=ARMHF // RUN: %clang_cc1 %s -O0 -emit-llvm -triple thumbv7k-apple-watchos2.0 -o - -target-abi aapcs16 | FileCheck %s --check-prefix=ARM7K -// RUN: %clang_cc1 %s -O0 -emit-llvm -triple aarch64-unknown-unknown -ffast-math -ffp-contract=fast -complex-range=fortran -o - | FileCheck %s --check-prefix=AARCH64-FASTMATH +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple aarch64-unknown-unknown -ffast-math -ffp-contract=fast -complex-range=improved -o - | FileCheck %s --check-prefix=AARCH64-FASTMATH // RUN: %clang_cc1 %s -O0 -emit-llvm -triple spir -o - | FileCheck %s --check-prefix=SPIR float _Complex add_float_rr(float a, float b) { diff --git a/clang/test/CodeGen/cx-complex-range.c b/clang/test/CodeGen/cx-complex-range.c index 2d8507c710f2..9ec80252085b 100644 --- a/clang/test/CodeGen/cx-complex-range.c +++ b/clang/test/CodeGen/cx-complex-range.c @@ -1,124 +1,3451 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ // RUN: -o - | FileCheck %s --check-prefix=FULL // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -complex-range=limited -o - | FileCheck %s --check-prefix=LMTD +// RUN: -complex-range=basic -o - | FileCheck %s --check-prefix=BASIC // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ // RUN: -fno-cx-limited-range -o - | FileCheck %s --check-prefix=FULL // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -complex-range=fortran -o - | FileCheck %s --check-prefix=FRTRN +// RUN: -complex-range=improved -o - | FileCheck %s --check-prefix=IMPRVD + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -complex-range=promoted -o - | FileCheck %s --check-prefix=PRMTD + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -complex-range=full -o - | FileCheck %s --check-prefix=FULL + +// RUN: %clang_cc1 -triple x86_64-windows-pc -complex-range=promoted \ +// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=X86WINPRMTD + +// RUN: %clang_cc1 -triple=avr-unknown-unknown -mdouble=32 \ +// RUN: -complex-range=promoted -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=AVRFP32 + +// RUN: %clang_cc1 -triple=avr-unknown-unknown -mdouble=64 \ +// RUN: -complex-range=promoted -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=AVRFP64 // Fast math // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ -// RUN: -ffast-math -complex-range=limited -emit-llvm -o - %s \ -// RUN: | FileCheck %s --check-prefix=LMTD-FAST +// RUN: -ffast-math -complex-range=basic -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=BASIC_FAST // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ // RUN: -ffast-math -complex-range=full -emit-llvm -o - %s \ -// RUN: | FileCheck %s --check-prefix=FULL +// RUN: | FileCheck %s --check-prefix=FULL_FAST // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ // RUN: -fno-cx-fortran-rules -o - | FileCheck %s --check-prefix=FULL -// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fcx-limited-range -fno-cx-limited-range -o - \ -// RUN: | FileCheck %s --check-prefix=FULL +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ +// RUN: -ffast-math -complex-range=improved -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=IMPRVD_FAST -// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fno-cx-limited-range -fcx-limited-range -o - \ -// RUN: | FileCheck %s --check-prefix=FULL +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ +// RUN: -ffast-math -complex-range=promoted -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=PRMTD_FAST -// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fno-cx-fortran-rules -fcx-fortran-rules -o - \ -// RUN: | FileCheck %s --check-prefix=FULL - -_Complex float div(_Complex float a, _Complex float b) { - // LABEL: define {{.*}} @div( - // FULL: call {{.*}} @__divsc3 - - // LMTD: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fadd float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fadd float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fsub float - // LMTD-NEXT: fdiv float - // LMTD-NEXT: fdiv float - - // FRTRN: call {{.*}}float @llvm.fabs.f32(float {{.*}}) - // FRTRN-NEXT: call {{.*}}float @llvm.fabs.f32(float {{.*}}) - // FRTRN-NEXT: fcmp {{.*}}ugt float - // FRTRN-NEXT: br i1 {{.*}}, label - // FRTRN: abs_rhsr_greater_or_equal_abs_rhsi: - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fadd {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fadd {{.*}}float - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fsub {{.*}}float - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: br label - // FRTRN: abs_rhsr_less_than_abs_rhsi: - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fadd {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fadd {{.*}}float - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fsub {{.*}}float - // FRTRN-NEXT: fdiv {{.*}}float - // FRTRN-NEXT: br label - // FRTRN: complex_div: - // FRTRN-NEXT: phi {{.*}}float - // FRTRN-NEXT: phi {{.*}}float - - // LMTD-FAST: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fadd {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fadd {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fsub {{.*}} float - // LMTD-FAST-NEXT: fdiv {{.*}} float - // LMTD-FAST-NEXT: fdiv {{.*}} float +// FULL-LABEL: define dso_local <2 x float> @divf( +// FULL-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// FULL-NEXT: entry: +// FULL-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// FULL-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// FULL-NEXT: [[CALL:%.*]] = call <2 x float> @__divsc3(float noundef [[A_REAL]], float noundef [[A_IMAG]], float noundef [[B_REAL]], float noundef [[B_IMAG]]) #[[ATTR2:[0-9]+]] +// FULL-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 +// FULL-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// FULL-NEXT: store float [[COERCE_REAL]], ptr [[RETVAL_REALP]], align 4 +// FULL-NEXT: store float [[COERCE_IMAG]], ptr [[RETVAL_IMAGP]], align 4 +// FULL-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// FULL-NEXT: ret <2 x float> [[TMP0]] +// +// BASIC-LABEL: define dso_local <2 x float> @divf( +// BASIC-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// BASIC-NEXT: entry: +// BASIC-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// BASIC-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// BASIC-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// BASIC-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// BASIC-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// BASIC-NEXT: [[TMP0:%.*]] = fmul float [[A_REAL]], [[B_REAL]] +// BASIC-NEXT: [[TMP1:%.*]] = fmul float [[A_IMAG]], [[B_IMAG]] +// BASIC-NEXT: [[TMP2:%.*]] = fadd float [[TMP0]], [[TMP1]] +// BASIC-NEXT: [[TMP3:%.*]] = fmul float [[B_REAL]], [[B_REAL]] +// BASIC-NEXT: [[TMP4:%.*]] = fmul float [[B_IMAG]], [[B_IMAG]] +// BASIC-NEXT: [[TMP5:%.*]] = fadd float [[TMP3]], [[TMP4]] +// BASIC-NEXT: [[TMP6:%.*]] = fmul float [[A_IMAG]], [[B_REAL]] +// BASIC-NEXT: [[TMP7:%.*]] = fmul float [[A_REAL]], [[B_IMAG]] +// BASIC-NEXT: [[TMP8:%.*]] = fsub float [[TMP6]], [[TMP7]] +// BASIC-NEXT: [[TMP9:%.*]] = fdiv float [[TMP2]], [[TMP5]] +// BASIC-NEXT: [[TMP10:%.*]] = fdiv float [[TMP8]], [[TMP5]] +// BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC-NEXT: store float [[TMP9]], ptr [[RETVAL_REALP]], align 4 +// BASIC-NEXT: store float [[TMP10]], ptr [[RETVAL_IMAGP]], align 4 +// BASIC-NEXT: [[TMP11:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// BASIC-NEXT: ret <2 x float> [[TMP11]] +// +// IMPRVD-LABEL: define dso_local <2 x float> @divf( +// IMPRVD-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// IMPRVD-NEXT: entry: +// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// IMPRVD-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// IMPRVD-NEXT: [[TMP0:%.*]] = call float @llvm.fabs.f32(float [[B_REAL]]) +// IMPRVD-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[B_IMAG]]) +// IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP0]], [[TMP1]] +// IMPRVD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD-NEXT: [[TMP2:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]] +// IMPRVD-NEXT: [[TMP3:%.*]] = fmul float [[TMP2]], [[B_IMAG]] +// IMPRVD-NEXT: [[TMP4:%.*]] = fadd float [[B_REAL]], [[TMP3]] +// IMPRVD-NEXT: [[TMP5:%.*]] = fmul float [[A_IMAG]], [[TMP2]] +// IMPRVD-NEXT: [[TMP6:%.*]] = fadd float [[A_REAL]], [[TMP5]] +// IMPRVD-NEXT: [[TMP7:%.*]] = fdiv float [[TMP6]], [[TMP4]] +// IMPRVD-NEXT: [[TMP8:%.*]] = fmul float [[A_REAL]], [[TMP2]] +// IMPRVD-NEXT: [[TMP9:%.*]] = fsub float [[A_IMAG]], [[TMP8]] +// IMPRVD-NEXT: [[TMP10:%.*]] = fdiv float [[TMP9]], [[TMP4]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD: abs_rhsr_less_than_abs_rhsi: +// IMPRVD-NEXT: [[TMP11:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]] +// IMPRVD-NEXT: [[TMP12:%.*]] = fmul float [[TMP11]], [[B_REAL]] +// IMPRVD-NEXT: [[TMP13:%.*]] = fadd float [[B_IMAG]], [[TMP12]] +// IMPRVD-NEXT: [[TMP14:%.*]] = fmul float [[A_REAL]], [[TMP11]] +// IMPRVD-NEXT: [[TMP15:%.*]] = fadd float [[TMP14]], [[A_IMAG]] +// IMPRVD-NEXT: [[TMP16:%.*]] = fdiv float [[TMP15]], [[TMP13]] +// IMPRVD-NEXT: [[TMP17:%.*]] = fmul float [[A_IMAG]], [[TMP11]] +// IMPRVD-NEXT: [[TMP18:%.*]] = fsub float [[TMP17]], [[A_REAL]] +// IMPRVD-NEXT: [[TMP19:%.*]] = fdiv float [[TMP18]], [[TMP13]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD: complex_div: +// IMPRVD-NEXT: [[TMP20:%.*]] = phi float [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[TMP21:%.*]] = phi float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD-NEXT: store float [[TMP20]], ptr [[RETVAL_REALP]], align 4 +// IMPRVD-NEXT: store float [[TMP21]], ptr [[RETVAL_IMAGP]], align 4 +// IMPRVD-NEXT: [[TMP22:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// IMPRVD-NEXT: ret <2 x float> [[TMP22]] +// +// PRMTD-LABEL: define dso_local <2 x float> @divf( +// PRMTD-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// PRMTD-NEXT: entry: +// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// PRMTD-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// PRMTD-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// PRMTD-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// PRMTD-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// PRMTD-NEXT: [[EXT:%.*]] = fpext float [[A_REAL]] to double +// PRMTD-NEXT: [[EXT1:%.*]] = fpext float [[A_IMAG]] to double +// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// PRMTD-NEXT: [[EXT2:%.*]] = fpext float [[B_REAL]] to double +// PRMTD-NEXT: [[EXT3:%.*]] = fpext float [[B_IMAG]] to double +// PRMTD-NEXT: [[TMP0:%.*]] = fmul double [[EXT]], [[EXT2]] +// PRMTD-NEXT: [[TMP1:%.*]] = fmul double [[EXT1]], [[EXT3]] +// PRMTD-NEXT: [[TMP2:%.*]] = fadd double [[TMP0]], [[TMP1]] +// PRMTD-NEXT: [[TMP3:%.*]] = fmul double [[EXT2]], [[EXT2]] +// PRMTD-NEXT: [[TMP4:%.*]] = fmul double [[EXT3]], [[EXT3]] +// PRMTD-NEXT: [[TMP5:%.*]] = fadd double [[TMP3]], [[TMP4]] +// PRMTD-NEXT: [[TMP6:%.*]] = fmul double [[EXT1]], [[EXT2]] +// PRMTD-NEXT: [[TMP7:%.*]] = fmul double [[EXT]], [[EXT3]] +// PRMTD-NEXT: [[TMP8:%.*]] = fsub double [[TMP6]], [[TMP7]] +// PRMTD-NEXT: [[TMP9:%.*]] = fdiv double [[TMP2]], [[TMP5]] +// PRMTD-NEXT: [[TMP10:%.*]] = fdiv double [[TMP8]], [[TMP5]] +// PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc double [[TMP9]] to float +// PRMTD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc double [[TMP10]] to float +// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD-NEXT: store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4 +// PRMTD-NEXT: store float [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 4 +// PRMTD-NEXT: [[TMP11:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// PRMTD-NEXT: ret <2 x float> [[TMP11]] +// +// X86WINPRMTD-LABEL: define dso_local i64 @divf( +// X86WINPRMTD-SAME: i64 noundef [[A_COERCE:%.*]], i64 noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// X86WINPRMTD-NEXT: entry: +// X86WINPRMTD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// X86WINPRMTD-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// X86WINPRMTD-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// X86WINPRMTD-NEXT: store i64 [[A_COERCE]], ptr [[A]], align 4 +// X86WINPRMTD-NEXT: store i64 [[B_COERCE]], ptr [[B]], align 4 +// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// X86WINPRMTD-NEXT: [[EXT:%.*]] = fpext float [[A_REAL]] to double +// X86WINPRMTD-NEXT: [[EXT1:%.*]] = fpext float [[A_IMAG]] to double +// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// X86WINPRMTD-NEXT: [[EXT2:%.*]] = fpext float [[B_REAL]] to double +// X86WINPRMTD-NEXT: [[EXT3:%.*]] = fpext float [[B_IMAG]] to double +// X86WINPRMTD-NEXT: [[TMP0:%.*]] = fmul double [[EXT]], [[EXT2]] +// X86WINPRMTD-NEXT: [[TMP1:%.*]] = fmul double [[EXT1]], [[EXT3]] +// X86WINPRMTD-NEXT: [[TMP2:%.*]] = fadd double [[TMP0]], [[TMP1]] +// X86WINPRMTD-NEXT: [[TMP3:%.*]] = fmul double [[EXT2]], [[EXT2]] +// X86WINPRMTD-NEXT: [[TMP4:%.*]] = fmul double [[EXT3]], [[EXT3]] +// X86WINPRMTD-NEXT: [[TMP5:%.*]] = fadd double [[TMP3]], [[TMP4]] +// X86WINPRMTD-NEXT: [[TMP6:%.*]] = fmul double [[EXT1]], [[EXT2]] +// X86WINPRMTD-NEXT: [[TMP7:%.*]] = fmul double [[EXT]], [[EXT3]] +// X86WINPRMTD-NEXT: [[TMP8:%.*]] = fsub double [[TMP6]], [[TMP7]] +// X86WINPRMTD-NEXT: [[TMP9:%.*]] = fdiv double [[TMP2]], [[TMP5]] +// X86WINPRMTD-NEXT: [[TMP10:%.*]] = fdiv double [[TMP8]], [[TMP5]] +// X86WINPRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc double [[TMP9]] to float +// X86WINPRMTD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc double [[TMP10]] to float +// X86WINPRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4 +// X86WINPRMTD-NEXT: store float [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 4 +// X86WINPRMTD-NEXT: [[TMP11:%.*]] = load i64, ptr [[RETVAL]], align 4 +// X86WINPRMTD-NEXT: ret i64 [[TMP11]] +// +// AVRFP32-LABEL: define dso_local { float, float } @divf( +// AVRFP32-SAME: float noundef [[A_COERCE0:%.*]], float noundef [[A_COERCE1:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0:[0-9]+]] { +// AVRFP32-NEXT: entry: +// AVRFP32-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[A:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[A_COERCE0]], ptr [[TMP0]], align 1 +// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[A_COERCE1]], ptr [[TMP1]], align 1 +// AVRFP32-NEXT: [[TMP2:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP2]], align 1 +// AVRFP32-NEXT: [[TMP3:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP3]], align 1 +// AVRFP32-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 1 +// AVRFP32-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 1 +// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1 +// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1 +// AVRFP32-NEXT: [[TMP4:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_REAL]]) +// AVRFP32-NEXT: [[TMP5:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_IMAG]]) +// AVRFP32-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP4]], [[TMP5]] +// AVRFP32-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// AVRFP32: abs_rhsr_greater_or_equal_abs_rhsi: +// AVRFP32-NEXT: [[TMP6:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]] +// AVRFP32-NEXT: [[TMP7:%.*]] = fmul float [[TMP6]], [[B_IMAG]] +// AVRFP32-NEXT: [[TMP8:%.*]] = fadd float [[B_REAL]], [[TMP7]] +// AVRFP32-NEXT: [[TMP9:%.*]] = fmul float [[A_IMAG]], [[TMP6]] +// AVRFP32-NEXT: [[TMP10:%.*]] = fadd float [[A_REAL]], [[TMP9]] +// AVRFP32-NEXT: [[TMP11:%.*]] = fdiv float [[TMP10]], [[TMP8]] +// AVRFP32-NEXT: [[TMP12:%.*]] = fmul float [[A_REAL]], [[TMP6]] +// AVRFP32-NEXT: [[TMP13:%.*]] = fsub float [[A_IMAG]], [[TMP12]] +// AVRFP32-NEXT: [[TMP14:%.*]] = fdiv float [[TMP13]], [[TMP8]] +// AVRFP32-NEXT: br label [[COMPLEX_DIV:%.*]] +// AVRFP32: abs_rhsr_less_than_abs_rhsi: +// AVRFP32-NEXT: [[TMP15:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]] +// AVRFP32-NEXT: [[TMP16:%.*]] = fmul float [[TMP15]], [[B_REAL]] +// AVRFP32-NEXT: [[TMP17:%.*]] = fadd float [[B_IMAG]], [[TMP16]] +// AVRFP32-NEXT: [[TMP18:%.*]] = fmul float [[A_REAL]], [[TMP15]] +// AVRFP32-NEXT: [[TMP19:%.*]] = fadd float [[TMP18]], [[A_IMAG]] +// AVRFP32-NEXT: [[TMP20:%.*]] = fdiv float [[TMP19]], [[TMP17]] +// AVRFP32-NEXT: [[TMP21:%.*]] = fmul float [[A_IMAG]], [[TMP15]] +// AVRFP32-NEXT: [[TMP22:%.*]] = fsub float [[TMP21]], [[A_REAL]] +// AVRFP32-NEXT: [[TMP23:%.*]] = fdiv float [[TMP22]], [[TMP17]] +// AVRFP32-NEXT: br label [[COMPLEX_DIV]] +// AVRFP32: complex_div: +// AVRFP32-NEXT: [[TMP24:%.*]] = phi float [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP32-NEXT: [[TMP25:%.*]] = phi float [ [[TMP14]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP23]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// AVRFP32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[TMP24]], ptr [[RETVAL_REALP]], align 1 +// AVRFP32-NEXT: store float [[TMP25]], ptr [[RETVAL_IMAGP]], align 1 +// AVRFP32-NEXT: [[TMP26:%.*]] = load { float, float }, ptr [[RETVAL]], align 1 +// AVRFP32-NEXT: ret { float, float } [[TMP26]] +// +// AVRFP64-LABEL: define dso_local { float, float } @divf( +// AVRFP64-SAME: float noundef [[A_COERCE0:%.*]], float noundef [[A_COERCE1:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0:[0-9]+]] { +// AVRFP64-NEXT: entry: +// AVRFP64-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 1 +// AVRFP64-NEXT: [[A:%.*]] = alloca { float, float }, align 1 +// AVRFP64-NEXT: [[B:%.*]] = alloca { float, float }, align 1 +// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: store float [[A_COERCE0]], ptr [[TMP0]], align 1 +// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: store float [[A_COERCE1]], ptr [[TMP1]], align 1 +// AVRFP64-NEXT: [[TMP2:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: store float [[B_COERCE0]], ptr [[TMP2]], align 1 +// AVRFP64-NEXT: [[TMP3:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: store float [[B_COERCE1]], ptr [[TMP3]], align 1 +// AVRFP64-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 1 +// AVRFP64-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 1 +// AVRFP64-NEXT: [[EXT:%.*]] = fpext float [[A_REAL]] to double +// AVRFP64-NEXT: [[EXT1:%.*]] = fpext float [[A_IMAG]] to double +// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1 +// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1 +// AVRFP64-NEXT: [[EXT2:%.*]] = fpext float [[B_REAL]] to double +// AVRFP64-NEXT: [[EXT3:%.*]] = fpext float [[B_IMAG]] to double +// AVRFP64-NEXT: [[TMP4:%.*]] = fmul double [[EXT]], [[EXT2]] +// AVRFP64-NEXT: [[TMP5:%.*]] = fmul double [[EXT1]], [[EXT3]] +// AVRFP64-NEXT: [[TMP6:%.*]] = fadd double [[TMP4]], [[TMP5]] +// AVRFP64-NEXT: [[TMP7:%.*]] = fmul double [[EXT2]], [[EXT2]] +// AVRFP64-NEXT: [[TMP8:%.*]] = fmul double [[EXT3]], [[EXT3]] +// AVRFP64-NEXT: [[TMP9:%.*]] = fadd double [[TMP7]], [[TMP8]] +// AVRFP64-NEXT: [[TMP10:%.*]] = fmul double [[EXT1]], [[EXT2]] +// AVRFP64-NEXT: [[TMP11:%.*]] = fmul double [[EXT]], [[EXT3]] +// AVRFP64-NEXT: [[TMP12:%.*]] = fsub double [[TMP10]], [[TMP11]] +// AVRFP64-NEXT: [[TMP13:%.*]] = fdiv double [[TMP6]], [[TMP9]] +// AVRFP64-NEXT: [[TMP14:%.*]] = fdiv double [[TMP12]], [[TMP9]] +// AVRFP64-NEXT: [[UNPROMOTION:%.*]] = fptrunc double [[TMP13]] to float +// AVRFP64-NEXT: [[UNPROMOTION4:%.*]] = fptrunc double [[TMP14]] to float +// AVRFP64-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// AVRFP64-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// AVRFP64-NEXT: store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 1 +// AVRFP64-NEXT: store float [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 1 +// AVRFP64-NEXT: [[TMP15:%.*]] = load { float, float }, ptr [[RETVAL]], align 1 +// AVRFP64-NEXT: ret { float, float } [[TMP15]] +// +// BASIC_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @divf( +// BASIC_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// BASIC_FAST-NEXT: entry: +// BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// BASIC_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// BASIC_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// BASIC_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// BASIC_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// BASIC_FAST-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[B_REAL]] +// BASIC_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[TMP2:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP0]], [[TMP1]] +// BASIC_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[B_REAL]], [[B_REAL]] +// BASIC_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[B_IMAG]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP3]], [[TMP4]] +// BASIC_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[B_REAL]] +// BASIC_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[TMP8:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP6]], [[TMP7]] +// BASIC_FAST-NEXT: [[TMP9:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP2]], [[TMP5]] +// BASIC_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP8]], [[TMP5]] +// BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC_FAST-NEXT: store float [[TMP9]], ptr [[RETVAL_REALP]], align 4 +// BASIC_FAST-NEXT: store float [[TMP10]], ptr [[RETVAL_IMAGP]], align 4 +// BASIC_FAST-NEXT: [[TMP11:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// BASIC_FAST-NEXT: ret <2 x float> [[TMP11]] +// +// FULL_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @divf( +// FULL_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// FULL_FAST-NEXT: entry: +// FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// FULL_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// FULL_FAST-NEXT: [[CALL:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) <2 x float> @__divsc3(float noundef nofpclass(nan inf) [[A_REAL]], float noundef nofpclass(nan inf) [[A_IMAG]], float noundef nofpclass(nan inf) [[B_REAL]], float noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2:[0-9]+]] +// FULL_FAST-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 +// FULL_FAST-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL_FAST-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL_FAST-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL_FAST-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// FULL_FAST-NEXT: store float [[COERCE_REAL]], ptr [[RETVAL_REALP]], align 4 +// FULL_FAST-NEXT: store float [[COERCE_IMAG]], ptr [[RETVAL_IMAGP]], align 4 +// FULL_FAST-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// FULL_FAST-NEXT: ret <2 x float> [[TMP0]] +// +// IMPRVD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @divf( +// IMPRVD_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// IMPRVD_FAST-NEXT: entry: +// IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// IMPRVD_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// IMPRVD_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// IMPRVD_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[B_REAL]]) +// IMPRVD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[B_IMAG]]) +// IMPRVD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt float [[TMP0]], [[TMP1]] +// IMPRVD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP2:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[B_IMAG]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP2]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[B_REAL]], [[TMP3]] +// IMPRVD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[TMP2]] +// IMPRVD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[TMP5]] +// IMPRVD_FAST-NEXT: [[TMP7:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP6]], [[TMP4]] +// IMPRVD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[TMP2]] +// IMPRVD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[TMP8]] +// IMPRVD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP9]], [[TMP4]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[B_REAL]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP11]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[B_IMAG]], [[TMP12]] +// IMPRVD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[TMP11]] +// IMPRVD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP14]], [[A_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP16:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP15]], [[TMP13]] +// IMPRVD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[TMP11]] +// IMPRVD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP17]], [[A_REAL]] +// IMPRVD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP18]], [[TMP13]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD_FAST: complex_div: +// IMPRVD_FAST-NEXT: [[TMP20:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store float [[TMP20]], ptr [[RETVAL_REALP]], align 4 +// IMPRVD_FAST-NEXT: store float [[TMP21]], ptr [[RETVAL_IMAGP]], align 4 +// IMPRVD_FAST-NEXT: [[TMP22:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// IMPRVD_FAST-NEXT: ret <2 x float> [[TMP22]] +// +// PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @divf( +// PRMTD_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// PRMTD_FAST-NEXT: entry: +// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// PRMTD_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// PRMTD_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// PRMTD_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// PRMTD_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// PRMTD_FAST-NEXT: [[EXT:%.*]] = fpext float [[A_REAL]] to double +// PRMTD_FAST-NEXT: [[EXT1:%.*]] = fpext float [[A_IMAG]] to double +// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// PRMTD_FAST-NEXT: [[EXT2:%.*]] = fpext float [[B_REAL]] to double +// PRMTD_FAST-NEXT: [[EXT3:%.*]] = fpext float [[B_IMAG]] to double +// PRMTD_FAST-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT]], [[EXT2]] +// PRMTD_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT1]], [[EXT3]] +// PRMTD_FAST-NEXT: [[TMP2:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[TMP0]], [[TMP1]] +// PRMTD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT2]], [[EXT2]] +// PRMTD_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT3]], [[EXT3]] +// PRMTD_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[TMP3]], [[TMP4]] +// PRMTD_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT1]], [[EXT2]] +// PRMTD_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT]], [[EXT3]] +// PRMTD_FAST-NEXT: [[TMP8:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[TMP6]], [[TMP7]] +// PRMTD_FAST-NEXT: [[TMP9:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP2]], [[TMP5]] +// PRMTD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP8]], [[TMP5]] +// PRMTD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc double [[TMP9]] to float +// PRMTD_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc double [[TMP10]] to float +// PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4 +// PRMTD_FAST-NEXT: store float [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 4 +// PRMTD_FAST-NEXT: [[TMP11:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// PRMTD_FAST-NEXT: ret <2 x float> [[TMP11]] +// +_Complex float divf(_Complex float a, _Complex float b) { + return a / b; +} + +// FULL-LABEL: define dso_local <2 x float> @mulf( +// FULL-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { +// FULL-NEXT: entry: +// FULL-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// FULL-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// FULL-NEXT: [[MUL_AC:%.*]] = fmul float [[A_REAL]], [[B_REAL]] +// FULL-NEXT: [[MUL_BD:%.*]] = fmul float [[A_IMAG]], [[B_IMAG]] +// FULL-NEXT: [[MUL_AD:%.*]] = fmul float [[A_REAL]], [[B_IMAG]] +// FULL-NEXT: [[MUL_BC:%.*]] = fmul float [[A_IMAG]], [[B_REAL]] +// FULL-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// FULL-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// FULL-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno float [[MUL_R]], [[MUL_R]] +// FULL-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2:![0-9]+]] +// FULL: complex_mul_imag_nan: +// FULL-NEXT: [[ISNAN_CMP1:%.*]] = fcmp uno float [[MUL_I]], [[MUL_I]] +// FULL-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]] +// FULL: complex_mul_libcall: +// FULL-NEXT: [[CALL:%.*]] = call <2 x float> @__mulsc3(float noundef [[A_REAL]], float noundef [[A_IMAG]], float noundef [[B_REAL]], float noundef [[B_IMAG]]) #[[ATTR2]] +// FULL-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 +// FULL-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL-NEXT: br label [[COMPLEX_MUL_CONT]] +// FULL: complex_mul_cont: +// FULL-NEXT: [[REAL_MUL_PHI:%.*]] = phi float [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_REAL]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL-NEXT: [[IMAG_MUL_PHI:%.*]] = phi float [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_IMAG]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// FULL-NEXT: store float [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 4 +// FULL-NEXT: store float [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 4 +// FULL-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// FULL-NEXT: ret <2 x float> [[TMP0]] +// +// BASIC-LABEL: define dso_local <2 x float> @mulf( +// BASIC-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { +// BASIC-NEXT: entry: +// BASIC-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// BASIC-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// BASIC-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// BASIC-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// BASIC-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// BASIC-NEXT: [[MUL_AC:%.*]] = fmul float [[A_REAL]], [[B_REAL]] +// BASIC-NEXT: [[MUL_BD:%.*]] = fmul float [[A_IMAG]], [[B_IMAG]] +// BASIC-NEXT: [[MUL_AD:%.*]] = fmul float [[A_REAL]], [[B_IMAG]] +// BASIC-NEXT: [[MUL_BC:%.*]] = fmul float [[A_IMAG]], [[B_REAL]] +// BASIC-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// BASIC-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC-NEXT: store float [[MUL_R]], ptr [[RETVAL_REALP]], align 4 +// BASIC-NEXT: store float [[MUL_I]], ptr [[RETVAL_IMAGP]], align 4 +// BASIC-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// BASIC-NEXT: ret <2 x float> [[TMP0]] +// +// IMPRVD-LABEL: define dso_local <2 x float> @mulf( +// IMPRVD-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { +// IMPRVD-NEXT: entry: +// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// IMPRVD-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// IMPRVD-NEXT: [[MUL_AC:%.*]] = fmul float [[A_REAL]], [[B_REAL]] +// IMPRVD-NEXT: [[MUL_BD:%.*]] = fmul float [[A_IMAG]], [[B_IMAG]] +// IMPRVD-NEXT: [[MUL_AD:%.*]] = fmul float [[A_REAL]], [[B_IMAG]] +// IMPRVD-NEXT: [[MUL_BC:%.*]] = fmul float [[A_IMAG]], [[B_REAL]] +// IMPRVD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// IMPRVD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD-NEXT: store float [[MUL_R]], ptr [[RETVAL_REALP]], align 4 +// IMPRVD-NEXT: store float [[MUL_I]], ptr [[RETVAL_IMAGP]], align 4 +// IMPRVD-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// IMPRVD-NEXT: ret <2 x float> [[TMP0]] +// +// PRMTD-LABEL: define dso_local <2 x float> @mulf( +// PRMTD-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { +// PRMTD-NEXT: entry: +// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// PRMTD-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// PRMTD-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// PRMTD-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// PRMTD-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// PRMTD-NEXT: [[MUL_AC:%.*]] = fmul float [[A_REAL]], [[B_REAL]] +// PRMTD-NEXT: [[MUL_BD:%.*]] = fmul float [[A_IMAG]], [[B_IMAG]] +// PRMTD-NEXT: [[MUL_AD:%.*]] = fmul float [[A_REAL]], [[B_IMAG]] +// PRMTD-NEXT: [[MUL_BC:%.*]] = fmul float [[A_IMAG]], [[B_REAL]] +// PRMTD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// PRMTD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD-NEXT: store float [[MUL_R]], ptr [[RETVAL_REALP]], align 4 +// PRMTD-NEXT: store float [[MUL_I]], ptr [[RETVAL_IMAGP]], align 4 +// PRMTD-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// PRMTD-NEXT: ret <2 x float> [[TMP0]] +// +// X86WINPRMTD-LABEL: define dso_local i64 @mulf( +// X86WINPRMTD-SAME: i64 noundef [[A_COERCE:%.*]], i64 noundef [[B_COERCE:%.*]]) #[[ATTR0]] { +// X86WINPRMTD-NEXT: entry: +// X86WINPRMTD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// X86WINPRMTD-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// X86WINPRMTD-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// X86WINPRMTD-NEXT: store i64 [[A_COERCE]], ptr [[A]], align 4 +// X86WINPRMTD-NEXT: store i64 [[B_COERCE]], ptr [[B]], align 4 +// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// X86WINPRMTD-NEXT: [[MUL_AC:%.*]] = fmul float [[A_REAL]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[MUL_BD:%.*]] = fmul float [[A_IMAG]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[MUL_AD:%.*]] = fmul float [[A_REAL]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[MUL_BC:%.*]] = fmul float [[A_IMAG]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// X86WINPRMTD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// X86WINPRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store float [[MUL_R]], ptr [[RETVAL_REALP]], align 4 +// X86WINPRMTD-NEXT: store float [[MUL_I]], ptr [[RETVAL_IMAGP]], align 4 +// X86WINPRMTD-NEXT: [[TMP0:%.*]] = load i64, ptr [[RETVAL]], align 4 +// X86WINPRMTD-NEXT: ret i64 [[TMP0]] +// +// AVRFP32-LABEL: define dso_local { float, float } @mulf( +// AVRFP32-SAME: float noundef [[A_COERCE0:%.*]], float noundef [[A_COERCE1:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP32-NEXT: entry: +// AVRFP32-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[A:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[A_COERCE0]], ptr [[TMP0]], align 1 +// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[A_COERCE1]], ptr [[TMP1]], align 1 +// AVRFP32-NEXT: [[TMP2:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP2]], align 1 +// AVRFP32-NEXT: [[TMP3:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP3]], align 1 +// AVRFP32-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 1 +// AVRFP32-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 1 +// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1 +// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1 +// AVRFP32-NEXT: [[MUL_AC:%.*]] = fmul float [[A_REAL]], [[B_REAL]] +// AVRFP32-NEXT: [[MUL_BD:%.*]] = fmul float [[A_IMAG]], [[B_IMAG]] +// AVRFP32-NEXT: [[MUL_AD:%.*]] = fmul float [[A_REAL]], [[B_IMAG]] +// AVRFP32-NEXT: [[MUL_BC:%.*]] = fmul float [[A_IMAG]], [[B_REAL]] +// AVRFP32-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// AVRFP32-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// AVRFP32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// AVRFP32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[MUL_R]], ptr [[RETVAL_REALP]], align 1 +// AVRFP32-NEXT: store float [[MUL_I]], ptr [[RETVAL_IMAGP]], align 1 +// AVRFP32-NEXT: [[TMP4:%.*]] = load { float, float }, ptr [[RETVAL]], align 1 +// AVRFP32-NEXT: ret { float, float } [[TMP4]] +// +// AVRFP64-LABEL: define dso_local { float, float } @mulf( +// AVRFP64-SAME: float noundef [[A_COERCE0:%.*]], float noundef [[A_COERCE1:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP64-NEXT: entry: +// AVRFP64-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 1 +// AVRFP64-NEXT: [[A:%.*]] = alloca { float, float }, align 1 +// AVRFP64-NEXT: [[B:%.*]] = alloca { float, float }, align 1 +// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: store float [[A_COERCE0]], ptr [[TMP0]], align 1 +// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: store float [[A_COERCE1]], ptr [[TMP1]], align 1 +// AVRFP64-NEXT: [[TMP2:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: store float [[B_COERCE0]], ptr [[TMP2]], align 1 +// AVRFP64-NEXT: [[TMP3:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: store float [[B_COERCE1]], ptr [[TMP3]], align 1 +// AVRFP64-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 1 +// AVRFP64-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 1 +// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1 +// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1 +// AVRFP64-NEXT: [[MUL_AC:%.*]] = fmul float [[A_REAL]], [[B_REAL]] +// AVRFP64-NEXT: [[MUL_BD:%.*]] = fmul float [[A_IMAG]], [[B_IMAG]] +// AVRFP64-NEXT: [[MUL_AD:%.*]] = fmul float [[A_REAL]], [[B_IMAG]] +// AVRFP64-NEXT: [[MUL_BC:%.*]] = fmul float [[A_IMAG]], [[B_REAL]] +// AVRFP64-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// AVRFP64-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// AVRFP64-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// AVRFP64-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// AVRFP64-NEXT: store float [[MUL_R]], ptr [[RETVAL_REALP]], align 1 +// AVRFP64-NEXT: store float [[MUL_I]], ptr [[RETVAL_IMAGP]], align 1 +// AVRFP64-NEXT: [[TMP4:%.*]] = load { float, float }, ptr [[RETVAL]], align 1 +// AVRFP64-NEXT: ret { float, float } [[TMP4]] +// +// BASIC_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @mulf( +// BASIC_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { +// BASIC_FAST-NEXT: entry: +// BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// BASIC_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// BASIC_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// BASIC_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// BASIC_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// BASIC_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[B_REAL]] +// BASIC_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[B_REAL]] +// BASIC_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] +// BASIC_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] +// BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC_FAST-NEXT: store float [[MUL_R]], ptr [[RETVAL_REALP]], align 4 +// BASIC_FAST-NEXT: store float [[MUL_I]], ptr [[RETVAL_IMAGP]], align 4 +// BASIC_FAST-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// BASIC_FAST-NEXT: ret <2 x float> [[TMP0]] +// +// FULL_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @mulf( +// FULL_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { +// FULL_FAST-NEXT: entry: +// FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// FULL_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// FULL_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[B_REAL]] +// FULL_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[B_IMAG]] +// FULL_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[B_IMAG]] +// FULL_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[B_REAL]] +// FULL_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] +// FULL_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] +// FULL_FAST-NEXT: [[ISNAN_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno float [[MUL_R]], [[MUL_R]] +// FULL_FAST-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2:![0-9]+]] +// FULL_FAST: complex_mul_imag_nan: +// FULL_FAST-NEXT: [[ISNAN_CMP1:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno float [[MUL_I]], [[MUL_I]] +// FULL_FAST-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]] +// FULL_FAST: complex_mul_libcall: +// FULL_FAST-NEXT: [[CALL:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) <2 x float> @__mulsc3(float noundef nofpclass(nan inf) [[A_REAL]], float noundef nofpclass(nan inf) [[A_IMAG]], float noundef nofpclass(nan inf) [[B_REAL]], float noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2]] +// FULL_FAST-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 +// FULL_FAST-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL_FAST-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL_FAST-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL_FAST-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL_FAST-NEXT: br label [[COMPLEX_MUL_CONT]] +// FULL_FAST: complex_mul_cont: +// FULL_FAST-NEXT: [[REAL_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_REAL]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL_FAST-NEXT: [[IMAG_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_IMAG]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// FULL_FAST-NEXT: store float [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 4 +// FULL_FAST-NEXT: store float [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 4 +// FULL_FAST-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// FULL_FAST-NEXT: ret <2 x float> [[TMP0]] +// +// IMPRVD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @mulf( +// IMPRVD_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { +// IMPRVD_FAST-NEXT: entry: +// IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// IMPRVD_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// IMPRVD_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// IMPRVD_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// IMPRVD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] +// IMPRVD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] +// IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store float [[MUL_R]], ptr [[RETVAL_REALP]], align 4 +// IMPRVD_FAST-NEXT: store float [[MUL_I]], ptr [[RETVAL_IMAGP]], align 4 +// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// IMPRVD_FAST-NEXT: ret <2 x float> [[TMP0]] +// +// PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @mulf( +// PRMTD_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { +// PRMTD_FAST-NEXT: entry: +// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// PRMTD_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// PRMTD_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// PRMTD_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// PRMTD_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// PRMTD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[B_REAL]] +// PRMTD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[B_IMAG]] +// PRMTD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[B_IMAG]] +// PRMTD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[B_REAL]] +// PRMTD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] +// PRMTD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] +// PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store float [[MUL_R]], ptr [[RETVAL_REALP]], align 4 +// PRMTD_FAST-NEXT: store float [[MUL_I]], ptr [[RETVAL_IMAGP]], align 4 +// PRMTD_FAST-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// PRMTD_FAST-NEXT: ret <2 x float> [[TMP0]] +// +_Complex float mulf(_Complex float a, _Complex float b) { + return a * b; +} +// FULL-LABEL: define dso_local { double, double } @divd( +// FULL-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] { +// FULL-NEXT: entry: +// FULL-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// FULL-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// FULL-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// FULL-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// FULL-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// FULL-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// FULL-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// FULL-NEXT: [[CALL:%.*]] = call { double, double } @__divdc3(double noundef [[A_REAL]], double noundef [[A_IMAG]], double noundef [[B_REAL]], double noundef [[B_IMAG]]) #[[ATTR2]] +// FULL-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 0 +// FULL-NEXT: [[TMP5:%.*]] = extractvalue { double, double } [[CALL]], 1 +// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// FULL-NEXT: store double [[TMP4]], ptr [[RETVAL_REALP]], align 8 +// FULL-NEXT: store double [[TMP5]], ptr [[RETVAL_IMAGP]], align 8 +// FULL-NEXT: [[TMP6:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// FULL-NEXT: ret { double, double } [[TMP6]] +// +// BASIC-LABEL: define dso_local { double, double } @divd( +// BASIC-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] { +// BASIC-NEXT: entry: +// BASIC-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// BASIC-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// BASIC-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// BASIC-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// BASIC-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// BASIC-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// BASIC-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// BASIC-NEXT: [[TMP4:%.*]] = fmul double [[A_REAL]], [[B_REAL]] +// BASIC-NEXT: [[TMP5:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]] +// BASIC-NEXT: [[TMP6:%.*]] = fadd double [[TMP4]], [[TMP5]] +// BASIC-NEXT: [[TMP7:%.*]] = fmul double [[B_REAL]], [[B_REAL]] +// BASIC-NEXT: [[TMP8:%.*]] = fmul double [[B_IMAG]], [[B_IMAG]] +// BASIC-NEXT: [[TMP9:%.*]] = fadd double [[TMP7]], [[TMP8]] +// BASIC-NEXT: [[TMP10:%.*]] = fmul double [[A_IMAG]], [[B_REAL]] +// BASIC-NEXT: [[TMP11:%.*]] = fmul double [[A_REAL]], [[B_IMAG]] +// BASIC-NEXT: [[TMP12:%.*]] = fsub double [[TMP10]], [[TMP11]] +// BASIC-NEXT: [[TMP13:%.*]] = fdiv double [[TMP6]], [[TMP9]] +// BASIC-NEXT: [[TMP14:%.*]] = fdiv double [[TMP12]], [[TMP9]] +// BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC-NEXT: store double [[TMP13]], ptr [[RETVAL_REALP]], align 8 +// BASIC-NEXT: store double [[TMP14]], ptr [[RETVAL_IMAGP]], align 8 +// BASIC-NEXT: [[TMP15:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// BASIC-NEXT: ret { double, double } [[TMP15]] +// +// IMPRVD-LABEL: define dso_local { double, double } @divd( +// IMPRVD-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR2:[0-9]+]] { +// IMPRVD-NEXT: entry: +// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// IMPRVD-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// IMPRVD-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// IMPRVD-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// IMPRVD-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// IMPRVD-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// IMPRVD-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// IMPRVD-NEXT: [[TMP4:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]]) +// IMPRVD-NEXT: [[TMP5:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]]) +// IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP4]], [[TMP5]] +// IMPRVD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD-NEXT: [[TMP6:%.*]] = fdiv double [[B_IMAG]], [[B_REAL]] +// IMPRVD-NEXT: [[TMP7:%.*]] = fmul double [[TMP6]], [[B_IMAG]] +// IMPRVD-NEXT: [[TMP8:%.*]] = fadd double [[B_REAL]], [[TMP7]] +// IMPRVD-NEXT: [[TMP9:%.*]] = fmul double [[A_IMAG]], [[TMP6]] +// IMPRVD-NEXT: [[TMP10:%.*]] = fadd double [[A_REAL]], [[TMP9]] +// IMPRVD-NEXT: [[TMP11:%.*]] = fdiv double [[TMP10]], [[TMP8]] +// IMPRVD-NEXT: [[TMP12:%.*]] = fmul double [[A_REAL]], [[TMP6]] +// IMPRVD-NEXT: [[TMP13:%.*]] = fsub double [[A_IMAG]], [[TMP12]] +// IMPRVD-NEXT: [[TMP14:%.*]] = fdiv double [[TMP13]], [[TMP8]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD: abs_rhsr_less_than_abs_rhsi: +// IMPRVD-NEXT: [[TMP15:%.*]] = fdiv double [[B_REAL]], [[B_IMAG]] +// IMPRVD-NEXT: [[TMP16:%.*]] = fmul double [[TMP15]], [[B_REAL]] +// IMPRVD-NEXT: [[TMP17:%.*]] = fadd double [[B_IMAG]], [[TMP16]] +// IMPRVD-NEXT: [[TMP18:%.*]] = fmul double [[A_REAL]], [[TMP15]] +// IMPRVD-NEXT: [[TMP19:%.*]] = fadd double [[TMP18]], [[A_IMAG]] +// IMPRVD-NEXT: [[TMP20:%.*]] = fdiv double [[TMP19]], [[TMP17]] +// IMPRVD-NEXT: [[TMP21:%.*]] = fmul double [[A_IMAG]], [[TMP15]] +// IMPRVD-NEXT: [[TMP22:%.*]] = fsub double [[TMP21]], [[A_REAL]] +// IMPRVD-NEXT: [[TMP23:%.*]] = fdiv double [[TMP22]], [[TMP17]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD: complex_div: +// IMPRVD-NEXT: [[TMP24:%.*]] = phi double [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[TMP25:%.*]] = phi double [ [[TMP14]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP23]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD-NEXT: store double [[TMP24]], ptr [[RETVAL_REALP]], align 8 +// IMPRVD-NEXT: store double [[TMP25]], ptr [[RETVAL_IMAGP]], align 8 +// IMPRVD-NEXT: [[TMP26:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// IMPRVD-NEXT: ret { double, double } [[TMP26]] +// +// PRMTD-LABEL: define dso_local { double, double } @divd( +// PRMTD-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] { +// PRMTD-NEXT: entry: +// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// PRMTD-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// PRMTD-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// PRMTD-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// PRMTD-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// PRMTD-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// PRMTD-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// PRMTD-NEXT: [[EXT:%.*]] = fpext double [[A_REAL]] to x86_fp80 +// PRMTD-NEXT: [[EXT1:%.*]] = fpext double [[A_IMAG]] to x86_fp80 +// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// PRMTD-NEXT: [[EXT2:%.*]] = fpext double [[B_REAL]] to x86_fp80 +// PRMTD-NEXT: [[EXT3:%.*]] = fpext double [[B_IMAG]] to x86_fp80 +// PRMTD-NEXT: [[TMP4:%.*]] = fmul x86_fp80 [[EXT]], [[EXT2]] +// PRMTD-NEXT: [[TMP5:%.*]] = fmul x86_fp80 [[EXT1]], [[EXT3]] +// PRMTD-NEXT: [[TMP6:%.*]] = fadd x86_fp80 [[TMP4]], [[TMP5]] +// PRMTD-NEXT: [[TMP7:%.*]] = fmul x86_fp80 [[EXT2]], [[EXT2]] +// PRMTD-NEXT: [[TMP8:%.*]] = fmul x86_fp80 [[EXT3]], [[EXT3]] +// PRMTD-NEXT: [[TMP9:%.*]] = fadd x86_fp80 [[TMP7]], [[TMP8]] +// PRMTD-NEXT: [[TMP10:%.*]] = fmul x86_fp80 [[EXT1]], [[EXT2]] +// PRMTD-NEXT: [[TMP11:%.*]] = fmul x86_fp80 [[EXT]], [[EXT3]] +// PRMTD-NEXT: [[TMP12:%.*]] = fsub x86_fp80 [[TMP10]], [[TMP11]] +// PRMTD-NEXT: [[TMP13:%.*]] = fdiv x86_fp80 [[TMP6]], [[TMP9]] +// PRMTD-NEXT: [[TMP14:%.*]] = fdiv x86_fp80 [[TMP12]], [[TMP9]] +// PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc x86_fp80 [[TMP13]] to double +// PRMTD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc x86_fp80 [[TMP14]] to double +// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD-NEXT: store double [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 8 +// PRMTD-NEXT: store double [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 8 +// PRMTD-NEXT: [[TMP15:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// PRMTD-NEXT: ret { double, double } [[TMP15]] +// +// X86WINPRMTD-LABEL: define dso_local void @divd( +// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] { +// X86WINPRMTD-NEXT: entry: +// X86WINPRMTD-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: [[A_INDIRECT_ADDR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: store ptr [[AGG_RESULT]], ptr [[RESULT_PTR]], align 8 +// X86WINPRMTD-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8 +// X86WINPRMTD-NEXT: store ptr [[A]], ptr [[A_INDIRECT_ADDR]], align 8 +// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[TMP0:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]]) +// X86WINPRMTD-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]]) +// X86WINPRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP0]], [[TMP1]] +// X86WINPRMTD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// X86WINPRMTD: abs_rhsr_greater_or_equal_abs_rhsi: +// X86WINPRMTD-NEXT: [[TMP2:%.*]] = fdiv double [[B_IMAG]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[TMP3:%.*]] = fmul double [[TMP2]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[TMP4:%.*]] = fadd double [[B_REAL]], [[TMP3]] +// X86WINPRMTD-NEXT: [[TMP5:%.*]] = fmul double [[A_IMAG]], [[TMP2]] +// X86WINPRMTD-NEXT: [[TMP6:%.*]] = fadd double [[A_REAL]], [[TMP5]] +// X86WINPRMTD-NEXT: [[TMP7:%.*]] = fdiv double [[TMP6]], [[TMP4]] +// X86WINPRMTD-NEXT: [[TMP8:%.*]] = fmul double [[A_REAL]], [[TMP2]] +// X86WINPRMTD-NEXT: [[TMP9:%.*]] = fsub double [[A_IMAG]], [[TMP8]] +// X86WINPRMTD-NEXT: [[TMP10:%.*]] = fdiv double [[TMP9]], [[TMP4]] +// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV:%.*]] +// X86WINPRMTD: abs_rhsr_less_than_abs_rhsi: +// X86WINPRMTD-NEXT: [[TMP11:%.*]] = fdiv double [[B_REAL]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[TMP12:%.*]] = fmul double [[TMP11]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[TMP13:%.*]] = fadd double [[B_IMAG]], [[TMP12]] +// X86WINPRMTD-NEXT: [[TMP14:%.*]] = fmul double [[A_REAL]], [[TMP11]] +// X86WINPRMTD-NEXT: [[TMP15:%.*]] = fadd double [[TMP14]], [[A_IMAG]] +// X86WINPRMTD-NEXT: [[TMP16:%.*]] = fdiv double [[TMP15]], [[TMP13]] +// X86WINPRMTD-NEXT: [[TMP17:%.*]] = fmul double [[A_IMAG]], [[TMP11]] +// X86WINPRMTD-NEXT: [[TMP18:%.*]] = fsub double [[TMP17]], [[A_REAL]] +// X86WINPRMTD-NEXT: [[TMP19:%.*]] = fdiv double [[TMP18]], [[TMP13]] +// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV]] +// X86WINPRMTD: complex_div: +// X86WINPRMTD-NEXT: [[TMP20:%.*]] = phi double [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// X86WINPRMTD-NEXT: [[TMP21:%.*]] = phi double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store double [[TMP20]], ptr [[AGG_RESULT_REALP]], align 8 +// X86WINPRMTD-NEXT: store double [[TMP21]], ptr [[AGG_RESULT_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8 +// X86WINPRMTD-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8 +// X86WINPRMTD-NEXT: ret void +// +// AVRFP32-LABEL: define dso_local { float, float } @divd( +// AVRFP32-SAME: float noundef [[A_COERCE0:%.*]], float noundef [[A_COERCE1:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP32-NEXT: entry: +// AVRFP32-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[A_COERCE0]], ptr [[TMP0]], align 4 +// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[A_COERCE1]], ptr [[TMP1]], align 4 +// AVRFP32-NEXT: [[TMP2:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP2]], align 4 +// AVRFP32-NEXT: [[TMP3:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP3]], align 4 +// AVRFP32-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// AVRFP32-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// AVRFP32-NEXT: [[TMP4:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_REAL]]) +// AVRFP32-NEXT: [[TMP5:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_IMAG]]) +// AVRFP32-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP4]], [[TMP5]] +// AVRFP32-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// AVRFP32: abs_rhsr_greater_or_equal_abs_rhsi: +// AVRFP32-NEXT: [[TMP6:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]] +// AVRFP32-NEXT: [[TMP7:%.*]] = fmul float [[TMP6]], [[B_IMAG]] +// AVRFP32-NEXT: [[TMP8:%.*]] = fadd float [[B_REAL]], [[TMP7]] +// AVRFP32-NEXT: [[TMP9:%.*]] = fmul float [[A_IMAG]], [[TMP6]] +// AVRFP32-NEXT: [[TMP10:%.*]] = fadd float [[A_REAL]], [[TMP9]] +// AVRFP32-NEXT: [[TMP11:%.*]] = fdiv float [[TMP10]], [[TMP8]] +// AVRFP32-NEXT: [[TMP12:%.*]] = fmul float [[A_REAL]], [[TMP6]] +// AVRFP32-NEXT: [[TMP13:%.*]] = fsub float [[A_IMAG]], [[TMP12]] +// AVRFP32-NEXT: [[TMP14:%.*]] = fdiv float [[TMP13]], [[TMP8]] +// AVRFP32-NEXT: br label [[COMPLEX_DIV:%.*]] +// AVRFP32: abs_rhsr_less_than_abs_rhsi: +// AVRFP32-NEXT: [[TMP15:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]] +// AVRFP32-NEXT: [[TMP16:%.*]] = fmul float [[TMP15]], [[B_REAL]] +// AVRFP32-NEXT: [[TMP17:%.*]] = fadd float [[B_IMAG]], [[TMP16]] +// AVRFP32-NEXT: [[TMP18:%.*]] = fmul float [[A_REAL]], [[TMP15]] +// AVRFP32-NEXT: [[TMP19:%.*]] = fadd float [[TMP18]], [[A_IMAG]] +// AVRFP32-NEXT: [[TMP20:%.*]] = fdiv float [[TMP19]], [[TMP17]] +// AVRFP32-NEXT: [[TMP21:%.*]] = fmul float [[A_IMAG]], [[TMP15]] +// AVRFP32-NEXT: [[TMP22:%.*]] = fsub float [[TMP21]], [[A_REAL]] +// AVRFP32-NEXT: [[TMP23:%.*]] = fdiv float [[TMP22]], [[TMP17]] +// AVRFP32-NEXT: br label [[COMPLEX_DIV]] +// AVRFP32: complex_div: +// AVRFP32-NEXT: [[TMP24:%.*]] = phi float [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP32-NEXT: [[TMP25:%.*]] = phi float [ [[TMP14]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP23]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// AVRFP32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[TMP24]], ptr [[RETVAL_REALP]], align 1 +// AVRFP32-NEXT: store float [[TMP25]], ptr [[RETVAL_IMAGP]], align 1 +// AVRFP32-NEXT: [[TMP26:%.*]] = load { float, float }, ptr [[RETVAL]], align 1 +// AVRFP32-NEXT: ret { float, float } [[TMP26]] +// +// AVRFP64-LABEL: define dso_local void @divd( +// AVRFP64-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 1 [[AGG_RESULT:%.*]], double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP64-NEXT: entry: +// AVRFP64-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// AVRFP64-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// AVRFP64-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// AVRFP64-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// AVRFP64-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// AVRFP64-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// AVRFP64-NEXT: [[TMP4:%.*]] = call addrspace(1) double @llvm.fabs.f64(double [[B_REAL]]) +// AVRFP64-NEXT: [[TMP5:%.*]] = call addrspace(1) double @llvm.fabs.f64(double [[B_IMAG]]) +// AVRFP64-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP4]], [[TMP5]] +// AVRFP64-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// AVRFP64: abs_rhsr_greater_or_equal_abs_rhsi: +// AVRFP64-NEXT: [[TMP6:%.*]] = fdiv double [[B_IMAG]], [[B_REAL]] +// AVRFP64-NEXT: [[TMP7:%.*]] = fmul double [[TMP6]], [[B_IMAG]] +// AVRFP64-NEXT: [[TMP8:%.*]] = fadd double [[B_REAL]], [[TMP7]] +// AVRFP64-NEXT: [[TMP9:%.*]] = fmul double [[A_IMAG]], [[TMP6]] +// AVRFP64-NEXT: [[TMP10:%.*]] = fadd double [[A_REAL]], [[TMP9]] +// AVRFP64-NEXT: [[TMP11:%.*]] = fdiv double [[TMP10]], [[TMP8]] +// AVRFP64-NEXT: [[TMP12:%.*]] = fmul double [[A_REAL]], [[TMP6]] +// AVRFP64-NEXT: [[TMP13:%.*]] = fsub double [[A_IMAG]], [[TMP12]] +// AVRFP64-NEXT: [[TMP14:%.*]] = fdiv double [[TMP13]], [[TMP8]] +// AVRFP64-NEXT: br label [[COMPLEX_DIV:%.*]] +// AVRFP64: abs_rhsr_less_than_abs_rhsi: +// AVRFP64-NEXT: [[TMP15:%.*]] = fdiv double [[B_REAL]], [[B_IMAG]] +// AVRFP64-NEXT: [[TMP16:%.*]] = fmul double [[TMP15]], [[B_REAL]] +// AVRFP64-NEXT: [[TMP17:%.*]] = fadd double [[B_IMAG]], [[TMP16]] +// AVRFP64-NEXT: [[TMP18:%.*]] = fmul double [[A_REAL]], [[TMP15]] +// AVRFP64-NEXT: [[TMP19:%.*]] = fadd double [[TMP18]], [[A_IMAG]] +// AVRFP64-NEXT: [[TMP20:%.*]] = fdiv double [[TMP19]], [[TMP17]] +// AVRFP64-NEXT: [[TMP21:%.*]] = fmul double [[A_IMAG]], [[TMP15]] +// AVRFP64-NEXT: [[TMP22:%.*]] = fsub double [[TMP21]], [[A_REAL]] +// AVRFP64-NEXT: [[TMP23:%.*]] = fdiv double [[TMP22]], [[TMP17]] +// AVRFP64-NEXT: br label [[COMPLEX_DIV]] +// AVRFP64: complex_div: +// AVRFP64-NEXT: [[TMP24:%.*]] = phi double [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP64-NEXT: [[TMP25:%.*]] = phi double [ [[TMP14]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP23]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP64-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[TMP24]], ptr [[AGG_RESULT_REALP]], align 1 +// AVRFP64-NEXT: store double [[TMP25]], ptr [[AGG_RESULT_IMAGP]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 1 +// AVRFP64-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 1 +// AVRFP64-NEXT: ret void +// +// BASIC_FAST-LABEL: define dso_local { double, double } @divd( +// BASIC_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] { +// BASIC_FAST-NEXT: entry: +// BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// BASIC_FAST-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// BASIC_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// BASIC_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// BASIC_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// BASIC_FAST-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// BASIC_FAST-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// BASIC_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[B_REAL]] +// BASIC_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[TMP4]], [[TMP5]] +// BASIC_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[B_REAL]], [[B_REAL]] +// BASIC_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[B_IMAG]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[TMP9:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[TMP7]], [[TMP8]] +// BASIC_FAST-NEXT: [[TMP10:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[B_REAL]] +// BASIC_FAST-NEXT: [[TMP11:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[TMP12:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[TMP10]], [[TMP11]] +// BASIC_FAST-NEXT: [[TMP13:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP6]], [[TMP9]] +// BASIC_FAST-NEXT: [[TMP14:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP12]], [[TMP9]] +// BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC_FAST-NEXT: store double [[TMP13]], ptr [[RETVAL_REALP]], align 8 +// BASIC_FAST-NEXT: store double [[TMP14]], ptr [[RETVAL_IMAGP]], align 8 +// BASIC_FAST-NEXT: [[TMP15:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// BASIC_FAST-NEXT: ret { double, double } [[TMP15]] +// +// FULL_FAST-LABEL: define dso_local { double, double } @divd( +// FULL_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] { +// FULL_FAST-NEXT: entry: +// FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// FULL_FAST-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// FULL_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// FULL_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// FULL_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// FULL_FAST-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// FULL_FAST-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// FULL_FAST-NEXT: [[CALL:%.*]] = call { double, double } @__divdc3(double noundef nofpclass(nan inf) [[A_REAL]], double noundef nofpclass(nan inf) [[A_IMAG]], double noundef nofpclass(nan inf) [[B_REAL]], double noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2]] +// FULL_FAST-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 0 +// FULL_FAST-NEXT: [[TMP5:%.*]] = extractvalue { double, double } [[CALL]], 1 +// FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// FULL_FAST-NEXT: store double [[TMP4]], ptr [[RETVAL_REALP]], align 8 +// FULL_FAST-NEXT: store double [[TMP5]], ptr [[RETVAL_IMAGP]], align 8 +// FULL_FAST-NEXT: [[TMP6:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// FULL_FAST-NEXT: ret { double, double } [[TMP6]] +// +// IMPRVD_FAST-LABEL: define dso_local { double, double } @divd( +// IMPRVD_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR2:[0-9]+]] { +// IMPRVD_FAST-NEXT: entry: +// IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// IMPRVD_FAST-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// IMPRVD_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// IMPRVD_FAST-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// IMPRVD_FAST-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// IMPRVD_FAST-NEXT: [[TMP4:%.*]] = call reassoc nnan ninf nsz arcp afn double @llvm.fabs.f64(double [[B_REAL]]) +// IMPRVD_FAST-NEXT: [[TMP5:%.*]] = call reassoc nnan ninf nsz arcp afn double @llvm.fabs.f64(double [[B_IMAG]]) +// IMPRVD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt double [[TMP4]], [[TMP5]] +// IMPRVD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP6:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[B_IMAG]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[TMP6]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP8:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[B_REAL]], [[TMP7]] +// IMPRVD_FAST-NEXT: [[TMP9:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[TMP6]] +// IMPRVD_FAST-NEXT: [[TMP10:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[TMP9]] +// IMPRVD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP10]], [[TMP8]] +// IMPRVD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[TMP6]] +// IMPRVD_FAST-NEXT: [[TMP13:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[TMP12]] +// IMPRVD_FAST-NEXT: [[TMP14:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP13]], [[TMP8]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP15:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[B_REAL]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP16:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[TMP15]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[TMP17:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[B_IMAG]], [[TMP16]] +// IMPRVD_FAST-NEXT: [[TMP18:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[TMP15]] +// IMPRVD_FAST-NEXT: [[TMP19:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[TMP18]], [[A_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP20:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP19]], [[TMP17]] +// IMPRVD_FAST-NEXT: [[TMP21:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[TMP15]] +// IMPRVD_FAST-NEXT: [[TMP22:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[TMP21]], [[A_REAL]] +// IMPRVD_FAST-NEXT: [[TMP23:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP22]], [[TMP17]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD_FAST: complex_div: +// IMPRVD_FAST-NEXT: [[TMP24:%.*]] = phi reassoc nnan ninf nsz arcp afn double [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[TMP25:%.*]] = phi reassoc nnan ninf nsz arcp afn double [ [[TMP14]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP23]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store double [[TMP24]], ptr [[RETVAL_REALP]], align 8 +// IMPRVD_FAST-NEXT: store double [[TMP25]], ptr [[RETVAL_IMAGP]], align 8 +// IMPRVD_FAST-NEXT: [[TMP26:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// IMPRVD_FAST-NEXT: ret { double, double } [[TMP26]] +// +// PRMTD_FAST-LABEL: define dso_local { double, double } @divd( +// PRMTD_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] { +// PRMTD_FAST-NEXT: entry: +// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// PRMTD_FAST-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// PRMTD_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// PRMTD_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// PRMTD_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// PRMTD_FAST-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// PRMTD_FAST-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// PRMTD_FAST-NEXT: [[EXT:%.*]] = fpext double [[A_REAL]] to x86_fp80 +// PRMTD_FAST-NEXT: [[EXT1:%.*]] = fpext double [[A_IMAG]] to x86_fp80 +// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// PRMTD_FAST-NEXT: [[EXT2:%.*]] = fpext double [[B_REAL]] to x86_fp80 +// PRMTD_FAST-NEXT: [[EXT3:%.*]] = fpext double [[B_IMAG]] to x86_fp80 +// PRMTD_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[EXT]], [[EXT2]] +// PRMTD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[EXT1]], [[EXT3]] +// PRMTD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP4]], [[TMP5]] +// PRMTD_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[EXT2]], [[EXT2]] +// PRMTD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[EXT3]], [[EXT3]] +// PRMTD_FAST-NEXT: [[TMP9:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP7]], [[TMP8]] +// PRMTD_FAST-NEXT: [[TMP10:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[EXT1]], [[EXT2]] +// PRMTD_FAST-NEXT: [[TMP11:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[EXT]], [[EXT3]] +// PRMTD_FAST-NEXT: [[TMP12:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP10]], [[TMP11]] +// PRMTD_FAST-NEXT: [[TMP13:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP9]] +// PRMTD_FAST-NEXT: [[TMP14:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP12]], [[TMP9]] +// PRMTD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc x86_fp80 [[TMP13]] to double +// PRMTD_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc x86_fp80 [[TMP14]] to double +// PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store double [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 8 +// PRMTD_FAST-NEXT: store double [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 8 +// PRMTD_FAST-NEXT: [[TMP15:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// PRMTD_FAST-NEXT: ret { double, double } [[TMP15]] +// +_Complex double divd(_Complex double a, _Complex double b) { return a / b; } -_Complex float mul(_Complex float a, _Complex float b) { - // LABEL: define {{.*}} @mul( - // FULL: call {{.*}} @__mulsc3 - - // LMTD: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fsub float - // LMTD-NEXT: fadd float - - // FRTRN: fmul {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fmul {{.*}}float - // FRTRN-NEXT: fsub {{.*}}float - // FRTRN-NEXT: fadd {{.*}}float - - // LMTD-FAST: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fmul {{.*}} float - // LMTD-FAST-NEXT: fsub {{.*}} float - // LMTD-FAST-NEXT: fadd {{.*}} float +// FULL-LABEL: define dso_local { double, double } @muld( +// FULL-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] { +// FULL-NEXT: entry: +// FULL-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// FULL-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// FULL-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// FULL-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// FULL-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// FULL-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// FULL-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// FULL-NEXT: [[MUL_AC:%.*]] = fmul double [[A_REAL]], [[B_REAL]] +// FULL-NEXT: [[MUL_BD:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]] +// FULL-NEXT: [[MUL_AD:%.*]] = fmul double [[A_REAL]], [[B_IMAG]] +// FULL-NEXT: [[MUL_BC:%.*]] = fmul double [[A_IMAG]], [[B_REAL]] +// FULL-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]] +// FULL-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]] +// FULL-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno double [[MUL_R]], [[MUL_R]] +// FULL-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]] +// FULL: complex_mul_imag_nan: +// FULL-NEXT: [[ISNAN_CMP1:%.*]] = fcmp uno double [[MUL_I]], [[MUL_I]] +// FULL-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]] +// FULL: complex_mul_libcall: +// FULL-NEXT: [[CALL:%.*]] = call { double, double } @__muldc3(double noundef [[A_REAL]], double noundef [[A_IMAG]], double noundef [[B_REAL]], double noundef [[B_IMAG]]) #[[ATTR2]] +// FULL-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 0 +// FULL-NEXT: [[TMP5:%.*]] = extractvalue { double, double } [[CALL]], 1 +// FULL-NEXT: br label [[COMPLEX_MUL_CONT]] +// FULL: complex_mul_cont: +// FULL-NEXT: [[REAL_MUL_PHI:%.*]] = phi double [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP4]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL-NEXT: [[IMAG_MUL_PHI:%.*]] = phi double [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP5]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// FULL-NEXT: store double [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 8 +// FULL-NEXT: store double [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 8 +// FULL-NEXT: [[TMP6:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// FULL-NEXT: ret { double, double } [[TMP6]] +// +// BASIC-LABEL: define dso_local { double, double } @muld( +// BASIC-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] { +// BASIC-NEXT: entry: +// BASIC-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// BASIC-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// BASIC-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// BASIC-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// BASIC-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// BASIC-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// BASIC-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// BASIC-NEXT: [[MUL_AC:%.*]] = fmul double [[A_REAL]], [[B_REAL]] +// BASIC-NEXT: [[MUL_BD:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]] +// BASIC-NEXT: [[MUL_AD:%.*]] = fmul double [[A_REAL]], [[B_IMAG]] +// BASIC-NEXT: [[MUL_BC:%.*]] = fmul double [[A_IMAG]], [[B_REAL]] +// BASIC-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]] +// BASIC-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]] +// BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC-NEXT: store double [[MUL_R]], ptr [[RETVAL_REALP]], align 8 +// BASIC-NEXT: store double [[MUL_I]], ptr [[RETVAL_IMAGP]], align 8 +// BASIC-NEXT: [[TMP4:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// BASIC-NEXT: ret { double, double } [[TMP4]] +// +// IMPRVD-LABEL: define dso_local { double, double } @muld( +// IMPRVD-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR2]] { +// IMPRVD-NEXT: entry: +// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// IMPRVD-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// IMPRVD-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// IMPRVD-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// IMPRVD-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// IMPRVD-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// IMPRVD-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// IMPRVD-NEXT: [[MUL_AC:%.*]] = fmul double [[A_REAL]], [[B_REAL]] +// IMPRVD-NEXT: [[MUL_BD:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]] +// IMPRVD-NEXT: [[MUL_AD:%.*]] = fmul double [[A_REAL]], [[B_IMAG]] +// IMPRVD-NEXT: [[MUL_BC:%.*]] = fmul double [[A_IMAG]], [[B_REAL]] +// IMPRVD-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]] +// IMPRVD-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]] +// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD-NEXT: store double [[MUL_R]], ptr [[RETVAL_REALP]], align 8 +// IMPRVD-NEXT: store double [[MUL_I]], ptr [[RETVAL_IMAGP]], align 8 +// IMPRVD-NEXT: [[TMP4:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// IMPRVD-NEXT: ret { double, double } [[TMP4]] +// +// PRMTD-LABEL: define dso_local { double, double } @muld( +// PRMTD-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] { +// PRMTD-NEXT: entry: +// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// PRMTD-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// PRMTD-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// PRMTD-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// PRMTD-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// PRMTD-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// PRMTD-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// PRMTD-NEXT: [[MUL_AC:%.*]] = fmul double [[A_REAL]], [[B_REAL]] +// PRMTD-NEXT: [[MUL_BD:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]] +// PRMTD-NEXT: [[MUL_AD:%.*]] = fmul double [[A_REAL]], [[B_IMAG]] +// PRMTD-NEXT: [[MUL_BC:%.*]] = fmul double [[A_IMAG]], [[B_REAL]] +// PRMTD-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]] +// PRMTD-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]] +// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD-NEXT: store double [[MUL_R]], ptr [[RETVAL_REALP]], align 8 +// PRMTD-NEXT: store double [[MUL_I]], ptr [[RETVAL_IMAGP]], align 8 +// PRMTD-NEXT: [[TMP4:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// PRMTD-NEXT: ret { double, double } [[TMP4]] +// +// X86WINPRMTD-LABEL: define dso_local void @muld( +// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] { +// X86WINPRMTD-NEXT: entry: +// X86WINPRMTD-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: [[A_INDIRECT_ADDR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: store ptr [[AGG_RESULT]], ptr [[RESULT_PTR]], align 8 +// X86WINPRMTD-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8 +// X86WINPRMTD-NEXT: store ptr [[A]], ptr [[A_INDIRECT_ADDR]], align 8 +// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[MUL_AC:%.*]] = fmul double [[A_REAL]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[MUL_BD:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[MUL_AD:%.*]] = fmul double [[A_REAL]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[MUL_BC:%.*]] = fmul double [[A_IMAG]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]] +// X86WINPRMTD-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]] +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store double [[MUL_R]], ptr [[AGG_RESULT_REALP]], align 8 +// X86WINPRMTD-NEXT: store double [[MUL_I]], ptr [[AGG_RESULT_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8 +// X86WINPRMTD-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8 +// X86WINPRMTD-NEXT: ret void +// +// AVRFP32-LABEL: define dso_local { float, float } @muld( +// AVRFP32-SAME: float noundef [[A_COERCE0:%.*]], float noundef [[A_COERCE1:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP32-NEXT: entry: +// AVRFP32-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[A_COERCE0]], ptr [[TMP0]], align 4 +// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[A_COERCE1]], ptr [[TMP1]], align 4 +// AVRFP32-NEXT: [[TMP2:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP2]], align 4 +// AVRFP32-NEXT: [[TMP3:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP3]], align 4 +// AVRFP32-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// AVRFP32-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// AVRFP32-NEXT: [[MUL_AC:%.*]] = fmul float [[A_REAL]], [[B_REAL]] +// AVRFP32-NEXT: [[MUL_BD:%.*]] = fmul float [[A_IMAG]], [[B_IMAG]] +// AVRFP32-NEXT: [[MUL_AD:%.*]] = fmul float [[A_REAL]], [[B_IMAG]] +// AVRFP32-NEXT: [[MUL_BC:%.*]] = fmul float [[A_IMAG]], [[B_REAL]] +// AVRFP32-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// AVRFP32-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// AVRFP32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// AVRFP32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[MUL_R]], ptr [[RETVAL_REALP]], align 1 +// AVRFP32-NEXT: store float [[MUL_I]], ptr [[RETVAL_IMAGP]], align 1 +// AVRFP32-NEXT: [[TMP4:%.*]] = load { float, float }, ptr [[RETVAL]], align 1 +// AVRFP32-NEXT: ret { float, float } [[TMP4]] +// +// AVRFP64-LABEL: define dso_local void @muld( +// AVRFP64-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 1 [[AGG_RESULT:%.*]], double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP64-NEXT: entry: +// AVRFP64-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// AVRFP64-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// AVRFP64-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// AVRFP64-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// AVRFP64-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// AVRFP64-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// AVRFP64-NEXT: [[MUL_AC:%.*]] = fmul double [[A_REAL]], [[B_REAL]] +// AVRFP64-NEXT: [[MUL_BD:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]] +// AVRFP64-NEXT: [[MUL_AD:%.*]] = fmul double [[A_REAL]], [[B_IMAG]] +// AVRFP64-NEXT: [[MUL_BC:%.*]] = fmul double [[A_IMAG]], [[B_REAL]] +// AVRFP64-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]] +// AVRFP64-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]] +// AVRFP64-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[MUL_R]], ptr [[AGG_RESULT_REALP]], align 1 +// AVRFP64-NEXT: store double [[MUL_I]], ptr [[AGG_RESULT_IMAGP]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 1 +// AVRFP64-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 1 +// AVRFP64-NEXT: ret void +// +// BASIC_FAST-LABEL: define dso_local { double, double } @muld( +// BASIC_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1]] { +// BASIC_FAST-NEXT: entry: +// BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// BASIC_FAST-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// BASIC_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// BASIC_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// BASIC_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// BASIC_FAST-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// BASIC_FAST-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// BASIC_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[B_REAL]] +// BASIC_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[B_REAL]] +// BASIC_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[MUL_AC]], [[MUL_BD]] +// BASIC_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[MUL_AD]], [[MUL_BC]] +// BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC_FAST-NEXT: store double [[MUL_R]], ptr [[RETVAL_REALP]], align 8 +// BASIC_FAST-NEXT: store double [[MUL_I]], ptr [[RETVAL_IMAGP]], align 8 +// BASIC_FAST-NEXT: [[TMP4:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// BASIC_FAST-NEXT: ret { double, double } [[TMP4]] +// +// FULL_FAST-LABEL: define dso_local { double, double } @muld( +// FULL_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1]] { +// FULL_FAST-NEXT: entry: +// FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// FULL_FAST-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// FULL_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// FULL_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// FULL_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// FULL_FAST-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// FULL_FAST-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// FULL_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[B_REAL]] +// FULL_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[B_IMAG]] +// FULL_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[B_IMAG]] +// FULL_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[B_REAL]] +// FULL_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[MUL_AC]], [[MUL_BD]] +// FULL_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[MUL_AD]], [[MUL_BC]] +// FULL_FAST-NEXT: [[ISNAN_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno double [[MUL_R]], [[MUL_R]] +// FULL_FAST-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]] +// FULL_FAST: complex_mul_imag_nan: +// FULL_FAST-NEXT: [[ISNAN_CMP1:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno double [[MUL_I]], [[MUL_I]] +// FULL_FAST-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]] +// FULL_FAST: complex_mul_libcall: +// FULL_FAST-NEXT: [[CALL:%.*]] = call { double, double } @__muldc3(double noundef nofpclass(nan inf) [[A_REAL]], double noundef nofpclass(nan inf) [[A_IMAG]], double noundef nofpclass(nan inf) [[B_REAL]], double noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2]] +// FULL_FAST-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 0 +// FULL_FAST-NEXT: [[TMP5:%.*]] = extractvalue { double, double } [[CALL]], 1 +// FULL_FAST-NEXT: br label [[COMPLEX_MUL_CONT]] +// FULL_FAST: complex_mul_cont: +// FULL_FAST-NEXT: [[REAL_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn double [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP4]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL_FAST-NEXT: [[IMAG_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn double [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP5]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// FULL_FAST-NEXT: store double [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 8 +// FULL_FAST-NEXT: store double [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 8 +// FULL_FAST-NEXT: [[TMP6:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// FULL_FAST-NEXT: ret { double, double } [[TMP6]] +// +// IMPRVD_FAST-LABEL: define dso_local { double, double } @muld( +// IMPRVD_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR2]] { +// IMPRVD_FAST-NEXT: entry: +// IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// IMPRVD_FAST-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// IMPRVD_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// IMPRVD_FAST-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// IMPRVD_FAST-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// IMPRVD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[MUL_AC]], [[MUL_BD]] +// IMPRVD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[MUL_AD]], [[MUL_BC]] +// IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store double [[MUL_R]], ptr [[RETVAL_REALP]], align 8 +// IMPRVD_FAST-NEXT: store double [[MUL_I]], ptr [[RETVAL_IMAGP]], align 8 +// IMPRVD_FAST-NEXT: [[TMP4:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// IMPRVD_FAST-NEXT: ret { double, double } [[TMP4]] +// +// PRMTD_FAST-LABEL: define dso_local { double, double } @muld( +// PRMTD_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1]] { +// PRMTD_FAST-NEXT: entry: +// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8 +// PRMTD_FAST-NEXT: [[A:%.*]] = alloca { double, double }, align 8 +// PRMTD_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8 +// PRMTD_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8 +// PRMTD_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8 +// PRMTD_FAST-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8 +// PRMTD_FAST-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8 +// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// PRMTD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[B_REAL]] +// PRMTD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[B_IMAG]] +// PRMTD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_REAL]], [[B_IMAG]] +// PRMTD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[A_IMAG]], [[B_REAL]] +// PRMTD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[MUL_AC]], [[MUL_BD]] +// PRMTD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[MUL_AD]], [[MUL_BC]] +// PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store double [[MUL_R]], ptr [[RETVAL_REALP]], align 8 +// PRMTD_FAST-NEXT: store double [[MUL_I]], ptr [[RETVAL_IMAGP]], align 8 +// PRMTD_FAST-NEXT: [[TMP4:%.*]] = load { double, double }, ptr [[RETVAL]], align 8 +// PRMTD_FAST-NEXT: ret { double, double } [[TMP4]] +// +_Complex double muld(_Complex double a, _Complex double b) { + return a * b; +} + +// FULL-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld( +// FULL-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// FULL-NEXT: entry: +// FULL-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// FULL-NEXT: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__divxc3(x86_fp80 noundef [[A_REAL]], x86_fp80 noundef [[A_IMAG]], x86_fp80 noundef [[B_REAL]], x86_fp80 noundef [[B_IMAG]]) #[[ATTR2]] +// FULL-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0 +// FULL-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1 +// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// FULL-NEXT: store x86_fp80 [[TMP0]], ptr [[RETVAL_REALP]], align 16 +// FULL-NEXT: store x86_fp80 [[TMP1]], ptr [[RETVAL_IMAGP]], align 16 +// FULL-NEXT: [[TMP2:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// FULL-NEXT: ret { x86_fp80, x86_fp80 } [[TMP2]] +// +// BASIC-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld( +// BASIC-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// BASIC-NEXT: entry: +// BASIC-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// BASIC-NEXT: [[TMP0:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_REAL]] +// BASIC-NEXT: [[TMP1:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_IMAG]] +// BASIC-NEXT: [[TMP2:%.*]] = fadd x86_fp80 [[TMP0]], [[TMP1]] +// BASIC-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[B_REAL]], [[B_REAL]] +// BASIC-NEXT: [[TMP4:%.*]] = fmul x86_fp80 [[B_IMAG]], [[B_IMAG]] +// BASIC-NEXT: [[TMP5:%.*]] = fadd x86_fp80 [[TMP3]], [[TMP4]] +// BASIC-NEXT: [[TMP6:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_REAL]] +// BASIC-NEXT: [[TMP7:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_IMAG]] +// BASIC-NEXT: [[TMP8:%.*]] = fsub x86_fp80 [[TMP6]], [[TMP7]] +// BASIC-NEXT: [[TMP9:%.*]] = fdiv x86_fp80 [[TMP2]], [[TMP5]] +// BASIC-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP8]], [[TMP5]] +// BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC-NEXT: store x86_fp80 [[TMP9]], ptr [[RETVAL_REALP]], align 16 +// BASIC-NEXT: store x86_fp80 [[TMP10]], ptr [[RETVAL_IMAGP]], align 16 +// BASIC-NEXT: [[TMP11:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// BASIC-NEXT: ret { x86_fp80, x86_fp80 } [[TMP11]] +// +// IMPRVD-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld( +// IMPRVD-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] { +// IMPRVD-NEXT: entry: +// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// IMPRVD-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]]) +// IMPRVD-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]]) +// IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt x86_fp80 [[TMP0]], [[TMP1]] +// IMPRVD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[B_IMAG]], [[B_REAL]] +// IMPRVD-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[TMP2]], [[B_IMAG]] +// IMPRVD-NEXT: [[TMP4:%.*]] = fadd x86_fp80 [[B_REAL]], [[TMP3]] +// IMPRVD-NEXT: [[TMP5:%.*]] = fmul x86_fp80 [[A_IMAG]], [[TMP2]] +// IMPRVD-NEXT: [[TMP6:%.*]] = fadd x86_fp80 [[A_REAL]], [[TMP5]] +// IMPRVD-NEXT: [[TMP7:%.*]] = fdiv x86_fp80 [[TMP6]], [[TMP4]] +// IMPRVD-NEXT: [[TMP8:%.*]] = fmul x86_fp80 [[A_REAL]], [[TMP2]] +// IMPRVD-NEXT: [[TMP9:%.*]] = fsub x86_fp80 [[A_IMAG]], [[TMP8]] +// IMPRVD-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP9]], [[TMP4]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD: abs_rhsr_less_than_abs_rhsi: +// IMPRVD-NEXT: [[TMP11:%.*]] = fdiv x86_fp80 [[B_REAL]], [[B_IMAG]] +// IMPRVD-NEXT: [[TMP12:%.*]] = fmul x86_fp80 [[TMP11]], [[B_REAL]] +// IMPRVD-NEXT: [[TMP13:%.*]] = fadd x86_fp80 [[B_IMAG]], [[TMP12]] +// IMPRVD-NEXT: [[TMP14:%.*]] = fmul x86_fp80 [[A_REAL]], [[TMP11]] +// IMPRVD-NEXT: [[TMP15:%.*]] = fadd x86_fp80 [[TMP14]], [[A_IMAG]] +// IMPRVD-NEXT: [[TMP16:%.*]] = fdiv x86_fp80 [[TMP15]], [[TMP13]] +// IMPRVD-NEXT: [[TMP17:%.*]] = fmul x86_fp80 [[A_IMAG]], [[TMP11]] +// IMPRVD-NEXT: [[TMP18:%.*]] = fsub x86_fp80 [[TMP17]], [[A_REAL]] +// IMPRVD-NEXT: [[TMP19:%.*]] = fdiv x86_fp80 [[TMP18]], [[TMP13]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD: complex_div: +// IMPRVD-NEXT: [[TMP20:%.*]] = phi x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD-NEXT: store x86_fp80 [[TMP20]], ptr [[RETVAL_REALP]], align 16 +// IMPRVD-NEXT: store x86_fp80 [[TMP21]], ptr [[RETVAL_IMAGP]], align 16 +// IMPRVD-NEXT: [[TMP22:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// IMPRVD-NEXT: ret { x86_fp80, x86_fp80 } [[TMP22]] +// +// PRMTD-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld( +// PRMTD-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// PRMTD-NEXT: entry: +// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// PRMTD-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]]) +// PRMTD-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]]) +// PRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt x86_fp80 [[TMP0]], [[TMP1]] +// PRMTD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// PRMTD: abs_rhsr_greater_or_equal_abs_rhsi: +// PRMTD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[B_IMAG]], [[B_REAL]] +// PRMTD-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[TMP2]], [[B_IMAG]] +// PRMTD-NEXT: [[TMP4:%.*]] = fadd x86_fp80 [[B_REAL]], [[TMP3]] +// PRMTD-NEXT: [[TMP5:%.*]] = fmul x86_fp80 [[A_IMAG]], [[TMP2]] +// PRMTD-NEXT: [[TMP6:%.*]] = fadd x86_fp80 [[A_REAL]], [[TMP5]] +// PRMTD-NEXT: [[TMP7:%.*]] = fdiv x86_fp80 [[TMP6]], [[TMP4]] +// PRMTD-NEXT: [[TMP8:%.*]] = fmul x86_fp80 [[A_REAL]], [[TMP2]] +// PRMTD-NEXT: [[TMP9:%.*]] = fsub x86_fp80 [[A_IMAG]], [[TMP8]] +// PRMTD-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP9]], [[TMP4]] +// PRMTD-NEXT: br label [[COMPLEX_DIV:%.*]] +// PRMTD: abs_rhsr_less_than_abs_rhsi: +// PRMTD-NEXT: [[TMP11:%.*]] = fdiv x86_fp80 [[B_REAL]], [[B_IMAG]] +// PRMTD-NEXT: [[TMP12:%.*]] = fmul x86_fp80 [[TMP11]], [[B_REAL]] +// PRMTD-NEXT: [[TMP13:%.*]] = fadd x86_fp80 [[B_IMAG]], [[TMP12]] +// PRMTD-NEXT: [[TMP14:%.*]] = fmul x86_fp80 [[A_REAL]], [[TMP11]] +// PRMTD-NEXT: [[TMP15:%.*]] = fadd x86_fp80 [[TMP14]], [[A_IMAG]] +// PRMTD-NEXT: [[TMP16:%.*]] = fdiv x86_fp80 [[TMP15]], [[TMP13]] +// PRMTD-NEXT: [[TMP17:%.*]] = fmul x86_fp80 [[A_IMAG]], [[TMP11]] +// PRMTD-NEXT: [[TMP18:%.*]] = fsub x86_fp80 [[TMP17]], [[A_REAL]] +// PRMTD-NEXT: [[TMP19:%.*]] = fdiv x86_fp80 [[TMP18]], [[TMP13]] +// PRMTD-NEXT: br label [[COMPLEX_DIV]] +// PRMTD: complex_div: +// PRMTD-NEXT: [[TMP20:%.*]] = phi x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD-NEXT: store x86_fp80 [[TMP20]], ptr [[RETVAL_REALP]], align 16 +// PRMTD-NEXT: store x86_fp80 [[TMP21]], ptr [[RETVAL_IMAGP]], align 16 +// PRMTD-NEXT: [[TMP22:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// PRMTD-NEXT: ret { x86_fp80, x86_fp80 } [[TMP22]] +// +// X86WINPRMTD-LABEL: define dso_local void @divld( +// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] { +// X86WINPRMTD-NEXT: entry: +// X86WINPRMTD-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: [[A_INDIRECT_ADDR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: store ptr [[AGG_RESULT]], ptr [[RESULT_PTR]], align 8 +// X86WINPRMTD-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8 +// X86WINPRMTD-NEXT: store ptr [[A]], ptr [[A_INDIRECT_ADDR]], align 8 +// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[TMP0:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]]) +// X86WINPRMTD-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]]) +// X86WINPRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP0]], [[TMP1]] +// X86WINPRMTD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// X86WINPRMTD: abs_rhsr_greater_or_equal_abs_rhsi: +// X86WINPRMTD-NEXT: [[TMP2:%.*]] = fdiv double [[B_IMAG]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[TMP3:%.*]] = fmul double [[TMP2]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[TMP4:%.*]] = fadd double [[B_REAL]], [[TMP3]] +// X86WINPRMTD-NEXT: [[TMP5:%.*]] = fmul double [[A_IMAG]], [[TMP2]] +// X86WINPRMTD-NEXT: [[TMP6:%.*]] = fadd double [[A_REAL]], [[TMP5]] +// X86WINPRMTD-NEXT: [[TMP7:%.*]] = fdiv double [[TMP6]], [[TMP4]] +// X86WINPRMTD-NEXT: [[TMP8:%.*]] = fmul double [[A_REAL]], [[TMP2]] +// X86WINPRMTD-NEXT: [[TMP9:%.*]] = fsub double [[A_IMAG]], [[TMP8]] +// X86WINPRMTD-NEXT: [[TMP10:%.*]] = fdiv double [[TMP9]], [[TMP4]] +// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV:%.*]] +// X86WINPRMTD: abs_rhsr_less_than_abs_rhsi: +// X86WINPRMTD-NEXT: [[TMP11:%.*]] = fdiv double [[B_REAL]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[TMP12:%.*]] = fmul double [[TMP11]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[TMP13:%.*]] = fadd double [[B_IMAG]], [[TMP12]] +// X86WINPRMTD-NEXT: [[TMP14:%.*]] = fmul double [[A_REAL]], [[TMP11]] +// X86WINPRMTD-NEXT: [[TMP15:%.*]] = fadd double [[TMP14]], [[A_IMAG]] +// X86WINPRMTD-NEXT: [[TMP16:%.*]] = fdiv double [[TMP15]], [[TMP13]] +// X86WINPRMTD-NEXT: [[TMP17:%.*]] = fmul double [[A_IMAG]], [[TMP11]] +// X86WINPRMTD-NEXT: [[TMP18:%.*]] = fsub double [[TMP17]], [[A_REAL]] +// X86WINPRMTD-NEXT: [[TMP19:%.*]] = fdiv double [[TMP18]], [[TMP13]] +// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV]] +// X86WINPRMTD: complex_div: +// X86WINPRMTD-NEXT: [[TMP20:%.*]] = phi double [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// X86WINPRMTD-NEXT: [[TMP21:%.*]] = phi double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store double [[TMP20]], ptr [[AGG_RESULT_REALP]], align 8 +// X86WINPRMTD-NEXT: store double [[TMP21]], ptr [[AGG_RESULT_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8 +// X86WINPRMTD-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8 +// X86WINPRMTD-NEXT: ret void +// +// AVRFP32-LABEL: define dso_local { float, float } @divld( +// AVRFP32-SAME: float noundef [[A_COERCE0:%.*]], float noundef [[A_COERCE1:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP32-NEXT: entry: +// AVRFP32-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[A:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[A_COERCE0]], ptr [[TMP0]], align 1 +// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[A_COERCE1]], ptr [[TMP1]], align 1 +// AVRFP32-NEXT: [[TMP2:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP2]], align 1 +// AVRFP32-NEXT: [[TMP3:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP3]], align 1 +// AVRFP32-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 1 +// AVRFP32-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 1 +// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1 +// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1 +// AVRFP32-NEXT: [[TMP4:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_REAL]]) +// AVRFP32-NEXT: [[TMP5:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_IMAG]]) +// AVRFP32-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP4]], [[TMP5]] +// AVRFP32-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// AVRFP32: abs_rhsr_greater_or_equal_abs_rhsi: +// AVRFP32-NEXT: [[TMP6:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]] +// AVRFP32-NEXT: [[TMP7:%.*]] = fmul float [[TMP6]], [[B_IMAG]] +// AVRFP32-NEXT: [[TMP8:%.*]] = fadd float [[B_REAL]], [[TMP7]] +// AVRFP32-NEXT: [[TMP9:%.*]] = fmul float [[A_IMAG]], [[TMP6]] +// AVRFP32-NEXT: [[TMP10:%.*]] = fadd float [[A_REAL]], [[TMP9]] +// AVRFP32-NEXT: [[TMP11:%.*]] = fdiv float [[TMP10]], [[TMP8]] +// AVRFP32-NEXT: [[TMP12:%.*]] = fmul float [[A_REAL]], [[TMP6]] +// AVRFP32-NEXT: [[TMP13:%.*]] = fsub float [[A_IMAG]], [[TMP12]] +// AVRFP32-NEXT: [[TMP14:%.*]] = fdiv float [[TMP13]], [[TMP8]] +// AVRFP32-NEXT: br label [[COMPLEX_DIV:%.*]] +// AVRFP32: abs_rhsr_less_than_abs_rhsi: +// AVRFP32-NEXT: [[TMP15:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]] +// AVRFP32-NEXT: [[TMP16:%.*]] = fmul float [[TMP15]], [[B_REAL]] +// AVRFP32-NEXT: [[TMP17:%.*]] = fadd float [[B_IMAG]], [[TMP16]] +// AVRFP32-NEXT: [[TMP18:%.*]] = fmul float [[A_REAL]], [[TMP15]] +// AVRFP32-NEXT: [[TMP19:%.*]] = fadd float [[TMP18]], [[A_IMAG]] +// AVRFP32-NEXT: [[TMP20:%.*]] = fdiv float [[TMP19]], [[TMP17]] +// AVRFP32-NEXT: [[TMP21:%.*]] = fmul float [[A_IMAG]], [[TMP15]] +// AVRFP32-NEXT: [[TMP22:%.*]] = fsub float [[TMP21]], [[A_REAL]] +// AVRFP32-NEXT: [[TMP23:%.*]] = fdiv float [[TMP22]], [[TMP17]] +// AVRFP32-NEXT: br label [[COMPLEX_DIV]] +// AVRFP32: complex_div: +// AVRFP32-NEXT: [[TMP24:%.*]] = phi float [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP32-NEXT: [[TMP25:%.*]] = phi float [ [[TMP14]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP23]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// AVRFP32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[TMP24]], ptr [[RETVAL_REALP]], align 1 +// AVRFP32-NEXT: store float [[TMP25]], ptr [[RETVAL_IMAGP]], align 1 +// AVRFP32-NEXT: [[TMP26:%.*]] = load { float, float }, ptr [[RETVAL]], align 1 +// AVRFP32-NEXT: ret { float, float } [[TMP26]] +// +// AVRFP64-LABEL: define dso_local void @divld( +// AVRFP64-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 1 [[AGG_RESULT:%.*]], double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP64-NEXT: entry: +// AVRFP64-NEXT: [[A:%.*]] = alloca { double, double }, align 1 +// AVRFP64-NEXT: [[B:%.*]] = alloca { double, double }, align 1 +// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 1 +// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 1 +// AVRFP64-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 1 +// AVRFP64-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 1 +// AVRFP64-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 1 +// AVRFP64-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 1 +// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 1 +// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 1 +// AVRFP64-NEXT: [[TMP4:%.*]] = call addrspace(1) double @llvm.fabs.f64(double [[B_REAL]]) +// AVRFP64-NEXT: [[TMP5:%.*]] = call addrspace(1) double @llvm.fabs.f64(double [[B_IMAG]]) +// AVRFP64-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP4]], [[TMP5]] +// AVRFP64-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// AVRFP64: abs_rhsr_greater_or_equal_abs_rhsi: +// AVRFP64-NEXT: [[TMP6:%.*]] = fdiv double [[B_IMAG]], [[B_REAL]] +// AVRFP64-NEXT: [[TMP7:%.*]] = fmul double [[TMP6]], [[B_IMAG]] +// AVRFP64-NEXT: [[TMP8:%.*]] = fadd double [[B_REAL]], [[TMP7]] +// AVRFP64-NEXT: [[TMP9:%.*]] = fmul double [[A_IMAG]], [[TMP6]] +// AVRFP64-NEXT: [[TMP10:%.*]] = fadd double [[A_REAL]], [[TMP9]] +// AVRFP64-NEXT: [[TMP11:%.*]] = fdiv double [[TMP10]], [[TMP8]] +// AVRFP64-NEXT: [[TMP12:%.*]] = fmul double [[A_REAL]], [[TMP6]] +// AVRFP64-NEXT: [[TMP13:%.*]] = fsub double [[A_IMAG]], [[TMP12]] +// AVRFP64-NEXT: [[TMP14:%.*]] = fdiv double [[TMP13]], [[TMP8]] +// AVRFP64-NEXT: br label [[COMPLEX_DIV:%.*]] +// AVRFP64: abs_rhsr_less_than_abs_rhsi: +// AVRFP64-NEXT: [[TMP15:%.*]] = fdiv double [[B_REAL]], [[B_IMAG]] +// AVRFP64-NEXT: [[TMP16:%.*]] = fmul double [[TMP15]], [[B_REAL]] +// AVRFP64-NEXT: [[TMP17:%.*]] = fadd double [[B_IMAG]], [[TMP16]] +// AVRFP64-NEXT: [[TMP18:%.*]] = fmul double [[A_REAL]], [[TMP15]] +// AVRFP64-NEXT: [[TMP19:%.*]] = fadd double [[TMP18]], [[A_IMAG]] +// AVRFP64-NEXT: [[TMP20:%.*]] = fdiv double [[TMP19]], [[TMP17]] +// AVRFP64-NEXT: [[TMP21:%.*]] = fmul double [[A_IMAG]], [[TMP15]] +// AVRFP64-NEXT: [[TMP22:%.*]] = fsub double [[TMP21]], [[A_REAL]] +// AVRFP64-NEXT: [[TMP23:%.*]] = fdiv double [[TMP22]], [[TMP17]] +// AVRFP64-NEXT: br label [[COMPLEX_DIV]] +// AVRFP64: complex_div: +// AVRFP64-NEXT: [[TMP24:%.*]] = phi double [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP64-NEXT: [[TMP25:%.*]] = phi double [ [[TMP14]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP23]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP64-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[TMP24]], ptr [[AGG_RESULT_REALP]], align 1 +// AVRFP64-NEXT: store double [[TMP25]], ptr [[AGG_RESULT_IMAGP]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 1 +// AVRFP64-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 1 +// AVRFP64-NEXT: ret void +// +// BASIC_FAST-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld( +// BASIC_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// BASIC_FAST-NEXT: entry: +// BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// BASIC_FAST-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[B_REAL]] +// BASIC_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[TMP2:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP0]], [[TMP1]] +// BASIC_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[B_REAL]] +// BASIC_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP3]], [[TMP4]] +// BASIC_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[B_REAL]] +// BASIC_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[TMP8:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP7]] +// BASIC_FAST-NEXT: [[TMP9:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[TMP5]] +// BASIC_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP8]], [[TMP5]] +// BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC_FAST-NEXT: store x86_fp80 [[TMP9]], ptr [[RETVAL_REALP]], align 16 +// BASIC_FAST-NEXT: store x86_fp80 [[TMP10]], ptr [[RETVAL_IMAGP]], align 16 +// BASIC_FAST-NEXT: [[TMP11:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// BASIC_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP11]] +// +// FULL_FAST-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld( +// FULL_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// FULL_FAST-NEXT: entry: +// FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// FULL_FAST-NEXT: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__divxc3(x86_fp80 noundef nofpclass(nan inf) [[A_REAL]], x86_fp80 noundef nofpclass(nan inf) [[A_IMAG]], x86_fp80 noundef nofpclass(nan inf) [[B_REAL]], x86_fp80 noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2]] +// FULL_FAST-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0 +// FULL_FAST-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1 +// FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// FULL_FAST-NEXT: store x86_fp80 [[TMP0]], ptr [[RETVAL_REALP]], align 16 +// FULL_FAST-NEXT: store x86_fp80 [[TMP1]], ptr [[RETVAL_IMAGP]], align 16 +// FULL_FAST-NEXT: [[TMP2:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// FULL_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP2]] +// +// IMPRVD_FAST-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld( +// IMPRVD_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] { +// IMPRVD_FAST-NEXT: entry: +// IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]]) +// IMPRVD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]]) +// IMPRVD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt x86_fp80 [[TMP0]], [[TMP1]] +// IMPRVD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP2:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP3]] +// IMPRVD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[TMP2]] +// IMPRVD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[TMP5]] +// IMPRVD_FAST-NEXT: [[TMP7:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP4]] +// IMPRVD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[TMP2]] +// IMPRVD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[TMP8]] +// IMPRVD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP9]], [[TMP4]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP11]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP12]] +// IMPRVD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[TMP11]] +// IMPRVD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP14]], [[A_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP16:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP15]], [[TMP13]] +// IMPRVD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[TMP11]] +// IMPRVD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP17]], [[A_REAL]] +// IMPRVD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP18]], [[TMP13]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD_FAST: complex_div: +// IMPRVD_FAST-NEXT: [[TMP20:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store x86_fp80 [[TMP20]], ptr [[RETVAL_REALP]], align 16 +// IMPRVD_FAST-NEXT: store x86_fp80 [[TMP21]], ptr [[RETVAL_IMAGP]], align 16 +// IMPRVD_FAST-NEXT: [[TMP22:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// IMPRVD_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP22]] +// +// PRMTD_FAST-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld( +// PRMTD_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// PRMTD_FAST-NEXT: entry: +// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// PRMTD_FAST-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]]) +// PRMTD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]]) +// PRMTD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt x86_fp80 [[TMP0]], [[TMP1]] +// PRMTD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// PRMTD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: +// PRMTD_FAST-NEXT: [[TMP2:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[B_REAL]] +// PRMTD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[B_IMAG]] +// PRMTD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP3]] +// PRMTD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[TMP2]] +// PRMTD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[TMP5]] +// PRMTD_FAST-NEXT: [[TMP7:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP4]] +// PRMTD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[TMP2]] +// PRMTD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[TMP8]] +// PRMTD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP9]], [[TMP4]] +// PRMTD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] +// PRMTD_FAST: abs_rhsr_less_than_abs_rhsi: +// PRMTD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[B_IMAG]] +// PRMTD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP11]], [[B_REAL]] +// PRMTD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP12]] +// PRMTD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[TMP11]] +// PRMTD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP14]], [[A_IMAG]] +// PRMTD_FAST-NEXT: [[TMP16:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP15]], [[TMP13]] +// PRMTD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[TMP11]] +// PRMTD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP17]], [[A_REAL]] +// PRMTD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP18]], [[TMP13]] +// PRMTD_FAST-NEXT: br label [[COMPLEX_DIV]] +// PRMTD_FAST: complex_div: +// PRMTD_FAST-NEXT: [[TMP20:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store x86_fp80 [[TMP20]], ptr [[RETVAL_REALP]], align 16 +// PRMTD_FAST-NEXT: store x86_fp80 [[TMP21]], ptr [[RETVAL_IMAGP]], align 16 +// PRMTD_FAST-NEXT: [[TMP22:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// PRMTD_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP22]] +// +_Complex long double divld(_Complex long double a, _Complex long double b) { + return a / b; +} +// FULL-LABEL: define dso_local { x86_fp80, x86_fp80 } @mulld( +// FULL-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// FULL-NEXT: entry: +// FULL-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// FULL-NEXT: [[MUL_AC:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_REAL]] +// FULL-NEXT: [[MUL_BD:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_IMAG]] +// FULL-NEXT: [[MUL_AD:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_IMAG]] +// FULL-NEXT: [[MUL_BC:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_REAL]] +// FULL-NEXT: [[MUL_R:%.*]] = fsub x86_fp80 [[MUL_AC]], [[MUL_BD]] +// FULL-NEXT: [[MUL_I:%.*]] = fadd x86_fp80 [[MUL_AD]], [[MUL_BC]] +// FULL-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno x86_fp80 [[MUL_R]], [[MUL_R]] +// FULL-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]] +// FULL: complex_mul_imag_nan: +// FULL-NEXT: [[ISNAN_CMP1:%.*]] = fcmp uno x86_fp80 [[MUL_I]], [[MUL_I]] +// FULL-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]] +// FULL: complex_mul_libcall: +// FULL-NEXT: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__mulxc3(x86_fp80 noundef [[A_REAL]], x86_fp80 noundef [[A_IMAG]], x86_fp80 noundef [[B_REAL]], x86_fp80 noundef [[B_IMAG]]) #[[ATTR2]] +// FULL-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0 +// FULL-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1 +// FULL-NEXT: br label [[COMPLEX_MUL_CONT]] +// FULL: complex_mul_cont: +// FULL-NEXT: [[REAL_MUL_PHI:%.*]] = phi x86_fp80 [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP0]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL-NEXT: [[IMAG_MUL_PHI:%.*]] = phi x86_fp80 [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP1]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// FULL-NEXT: store x86_fp80 [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 16 +// FULL-NEXT: store x86_fp80 [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 16 +// FULL-NEXT: [[TMP2:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// FULL-NEXT: ret { x86_fp80, x86_fp80 } [[TMP2]] +// +// BASIC-LABEL: define dso_local { x86_fp80, x86_fp80 } @mulld( +// BASIC-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// BASIC-NEXT: entry: +// BASIC-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// BASIC-NEXT: [[MUL_AC:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_REAL]] +// BASIC-NEXT: [[MUL_BD:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_IMAG]] +// BASIC-NEXT: [[MUL_AD:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_IMAG]] +// BASIC-NEXT: [[MUL_BC:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_REAL]] +// BASIC-NEXT: [[MUL_R:%.*]] = fsub x86_fp80 [[MUL_AC]], [[MUL_BD]] +// BASIC-NEXT: [[MUL_I:%.*]] = fadd x86_fp80 [[MUL_AD]], [[MUL_BC]] +// BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC-NEXT: store x86_fp80 [[MUL_R]], ptr [[RETVAL_REALP]], align 16 +// BASIC-NEXT: store x86_fp80 [[MUL_I]], ptr [[RETVAL_IMAGP]], align 16 +// BASIC-NEXT: [[TMP0:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// BASIC-NEXT: ret { x86_fp80, x86_fp80 } [[TMP0]] +// +// IMPRVD-LABEL: define dso_local { x86_fp80, x86_fp80 } @mulld( +// IMPRVD-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] { +// IMPRVD-NEXT: entry: +// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// IMPRVD-NEXT: [[MUL_AC:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_REAL]] +// IMPRVD-NEXT: [[MUL_BD:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_IMAG]] +// IMPRVD-NEXT: [[MUL_AD:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_IMAG]] +// IMPRVD-NEXT: [[MUL_BC:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_REAL]] +// IMPRVD-NEXT: [[MUL_R:%.*]] = fsub x86_fp80 [[MUL_AC]], [[MUL_BD]] +// IMPRVD-NEXT: [[MUL_I:%.*]] = fadd x86_fp80 [[MUL_AD]], [[MUL_BC]] +// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD-NEXT: store x86_fp80 [[MUL_R]], ptr [[RETVAL_REALP]], align 16 +// IMPRVD-NEXT: store x86_fp80 [[MUL_I]], ptr [[RETVAL_IMAGP]], align 16 +// IMPRVD-NEXT: [[TMP0:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// IMPRVD-NEXT: ret { x86_fp80, x86_fp80 } [[TMP0]] +// +// PRMTD-LABEL: define dso_local { x86_fp80, x86_fp80 } @mulld( +// PRMTD-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// PRMTD-NEXT: entry: +// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// PRMTD-NEXT: [[MUL_AC:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_REAL]] +// PRMTD-NEXT: [[MUL_BD:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_IMAG]] +// PRMTD-NEXT: [[MUL_AD:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_IMAG]] +// PRMTD-NEXT: [[MUL_BC:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_REAL]] +// PRMTD-NEXT: [[MUL_R:%.*]] = fsub x86_fp80 [[MUL_AC]], [[MUL_BD]] +// PRMTD-NEXT: [[MUL_I:%.*]] = fadd x86_fp80 [[MUL_AD]], [[MUL_BC]] +// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD-NEXT: store x86_fp80 [[MUL_R]], ptr [[RETVAL_REALP]], align 16 +// PRMTD-NEXT: store x86_fp80 [[MUL_I]], ptr [[RETVAL_IMAGP]], align 16 +// PRMTD-NEXT: [[TMP0:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// PRMTD-NEXT: ret { x86_fp80, x86_fp80 } [[TMP0]] +// +// X86WINPRMTD-LABEL: define dso_local void @mulld( +// X86WINPRMTD-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] { +// X86WINPRMTD-NEXT: entry: +// X86WINPRMTD-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: [[A_INDIRECT_ADDR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: store ptr [[AGG_RESULT]], ptr [[RESULT_PTR]], align 8 +// X86WINPRMTD-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8 +// X86WINPRMTD-NEXT: store ptr [[A]], ptr [[A_INDIRECT_ADDR]], align 8 +// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8 +// X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[MUL_AC:%.*]] = fmul double [[A_REAL]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[MUL_BD:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[MUL_AD:%.*]] = fmul double [[A_REAL]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[MUL_BC:%.*]] = fmul double [[A_IMAG]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]] +// X86WINPRMTD-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]] +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store double [[MUL_R]], ptr [[AGG_RESULT_REALP]], align 8 +// X86WINPRMTD-NEXT: store double [[MUL_I]], ptr [[AGG_RESULT_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8 +// X86WINPRMTD-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8 +// X86WINPRMTD-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8 +// X86WINPRMTD-NEXT: ret void +// +// AVRFP32-LABEL: define dso_local { float, float } @mulld( +// AVRFP32-SAME: float noundef [[A_COERCE0:%.*]], float noundef [[A_COERCE1:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP32-NEXT: entry: +// AVRFP32-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[A:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[A_COERCE0]], ptr [[TMP0]], align 1 +// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[A_COERCE1]], ptr [[TMP1]], align 1 +// AVRFP32-NEXT: [[TMP2:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP2]], align 1 +// AVRFP32-NEXT: [[TMP3:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP3]], align 1 +// AVRFP32-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 1 +// AVRFP32-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 1 +// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1 +// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1 +// AVRFP32-NEXT: [[MUL_AC:%.*]] = fmul float [[A_REAL]], [[B_REAL]] +// AVRFP32-NEXT: [[MUL_BD:%.*]] = fmul float [[A_IMAG]], [[B_IMAG]] +// AVRFP32-NEXT: [[MUL_AD:%.*]] = fmul float [[A_REAL]], [[B_IMAG]] +// AVRFP32-NEXT: [[MUL_BC:%.*]] = fmul float [[A_IMAG]], [[B_REAL]] +// AVRFP32-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] +// AVRFP32-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] +// AVRFP32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// AVRFP32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[MUL_R]], ptr [[RETVAL_REALP]], align 1 +// AVRFP32-NEXT: store float [[MUL_I]], ptr [[RETVAL_IMAGP]], align 1 +// AVRFP32-NEXT: [[TMP4:%.*]] = load { float, float }, ptr [[RETVAL]], align 1 +// AVRFP32-NEXT: ret { float, float } [[TMP4]] +// +// AVRFP64-LABEL: define dso_local void @mulld( +// AVRFP64-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 1 [[AGG_RESULT:%.*]], double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP64-NEXT: entry: +// AVRFP64-NEXT: [[A:%.*]] = alloca { double, double }, align 1 +// AVRFP64-NEXT: [[B:%.*]] = alloca { double, double }, align 1 +// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 1 +// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 1 +// AVRFP64-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 1 +// AVRFP64-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 1 +// AVRFP64-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 1 +// AVRFP64-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 1 +// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 1 +// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 1 +// AVRFP64-NEXT: [[MUL_AC:%.*]] = fmul double [[A_REAL]], [[B_REAL]] +// AVRFP64-NEXT: [[MUL_BD:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]] +// AVRFP64-NEXT: [[MUL_AD:%.*]] = fmul double [[A_REAL]], [[B_IMAG]] +// AVRFP64-NEXT: [[MUL_BC:%.*]] = fmul double [[A_IMAG]], [[B_REAL]] +// AVRFP64-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]] +// AVRFP64-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]] +// AVRFP64-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[MUL_R]], ptr [[AGG_RESULT_REALP]], align 1 +// AVRFP64-NEXT: store double [[MUL_I]], ptr [[AGG_RESULT_IMAGP]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 1 +// AVRFP64-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0 +// AVRFP64-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 1 +// AVRFP64-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 1 +// AVRFP64-NEXT: ret void +// +// BASIC_FAST-LABEL: define dso_local { x86_fp80, x86_fp80 } @mulld( +// BASIC_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// BASIC_FAST-NEXT: entry: +// BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// BASIC_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[B_REAL]] +// BASIC_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[B_IMAG]] +// BASIC_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[B_REAL]] +// BASIC_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AC]], [[MUL_BD]] +// BASIC_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AD]], [[MUL_BC]] +// BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC_FAST-NEXT: store x86_fp80 [[MUL_R]], ptr [[RETVAL_REALP]], align 16 +// BASIC_FAST-NEXT: store x86_fp80 [[MUL_I]], ptr [[RETVAL_IMAGP]], align 16 +// BASIC_FAST-NEXT: [[TMP0:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// BASIC_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP0]] +// +// FULL_FAST-LABEL: define dso_local { x86_fp80, x86_fp80 } @mulld( +// FULL_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// FULL_FAST-NEXT: entry: +// FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// FULL_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[B_REAL]] +// FULL_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[B_IMAG]] +// FULL_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[B_IMAG]] +// FULL_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[B_REAL]] +// FULL_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AC]], [[MUL_BD]] +// FULL_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AD]], [[MUL_BC]] +// FULL_FAST-NEXT: [[ISNAN_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno x86_fp80 [[MUL_R]], [[MUL_R]] +// FULL_FAST-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]] +// FULL_FAST: complex_mul_imag_nan: +// FULL_FAST-NEXT: [[ISNAN_CMP1:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno x86_fp80 [[MUL_I]], [[MUL_I]] +// FULL_FAST-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]] +// FULL_FAST: complex_mul_libcall: +// FULL_FAST-NEXT: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__mulxc3(x86_fp80 noundef nofpclass(nan inf) [[A_REAL]], x86_fp80 noundef nofpclass(nan inf) [[A_IMAG]], x86_fp80 noundef nofpclass(nan inf) [[B_REAL]], x86_fp80 noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2]] +// FULL_FAST-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0 +// FULL_FAST-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1 +// FULL_FAST-NEXT: br label [[COMPLEX_MUL_CONT]] +// FULL_FAST: complex_mul_cont: +// FULL_FAST-NEXT: [[REAL_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP0]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL_FAST-NEXT: [[IMAG_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP1]], [[COMPLEX_MUL_LIBCALL]] ] +// FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// FULL_FAST-NEXT: store x86_fp80 [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 16 +// FULL_FAST-NEXT: store x86_fp80 [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 16 +// FULL_FAST-NEXT: [[TMP2:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// FULL_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP2]] +// +// IMPRVD_FAST-LABEL: define dso_local { x86_fp80, x86_fp80 } @mulld( +// IMPRVD_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] { +// IMPRVD_FAST-NEXT: entry: +// IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// IMPRVD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AC]], [[MUL_BD]] +// IMPRVD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AD]], [[MUL_BC]] +// IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store x86_fp80 [[MUL_R]], ptr [[RETVAL_REALP]], align 16 +// IMPRVD_FAST-NEXT: store x86_fp80 [[MUL_I]], ptr [[RETVAL_IMAGP]], align 16 +// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// IMPRVD_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP0]] +// +// PRMTD_FAST-LABEL: define dso_local { x86_fp80, x86_fp80 } @mulld( +// PRMTD_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] { +// PRMTD_FAST-NEXT: entry: +// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16 +// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16 +// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16 +// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// PRMTD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[B_REAL]] +// PRMTD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[B_IMAG]] +// PRMTD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[B_IMAG]] +// PRMTD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[B_REAL]] +// PRMTD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AC]], [[MUL_BD]] +// PRMTD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AD]], [[MUL_BC]] +// PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store x86_fp80 [[MUL_R]], ptr [[RETVAL_REALP]], align 16 +// PRMTD_FAST-NEXT: store x86_fp80 [[MUL_I]], ptr [[RETVAL_IMAGP]], align 16 +// PRMTD_FAST-NEXT: [[TMP0:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16 +// PRMTD_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP0]] +// +_Complex long double mulld(_Complex long double a, _Complex long double b) { return a * b; } + +// FULL-LABEL: define dso_local <2 x float> @f1( +// FULL-SAME: <2 x float> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x float> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { +// FULL-NEXT: entry: +// FULL-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: [[C:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// FULL-NEXT: store <2 x float> [[C_COERCE]], ptr [[C]], align 4 +// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// FULL-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// FULL-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// FULL-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// FULL-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 4 +// FULL-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// FULL-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 4 +// FULL-NEXT: [[CONV:%.*]] = fpext float [[C_REAL]] to x86_fp80 +// FULL-NEXT: [[CONV1:%.*]] = fpext float [[C_IMAG]] to x86_fp80 +// FULL-NEXT: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__divxc3(x86_fp80 noundef [[B_REAL]], x86_fp80 noundef [[B_IMAG]], x86_fp80 noundef [[CONV]], x86_fp80 noundef [[CONV1]]) #[[ATTR2]] +// FULL-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0 +// FULL-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1 +// FULL-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP0]] to float +// FULL-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP1]] to float +// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// FULL-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// FULL-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// FULL-NEXT: [[CALL4:%.*]] = call <2 x float> @__divsc3(float noundef [[CONV2]], float noundef [[CONV3]], float noundef [[A_REAL]], float noundef [[A_IMAG]]) #[[ATTR2]] +// FULL-NEXT: store <2 x float> [[CALL4]], ptr [[COERCE]], align 4 +// FULL-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// FULL-NEXT: store float [[COERCE_REAL]], ptr [[RETVAL_REALP]], align 4 +// FULL-NEXT: store float [[COERCE_IMAG]], ptr [[RETVAL_IMAGP]], align 4 +// FULL-NEXT: [[TMP2:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// FULL-NEXT: ret <2 x float> [[TMP2]] +// +// BASIC-LABEL: define dso_local <2 x float> @f1( +// BASIC-SAME: <2 x float> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x float> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { +// BASIC-NEXT: entry: +// BASIC-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// BASIC-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// BASIC-NEXT: [[C:%.*]] = alloca { float, float }, align 4 +// BASIC-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// BASIC-NEXT: store <2 x float> [[C_COERCE]], ptr [[C]], align 4 +// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// BASIC-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// BASIC-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// BASIC-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// BASIC-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 4 +// BASIC-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// BASIC-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 4 +// BASIC-NEXT: [[CONV:%.*]] = fpext float [[C_REAL]] to x86_fp80 +// BASIC-NEXT: [[CONV1:%.*]] = fpext float [[C_IMAG]] to x86_fp80 +// BASIC-NEXT: [[TMP0:%.*]] = fmul x86_fp80 [[B_REAL]], [[CONV]] +// BASIC-NEXT: [[TMP1:%.*]] = fmul x86_fp80 [[B_IMAG]], [[CONV1]] +// BASIC-NEXT: [[TMP2:%.*]] = fadd x86_fp80 [[TMP0]], [[TMP1]] +// BASIC-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[CONV]], [[CONV]] +// BASIC-NEXT: [[TMP4:%.*]] = fmul x86_fp80 [[CONV1]], [[CONV1]] +// BASIC-NEXT: [[TMP5:%.*]] = fadd x86_fp80 [[TMP3]], [[TMP4]] +// BASIC-NEXT: [[TMP6:%.*]] = fmul x86_fp80 [[B_IMAG]], [[CONV]] +// BASIC-NEXT: [[TMP7:%.*]] = fmul x86_fp80 [[B_REAL]], [[CONV1]] +// BASIC-NEXT: [[TMP8:%.*]] = fsub x86_fp80 [[TMP6]], [[TMP7]] +// BASIC-NEXT: [[TMP9:%.*]] = fdiv x86_fp80 [[TMP2]], [[TMP5]] +// BASIC-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP8]], [[TMP5]] +// BASIC-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP9]] to float +// BASIC-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP10]] to float +// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// BASIC-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// BASIC-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// BASIC-NEXT: [[TMP11:%.*]] = fmul float [[CONV2]], [[A_REAL]] +// BASIC-NEXT: [[TMP12:%.*]] = fmul float [[CONV3]], [[A_IMAG]] +// BASIC-NEXT: [[TMP13:%.*]] = fadd float [[TMP11]], [[TMP12]] +// BASIC-NEXT: [[TMP14:%.*]] = fmul float [[A_REAL]], [[A_REAL]] +// BASIC-NEXT: [[TMP15:%.*]] = fmul float [[A_IMAG]], [[A_IMAG]] +// BASIC-NEXT: [[TMP16:%.*]] = fadd float [[TMP14]], [[TMP15]] +// BASIC-NEXT: [[TMP17:%.*]] = fmul float [[CONV3]], [[A_REAL]] +// BASIC-NEXT: [[TMP18:%.*]] = fmul float [[CONV2]], [[A_IMAG]] +// BASIC-NEXT: [[TMP19:%.*]] = fsub float [[TMP17]], [[TMP18]] +// BASIC-NEXT: [[TMP20:%.*]] = fdiv float [[TMP13]], [[TMP16]] +// BASIC-NEXT: [[TMP21:%.*]] = fdiv float [[TMP19]], [[TMP16]] +// BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC-NEXT: store float [[TMP20]], ptr [[RETVAL_REALP]], align 4 +// BASIC-NEXT: store float [[TMP21]], ptr [[RETVAL_IMAGP]], align 4 +// BASIC-NEXT: [[TMP22:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// BASIC-NEXT: ret <2 x float> [[TMP22]] +// +// IMPRVD-LABEL: define dso_local <2 x float> @f1( +// IMPRVD-SAME: <2 x float> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x float> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { +// IMPRVD-NEXT: entry: +// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: [[C:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// IMPRVD-NEXT: store <2 x float> [[C_COERCE]], ptr [[C]], align 4 +// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// IMPRVD-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// IMPRVD-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 4 +// IMPRVD-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// IMPRVD-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 4 +// IMPRVD-NEXT: [[CONV:%.*]] = fpext float [[C_REAL]] to x86_fp80 +// IMPRVD-NEXT: [[CONV1:%.*]] = fpext float [[C_IMAG]] to x86_fp80 +// IMPRVD-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) +// IMPRVD-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) +// IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt x86_fp80 [[TMP0]], [[TMP1]] +// IMPRVD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[CONV1]], [[CONV]] +// IMPRVD-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[TMP2]], [[CONV1]] +// IMPRVD-NEXT: [[TMP4:%.*]] = fadd x86_fp80 [[CONV]], [[TMP3]] +// IMPRVD-NEXT: [[TMP5:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP2]] +// IMPRVD-NEXT: [[TMP6:%.*]] = fadd x86_fp80 [[B_REAL]], [[TMP5]] +// IMPRVD-NEXT: [[TMP7:%.*]] = fdiv x86_fp80 [[TMP6]], [[TMP4]] +// IMPRVD-NEXT: [[TMP8:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP2]] +// IMPRVD-NEXT: [[TMP9:%.*]] = fsub x86_fp80 [[B_IMAG]], [[TMP8]] +// IMPRVD-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP9]], [[TMP4]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD: abs_rhsr_less_than_abs_rhsi: +// IMPRVD-NEXT: [[TMP11:%.*]] = fdiv x86_fp80 [[CONV]], [[CONV1]] +// IMPRVD-NEXT: [[TMP12:%.*]] = fmul x86_fp80 [[TMP11]], [[CONV]] +// IMPRVD-NEXT: [[TMP13:%.*]] = fadd x86_fp80 [[CONV1]], [[TMP12]] +// IMPRVD-NEXT: [[TMP14:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP11]] +// IMPRVD-NEXT: [[TMP15:%.*]] = fadd x86_fp80 [[TMP14]], [[B_IMAG]] +// IMPRVD-NEXT: [[TMP16:%.*]] = fdiv x86_fp80 [[TMP15]], [[TMP13]] +// IMPRVD-NEXT: [[TMP17:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP11]] +// IMPRVD-NEXT: [[TMP18:%.*]] = fsub x86_fp80 [[TMP17]], [[B_REAL]] +// IMPRVD-NEXT: [[TMP19:%.*]] = fdiv x86_fp80 [[TMP18]], [[TMP13]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD: complex_div: +// IMPRVD-NEXT: [[TMP20:%.*]] = phi x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP20]] to float +// IMPRVD-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP21]] to float +// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// IMPRVD-NEXT: [[TMP22:%.*]] = call float @llvm.fabs.f32(float [[A_REAL]]) +// IMPRVD-NEXT: [[TMP23:%.*]] = call float @llvm.fabs.f32(float [[A_IMAG]]) +// IMPRVD-NEXT: [[ABS_CMP4:%.*]] = fcmp ugt float [[TMP22]], [[TMP23]] +// IMPRVD-NEXT: br i1 [[ABS_CMP4]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI5:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI6:%.*]] +// IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi5: +// IMPRVD-NEXT: [[TMP24:%.*]] = fdiv float [[A_IMAG]], [[A_REAL]] +// IMPRVD-NEXT: [[TMP25:%.*]] = fmul float [[TMP24]], [[A_IMAG]] +// IMPRVD-NEXT: [[TMP26:%.*]] = fadd float [[A_REAL]], [[TMP25]] +// IMPRVD-NEXT: [[TMP27:%.*]] = fmul float [[CONV3]], [[TMP24]] +// IMPRVD-NEXT: [[TMP28:%.*]] = fadd float [[CONV2]], [[TMP27]] +// IMPRVD-NEXT: [[TMP29:%.*]] = fdiv float [[TMP28]], [[TMP26]] +// IMPRVD-NEXT: [[TMP30:%.*]] = fmul float [[CONV2]], [[TMP24]] +// IMPRVD-NEXT: [[TMP31:%.*]] = fsub float [[CONV3]], [[TMP30]] +// IMPRVD-NEXT: [[TMP32:%.*]] = fdiv float [[TMP31]], [[TMP26]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV7:%.*]] +// IMPRVD: abs_rhsr_less_than_abs_rhsi6: +// IMPRVD-NEXT: [[TMP33:%.*]] = fdiv float [[A_REAL]], [[A_IMAG]] +// IMPRVD-NEXT: [[TMP34:%.*]] = fmul float [[TMP33]], [[A_REAL]] +// IMPRVD-NEXT: [[TMP35:%.*]] = fadd float [[A_IMAG]], [[TMP34]] +// IMPRVD-NEXT: [[TMP36:%.*]] = fmul float [[CONV2]], [[TMP33]] +// IMPRVD-NEXT: [[TMP37:%.*]] = fadd float [[TMP36]], [[CONV3]] +// IMPRVD-NEXT: [[TMP38:%.*]] = fdiv float [[TMP37]], [[TMP35]] +// IMPRVD-NEXT: [[TMP39:%.*]] = fmul float [[CONV3]], [[TMP33]] +// IMPRVD-NEXT: [[TMP40:%.*]] = fsub float [[TMP39]], [[CONV2]] +// IMPRVD-NEXT: [[TMP41:%.*]] = fdiv float [[TMP40]], [[TMP35]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV7]] +// IMPRVD: complex_div7: +// IMPRVD-NEXT: [[TMP42:%.*]] = phi float [ [[TMP29]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI5]] ], [ [[TMP38]], [[ABS_RHSR_LESS_THAN_ABS_RHSI6]] ] +// IMPRVD-NEXT: [[TMP43:%.*]] = phi float [ [[TMP32]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI5]] ], [ [[TMP41]], [[ABS_RHSR_LESS_THAN_ABS_RHSI6]] ] +// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD-NEXT: store float [[TMP42]], ptr [[RETVAL_REALP]], align 4 +// IMPRVD-NEXT: store float [[TMP43]], ptr [[RETVAL_IMAGP]], align 4 +// IMPRVD-NEXT: [[TMP44:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// IMPRVD-NEXT: ret <2 x float> [[TMP44]] +// +// PRMTD-LABEL: define dso_local <2 x float> @f1( +// PRMTD-SAME: <2 x float> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x float> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { +// PRMTD-NEXT: entry: +// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// PRMTD-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// PRMTD-NEXT: [[C:%.*]] = alloca { float, float }, align 4 +// PRMTD-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// PRMTD-NEXT: store <2 x float> [[C_COERCE]], ptr [[C]], align 4 +// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// PRMTD-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// PRMTD-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// PRMTD-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// PRMTD-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 4 +// PRMTD-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// PRMTD-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 4 +// PRMTD-NEXT: [[CONV:%.*]] = fpext float [[C_REAL]] to x86_fp80 +// PRMTD-NEXT: [[CONV1:%.*]] = fpext float [[C_IMAG]] to x86_fp80 +// PRMTD-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) +// PRMTD-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) +// PRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt x86_fp80 [[TMP0]], [[TMP1]] +// PRMTD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// PRMTD: abs_rhsr_greater_or_equal_abs_rhsi: +// PRMTD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[CONV1]], [[CONV]] +// PRMTD-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[TMP2]], [[CONV1]] +// PRMTD-NEXT: [[TMP4:%.*]] = fadd x86_fp80 [[CONV]], [[TMP3]] +// PRMTD-NEXT: [[TMP5:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP2]] +// PRMTD-NEXT: [[TMP6:%.*]] = fadd x86_fp80 [[B_REAL]], [[TMP5]] +// PRMTD-NEXT: [[TMP7:%.*]] = fdiv x86_fp80 [[TMP6]], [[TMP4]] +// PRMTD-NEXT: [[TMP8:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP2]] +// PRMTD-NEXT: [[TMP9:%.*]] = fsub x86_fp80 [[B_IMAG]], [[TMP8]] +// PRMTD-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP9]], [[TMP4]] +// PRMTD-NEXT: br label [[COMPLEX_DIV:%.*]] +// PRMTD: abs_rhsr_less_than_abs_rhsi: +// PRMTD-NEXT: [[TMP11:%.*]] = fdiv x86_fp80 [[CONV]], [[CONV1]] +// PRMTD-NEXT: [[TMP12:%.*]] = fmul x86_fp80 [[TMP11]], [[CONV]] +// PRMTD-NEXT: [[TMP13:%.*]] = fadd x86_fp80 [[CONV1]], [[TMP12]] +// PRMTD-NEXT: [[TMP14:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP11]] +// PRMTD-NEXT: [[TMP15:%.*]] = fadd x86_fp80 [[TMP14]], [[B_IMAG]] +// PRMTD-NEXT: [[TMP16:%.*]] = fdiv x86_fp80 [[TMP15]], [[TMP13]] +// PRMTD-NEXT: [[TMP17:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP11]] +// PRMTD-NEXT: [[TMP18:%.*]] = fsub x86_fp80 [[TMP17]], [[B_REAL]] +// PRMTD-NEXT: [[TMP19:%.*]] = fdiv x86_fp80 [[TMP18]], [[TMP13]] +// PRMTD-NEXT: br label [[COMPLEX_DIV]] +// PRMTD: complex_div: +// PRMTD-NEXT: [[TMP20:%.*]] = phi x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP20]] to float +// PRMTD-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP21]] to float +// PRMTD-NEXT: [[EXT:%.*]] = fpext float [[CONV2]] to double +// PRMTD-NEXT: [[EXT4:%.*]] = fpext float [[CONV3]] to double +// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// PRMTD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// PRMTD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// PRMTD-NEXT: [[EXT5:%.*]] = fpext float [[A_REAL]] to double +// PRMTD-NEXT: [[EXT6:%.*]] = fpext float [[A_IMAG]] to double +// PRMTD-NEXT: [[TMP22:%.*]] = fmul double [[EXT]], [[EXT5]] +// PRMTD-NEXT: [[TMP23:%.*]] = fmul double [[EXT4]], [[EXT6]] +// PRMTD-NEXT: [[TMP24:%.*]] = fadd double [[TMP22]], [[TMP23]] +// PRMTD-NEXT: [[TMP25:%.*]] = fmul double [[EXT5]], [[EXT5]] +// PRMTD-NEXT: [[TMP26:%.*]] = fmul double [[EXT6]], [[EXT6]] +// PRMTD-NEXT: [[TMP27:%.*]] = fadd double [[TMP25]], [[TMP26]] +// PRMTD-NEXT: [[TMP28:%.*]] = fmul double [[EXT4]], [[EXT5]] +// PRMTD-NEXT: [[TMP29:%.*]] = fmul double [[EXT]], [[EXT6]] +// PRMTD-NEXT: [[TMP30:%.*]] = fsub double [[TMP28]], [[TMP29]] +// PRMTD-NEXT: [[TMP31:%.*]] = fdiv double [[TMP24]], [[TMP27]] +// PRMTD-NEXT: [[TMP32:%.*]] = fdiv double [[TMP30]], [[TMP27]] +// PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc double [[TMP31]] to float +// PRMTD-NEXT: [[UNPROMOTION7:%.*]] = fptrunc double [[TMP32]] to float +// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD-NEXT: store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4 +// PRMTD-NEXT: store float [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 4 +// PRMTD-NEXT: [[TMP33:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// PRMTD-NEXT: ret <2 x float> [[TMP33]] +// +// X86WINPRMTD-LABEL: define dso_local i64 @f1( +// X86WINPRMTD-SAME: i64 noundef [[A_COERCE:%.*]], ptr noundef [[B:%.*]], i64 noundef [[C_COERCE:%.*]]) #[[ATTR0]] { +// X86WINPRMTD-NEXT: entry: +// X86WINPRMTD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// X86WINPRMTD-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// X86WINPRMTD-NEXT: [[C:%.*]] = alloca { float, float }, align 4 +// X86WINPRMTD-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8 +// X86WINPRMTD-NEXT: store i64 [[A_COERCE]], ptr [[A]], align 4 +// X86WINPRMTD-NEXT: store i64 [[C_COERCE]], ptr [[C]], align 4 +// X86WINPRMTD-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8 +// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 +// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 +// X86WINPRMTD-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 4 +// X86WINPRMTD-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 4 +// X86WINPRMTD-NEXT: [[CONV:%.*]] = fpext float [[C_REAL]] to double +// X86WINPRMTD-NEXT: [[CONV1:%.*]] = fpext float [[C_IMAG]] to double +// X86WINPRMTD-NEXT: [[TMP0:%.*]] = call double @llvm.fabs.f64(double [[CONV]]) +// X86WINPRMTD-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[CONV1]]) +// X86WINPRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP0]], [[TMP1]] +// X86WINPRMTD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// X86WINPRMTD: abs_rhsr_greater_or_equal_abs_rhsi: +// X86WINPRMTD-NEXT: [[TMP2:%.*]] = fdiv double [[CONV1]], [[CONV]] +// X86WINPRMTD-NEXT: [[TMP3:%.*]] = fmul double [[TMP2]], [[CONV1]] +// X86WINPRMTD-NEXT: [[TMP4:%.*]] = fadd double [[CONV]], [[TMP3]] +// X86WINPRMTD-NEXT: [[TMP5:%.*]] = fmul double [[B_IMAG]], [[TMP2]] +// X86WINPRMTD-NEXT: [[TMP6:%.*]] = fadd double [[B_REAL]], [[TMP5]] +// X86WINPRMTD-NEXT: [[TMP7:%.*]] = fdiv double [[TMP6]], [[TMP4]] +// X86WINPRMTD-NEXT: [[TMP8:%.*]] = fmul double [[B_REAL]], [[TMP2]] +// X86WINPRMTD-NEXT: [[TMP9:%.*]] = fsub double [[B_IMAG]], [[TMP8]] +// X86WINPRMTD-NEXT: [[TMP10:%.*]] = fdiv double [[TMP9]], [[TMP4]] +// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV:%.*]] +// X86WINPRMTD: abs_rhsr_less_than_abs_rhsi: +// X86WINPRMTD-NEXT: [[TMP11:%.*]] = fdiv double [[CONV]], [[CONV1]] +// X86WINPRMTD-NEXT: [[TMP12:%.*]] = fmul double [[TMP11]], [[CONV]] +// X86WINPRMTD-NEXT: [[TMP13:%.*]] = fadd double [[CONV1]], [[TMP12]] +// X86WINPRMTD-NEXT: [[TMP14:%.*]] = fmul double [[B_REAL]], [[TMP11]] +// X86WINPRMTD-NEXT: [[TMP15:%.*]] = fadd double [[TMP14]], [[B_IMAG]] +// X86WINPRMTD-NEXT: [[TMP16:%.*]] = fdiv double [[TMP15]], [[TMP13]] +// X86WINPRMTD-NEXT: [[TMP17:%.*]] = fmul double [[B_IMAG]], [[TMP11]] +// X86WINPRMTD-NEXT: [[TMP18:%.*]] = fsub double [[TMP17]], [[B_REAL]] +// X86WINPRMTD-NEXT: [[TMP19:%.*]] = fdiv double [[TMP18]], [[TMP13]] +// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV]] +// X86WINPRMTD: complex_div: +// X86WINPRMTD-NEXT: [[TMP20:%.*]] = phi double [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// X86WINPRMTD-NEXT: [[TMP21:%.*]] = phi double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// X86WINPRMTD-NEXT: [[CONV2:%.*]] = fptrunc double [[TMP20]] to float +// X86WINPRMTD-NEXT: [[CONV3:%.*]] = fptrunc double [[TMP21]] to float +// X86WINPRMTD-NEXT: [[EXT:%.*]] = fpext float [[CONV2]] to double +// X86WINPRMTD-NEXT: [[EXT4:%.*]] = fpext float [[CONV3]] to double +// X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// X86WINPRMTD-NEXT: [[EXT5:%.*]] = fpext float [[A_REAL]] to double +// X86WINPRMTD-NEXT: [[EXT6:%.*]] = fpext float [[A_IMAG]] to double +// X86WINPRMTD-NEXT: [[TMP22:%.*]] = fmul double [[EXT]], [[EXT5]] +// X86WINPRMTD-NEXT: [[TMP23:%.*]] = fmul double [[EXT4]], [[EXT6]] +// X86WINPRMTD-NEXT: [[TMP24:%.*]] = fadd double [[TMP22]], [[TMP23]] +// X86WINPRMTD-NEXT: [[TMP25:%.*]] = fmul double [[EXT5]], [[EXT5]] +// X86WINPRMTD-NEXT: [[TMP26:%.*]] = fmul double [[EXT6]], [[EXT6]] +// X86WINPRMTD-NEXT: [[TMP27:%.*]] = fadd double [[TMP25]], [[TMP26]] +// X86WINPRMTD-NEXT: [[TMP28:%.*]] = fmul double [[EXT4]], [[EXT5]] +// X86WINPRMTD-NEXT: [[TMP29:%.*]] = fmul double [[EXT]], [[EXT6]] +// X86WINPRMTD-NEXT: [[TMP30:%.*]] = fsub double [[TMP28]], [[TMP29]] +// X86WINPRMTD-NEXT: [[TMP31:%.*]] = fdiv double [[TMP24]], [[TMP27]] +// X86WINPRMTD-NEXT: [[TMP32:%.*]] = fdiv double [[TMP30]], [[TMP27]] +// X86WINPRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc double [[TMP31]] to float +// X86WINPRMTD-NEXT: [[UNPROMOTION7:%.*]] = fptrunc double [[TMP32]] to float +// X86WINPRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// X86WINPRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// X86WINPRMTD-NEXT: store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4 +// X86WINPRMTD-NEXT: store float [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 4 +// X86WINPRMTD-NEXT: [[TMP33:%.*]] = load i64, ptr [[RETVAL]], align 4 +// X86WINPRMTD-NEXT: ret i64 [[TMP33]] +// +// AVRFP32-LABEL: define dso_local { float, float } @f1( +// AVRFP32-SAME: float noundef [[A_COERCE0:%.*]], float noundef [[A_COERCE1:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]], float noundef [[C_COERCE0:%.*]], float noundef [[C_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP32-NEXT: entry: +// AVRFP32-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[A:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[C:%.*]] = alloca { float, float }, align 1 +// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[A_COERCE0]], ptr [[TMP0]], align 1 +// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[A_COERCE1]], ptr [[TMP1]], align 1 +// AVRFP32-NEXT: [[TMP2:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP2]], align 1 +// AVRFP32-NEXT: [[TMP3:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP3]], align 1 +// AVRFP32-NEXT: [[TMP4:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// AVRFP32-NEXT: store float [[C_COERCE0]], ptr [[TMP4]], align 1 +// AVRFP32-NEXT: [[TMP5:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[C_COERCE1]], ptr [[TMP5]], align 1 +// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1 +// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1 +// AVRFP32-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// AVRFP32-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 1 +// AVRFP32-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// AVRFP32-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 1 +// AVRFP32-NEXT: [[TMP6:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[C_REAL]]) +// AVRFP32-NEXT: [[TMP7:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[C_IMAG]]) +// AVRFP32-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP6]], [[TMP7]] +// AVRFP32-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// AVRFP32: abs_rhsr_greater_or_equal_abs_rhsi: +// AVRFP32-NEXT: [[TMP8:%.*]] = fdiv float [[C_IMAG]], [[C_REAL]] +// AVRFP32-NEXT: [[TMP9:%.*]] = fmul float [[TMP8]], [[C_IMAG]] +// AVRFP32-NEXT: [[TMP10:%.*]] = fadd float [[C_REAL]], [[TMP9]] +// AVRFP32-NEXT: [[TMP11:%.*]] = fmul float [[B_IMAG]], [[TMP8]] +// AVRFP32-NEXT: [[TMP12:%.*]] = fadd float [[B_REAL]], [[TMP11]] +// AVRFP32-NEXT: [[TMP13:%.*]] = fdiv float [[TMP12]], [[TMP10]] +// AVRFP32-NEXT: [[TMP14:%.*]] = fmul float [[B_REAL]], [[TMP8]] +// AVRFP32-NEXT: [[TMP15:%.*]] = fsub float [[B_IMAG]], [[TMP14]] +// AVRFP32-NEXT: [[TMP16:%.*]] = fdiv float [[TMP15]], [[TMP10]] +// AVRFP32-NEXT: br label [[COMPLEX_DIV:%.*]] +// AVRFP32: abs_rhsr_less_than_abs_rhsi: +// AVRFP32-NEXT: [[TMP17:%.*]] = fdiv float [[C_REAL]], [[C_IMAG]] +// AVRFP32-NEXT: [[TMP18:%.*]] = fmul float [[TMP17]], [[C_REAL]] +// AVRFP32-NEXT: [[TMP19:%.*]] = fadd float [[C_IMAG]], [[TMP18]] +// AVRFP32-NEXT: [[TMP20:%.*]] = fmul float [[B_REAL]], [[TMP17]] +// AVRFP32-NEXT: [[TMP21:%.*]] = fadd float [[TMP20]], [[B_IMAG]] +// AVRFP32-NEXT: [[TMP22:%.*]] = fdiv float [[TMP21]], [[TMP19]] +// AVRFP32-NEXT: [[TMP23:%.*]] = fmul float [[B_IMAG]], [[TMP17]] +// AVRFP32-NEXT: [[TMP24:%.*]] = fsub float [[TMP23]], [[B_REAL]] +// AVRFP32-NEXT: [[TMP25:%.*]] = fdiv float [[TMP24]], [[TMP19]] +// AVRFP32-NEXT: br label [[COMPLEX_DIV]] +// AVRFP32: complex_div: +// AVRFP32-NEXT: [[TMP26:%.*]] = phi float [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP32-NEXT: [[TMP27:%.*]] = phi float [ [[TMP16]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP25]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP32-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP32-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 1 +// AVRFP32-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP32-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 1 +// AVRFP32-NEXT: [[TMP28:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[A_REAL]]) +// AVRFP32-NEXT: [[TMP29:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[A_IMAG]]) +// AVRFP32-NEXT: [[ABS_CMP1:%.*]] = fcmp ugt float [[TMP28]], [[TMP29]] +// AVRFP32-NEXT: br i1 [[ABS_CMP1]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI2:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI3:%.*]] +// AVRFP32: abs_rhsr_greater_or_equal_abs_rhsi2: +// AVRFP32-NEXT: [[TMP30:%.*]] = fdiv float [[A_IMAG]], [[A_REAL]] +// AVRFP32-NEXT: [[TMP31:%.*]] = fmul float [[TMP30]], [[A_IMAG]] +// AVRFP32-NEXT: [[TMP32:%.*]] = fadd float [[A_REAL]], [[TMP31]] +// AVRFP32-NEXT: [[TMP33:%.*]] = fmul float [[TMP27]], [[TMP30]] +// AVRFP32-NEXT: [[TMP34:%.*]] = fadd float [[TMP26]], [[TMP33]] +// AVRFP32-NEXT: [[TMP35:%.*]] = fdiv float [[TMP34]], [[TMP32]] +// AVRFP32-NEXT: [[TMP36:%.*]] = fmul float [[TMP26]], [[TMP30]] +// AVRFP32-NEXT: [[TMP37:%.*]] = fsub float [[TMP27]], [[TMP36]] +// AVRFP32-NEXT: [[TMP38:%.*]] = fdiv float [[TMP37]], [[TMP32]] +// AVRFP32-NEXT: br label [[COMPLEX_DIV4:%.*]] +// AVRFP32: abs_rhsr_less_than_abs_rhsi3: +// AVRFP32-NEXT: [[TMP39:%.*]] = fdiv float [[A_REAL]], [[A_IMAG]] +// AVRFP32-NEXT: [[TMP40:%.*]] = fmul float [[TMP39]], [[A_REAL]] +// AVRFP32-NEXT: [[TMP41:%.*]] = fadd float [[A_IMAG]], [[TMP40]] +// AVRFP32-NEXT: [[TMP42:%.*]] = fmul float [[TMP26]], [[TMP39]] +// AVRFP32-NEXT: [[TMP43:%.*]] = fadd float [[TMP42]], [[TMP27]] +// AVRFP32-NEXT: [[TMP44:%.*]] = fdiv float [[TMP43]], [[TMP41]] +// AVRFP32-NEXT: [[TMP45:%.*]] = fmul float [[TMP27]], [[TMP39]] +// AVRFP32-NEXT: [[TMP46:%.*]] = fsub float [[TMP45]], [[TMP26]] +// AVRFP32-NEXT: [[TMP47:%.*]] = fdiv float [[TMP46]], [[TMP41]] +// AVRFP32-NEXT: br label [[COMPLEX_DIV4]] +// AVRFP32: complex_div4: +// AVRFP32-NEXT: [[TMP48:%.*]] = phi float [ [[TMP35]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI2]] ], [ [[TMP44]], [[ABS_RHSR_LESS_THAN_ABS_RHSI3]] ] +// AVRFP32-NEXT: [[TMP49:%.*]] = phi float [ [[TMP38]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI2]] ], [ [[TMP47]], [[ABS_RHSR_LESS_THAN_ABS_RHSI3]] ] +// AVRFP32-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// AVRFP32-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// AVRFP32-NEXT: store float [[TMP48]], ptr [[RETVAL_REALP]], align 1 +// AVRFP32-NEXT: store float [[TMP49]], ptr [[RETVAL_IMAGP]], align 1 +// AVRFP32-NEXT: [[TMP50:%.*]] = load { float, float }, ptr [[RETVAL]], align 1 +// AVRFP32-NEXT: ret { float, float } [[TMP50]] +// +// AVRFP64-LABEL: define dso_local { float, float } @f1( +// AVRFP64-SAME: float noundef [[A_COERCE0:%.*]], float noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]], float noundef [[C_COERCE0:%.*]], float noundef [[C_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] { +// AVRFP64-NEXT: entry: +// AVRFP64-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 1 +// AVRFP64-NEXT: [[A:%.*]] = alloca { float, float }, align 1 +// AVRFP64-NEXT: [[B:%.*]] = alloca { double, double }, align 1 +// AVRFP64-NEXT: [[C:%.*]] = alloca { float, float }, align 1 +// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: store float [[A_COERCE0]], ptr [[TMP0]], align 1 +// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: store float [[A_COERCE1]], ptr [[TMP1]], align 1 +// AVRFP64-NEXT: [[TMP2:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 1 +// AVRFP64-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 1 +// AVRFP64-NEXT: [[TMP4:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// AVRFP64-NEXT: store float [[C_COERCE0]], ptr [[TMP4]], align 1 +// AVRFP64-NEXT: [[TMP5:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// AVRFP64-NEXT: store float [[C_COERCE1]], ptr [[TMP5]], align 1 +// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0 +// AVRFP64-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 1 +// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1 +// AVRFP64-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 1 +// AVRFP64-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// AVRFP64-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 1 +// AVRFP64-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// AVRFP64-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 1 +// AVRFP64-NEXT: [[CONV:%.*]] = fpext float [[C_REAL]] to double +// AVRFP64-NEXT: [[CONV1:%.*]] = fpext float [[C_IMAG]] to double +// AVRFP64-NEXT: [[TMP6:%.*]] = call addrspace(1) double @llvm.fabs.f64(double [[CONV]]) +// AVRFP64-NEXT: [[TMP7:%.*]] = call addrspace(1) double @llvm.fabs.f64(double [[CONV1]]) +// AVRFP64-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP6]], [[TMP7]] +// AVRFP64-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// AVRFP64: abs_rhsr_greater_or_equal_abs_rhsi: +// AVRFP64-NEXT: [[TMP8:%.*]] = fdiv double [[CONV1]], [[CONV]] +// AVRFP64-NEXT: [[TMP9:%.*]] = fmul double [[TMP8]], [[CONV1]] +// AVRFP64-NEXT: [[TMP10:%.*]] = fadd double [[CONV]], [[TMP9]] +// AVRFP64-NEXT: [[TMP11:%.*]] = fmul double [[B_IMAG]], [[TMP8]] +// AVRFP64-NEXT: [[TMP12:%.*]] = fadd double [[B_REAL]], [[TMP11]] +// AVRFP64-NEXT: [[TMP13:%.*]] = fdiv double [[TMP12]], [[TMP10]] +// AVRFP64-NEXT: [[TMP14:%.*]] = fmul double [[B_REAL]], [[TMP8]] +// AVRFP64-NEXT: [[TMP15:%.*]] = fsub double [[B_IMAG]], [[TMP14]] +// AVRFP64-NEXT: [[TMP16:%.*]] = fdiv double [[TMP15]], [[TMP10]] +// AVRFP64-NEXT: br label [[COMPLEX_DIV:%.*]] +// AVRFP64: abs_rhsr_less_than_abs_rhsi: +// AVRFP64-NEXT: [[TMP17:%.*]] = fdiv double [[CONV]], [[CONV1]] +// AVRFP64-NEXT: [[TMP18:%.*]] = fmul double [[TMP17]], [[CONV]] +// AVRFP64-NEXT: [[TMP19:%.*]] = fadd double [[CONV1]], [[TMP18]] +// AVRFP64-NEXT: [[TMP20:%.*]] = fmul double [[B_REAL]], [[TMP17]] +// AVRFP64-NEXT: [[TMP21:%.*]] = fadd double [[TMP20]], [[B_IMAG]] +// AVRFP64-NEXT: [[TMP22:%.*]] = fdiv double [[TMP21]], [[TMP19]] +// AVRFP64-NEXT: [[TMP23:%.*]] = fmul double [[B_IMAG]], [[TMP17]] +// AVRFP64-NEXT: [[TMP24:%.*]] = fsub double [[TMP23]], [[B_REAL]] +// AVRFP64-NEXT: [[TMP25:%.*]] = fdiv double [[TMP24]], [[TMP19]] +// AVRFP64-NEXT: br label [[COMPLEX_DIV]] +// AVRFP64: complex_div: +// AVRFP64-NEXT: [[TMP26:%.*]] = phi double [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP64-NEXT: [[TMP27:%.*]] = phi double [ [[TMP16]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP25]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// AVRFP64-NEXT: [[CONV2:%.*]] = fptrunc double [[TMP26]] to float +// AVRFP64-NEXT: [[CONV3:%.*]] = fptrunc double [[TMP27]] to float +// AVRFP64-NEXT: [[EXT:%.*]] = fpext float [[CONV2]] to double +// AVRFP64-NEXT: [[EXT4:%.*]] = fpext float [[CONV3]] to double +// AVRFP64-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// AVRFP64-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 1 +// AVRFP64-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// AVRFP64-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 1 +// AVRFP64-NEXT: [[EXT5:%.*]] = fpext float [[A_REAL]] to double +// AVRFP64-NEXT: [[EXT6:%.*]] = fpext float [[A_IMAG]] to double +// AVRFP64-NEXT: [[TMP28:%.*]] = fmul double [[EXT]], [[EXT5]] +// AVRFP64-NEXT: [[TMP29:%.*]] = fmul double [[EXT4]], [[EXT6]] +// AVRFP64-NEXT: [[TMP30:%.*]] = fadd double [[TMP28]], [[TMP29]] +// AVRFP64-NEXT: [[TMP31:%.*]] = fmul double [[EXT5]], [[EXT5]] +// AVRFP64-NEXT: [[TMP32:%.*]] = fmul double [[EXT6]], [[EXT6]] +// AVRFP64-NEXT: [[TMP33:%.*]] = fadd double [[TMP31]], [[TMP32]] +// AVRFP64-NEXT: [[TMP34:%.*]] = fmul double [[EXT4]], [[EXT5]] +// AVRFP64-NEXT: [[TMP35:%.*]] = fmul double [[EXT]], [[EXT6]] +// AVRFP64-NEXT: [[TMP36:%.*]] = fsub double [[TMP34]], [[TMP35]] +// AVRFP64-NEXT: [[TMP37:%.*]] = fdiv double [[TMP30]], [[TMP33]] +// AVRFP64-NEXT: [[TMP38:%.*]] = fdiv double [[TMP36]], [[TMP33]] +// AVRFP64-NEXT: [[UNPROMOTION:%.*]] = fptrunc double [[TMP37]] to float +// AVRFP64-NEXT: [[UNPROMOTION7:%.*]] = fptrunc double [[TMP38]] to float +// AVRFP64-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// AVRFP64-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// AVRFP64-NEXT: store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 1 +// AVRFP64-NEXT: store float [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 1 +// AVRFP64-NEXT: [[TMP39:%.*]] = load { float, float }, ptr [[RETVAL]], align 1 +// AVRFP64-NEXT: ret { float, float } [[TMP39]] +// +// BASIC_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @f1( +// BASIC_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x float> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { +// BASIC_FAST-NEXT: entry: +// BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// BASIC_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// BASIC_FAST-NEXT: [[C:%.*]] = alloca { float, float }, align 4 +// BASIC_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// BASIC_FAST-NEXT: store <2 x float> [[C_COERCE]], ptr [[C]], align 4 +// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// BASIC_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 4 +// BASIC_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 4 +// BASIC_FAST-NEXT: [[CONV:%.*]] = fpext float [[C_REAL]] to x86_fp80 +// BASIC_FAST-NEXT: [[CONV1:%.*]] = fpext float [[C_IMAG]] to x86_fp80 +// BASIC_FAST-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[CONV]] +// BASIC_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[CONV1]] +// BASIC_FAST-NEXT: [[TMP2:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP0]], [[TMP1]] +// BASIC_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[CONV]] +// BASIC_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[CONV1]] +// BASIC_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP3]], [[TMP4]] +// BASIC_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[CONV]] +// BASIC_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[CONV1]] +// BASIC_FAST-NEXT: [[TMP8:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP7]] +// BASIC_FAST-NEXT: [[TMP9:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[TMP5]] +// BASIC_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP8]], [[TMP5]] +// BASIC_FAST-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP9]] to float +// BASIC_FAST-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP10]] to float +// BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// BASIC_FAST-NEXT: [[TMP11:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[CONV2]], [[A_REAL]] +// BASIC_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[CONV3]], [[A_IMAG]] +// BASIC_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP11]], [[TMP12]] +// BASIC_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[A_REAL]] +// BASIC_FAST-NEXT: [[TMP15:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[A_IMAG]] +// BASIC_FAST-NEXT: [[TMP16:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP14]], [[TMP15]] +// BASIC_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[CONV3]], [[A_REAL]] +// BASIC_FAST-NEXT: [[TMP18:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[CONV2]], [[A_IMAG]] +// BASIC_FAST-NEXT: [[TMP19:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP17]], [[TMP18]] +// BASIC_FAST-NEXT: [[TMP20:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP13]], [[TMP16]] +// BASIC_FAST-NEXT: [[TMP21:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP19]], [[TMP16]] +// BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// BASIC_FAST-NEXT: store float [[TMP20]], ptr [[RETVAL_REALP]], align 4 +// BASIC_FAST-NEXT: store float [[TMP21]], ptr [[RETVAL_IMAGP]], align 4 +// BASIC_FAST-NEXT: [[TMP22:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// BASIC_FAST-NEXT: ret <2 x float> [[TMP22]] +// +// FULL_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @f1( +// FULL_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x float> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { +// FULL_FAST-NEXT: entry: +// FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: [[C:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 +// FULL_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// FULL_FAST-NEXT: store <2 x float> [[C_COERCE]], ptr [[C]], align 4 +// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// FULL_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// FULL_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// FULL_FAST-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 4 +// FULL_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// FULL_FAST-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 4 +// FULL_FAST-NEXT: [[CONV:%.*]] = fpext float [[C_REAL]] to x86_fp80 +// FULL_FAST-NEXT: [[CONV1:%.*]] = fpext float [[C_IMAG]] to x86_fp80 +// FULL_FAST-NEXT: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__divxc3(x86_fp80 noundef nofpclass(nan inf) [[B_REAL]], x86_fp80 noundef nofpclass(nan inf) [[B_IMAG]], x86_fp80 noundef nofpclass(nan inf) [[CONV]], x86_fp80 noundef nofpclass(nan inf) [[CONV1]]) #[[ATTR2]] +// FULL_FAST-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0 +// FULL_FAST-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1 +// FULL_FAST-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP0]] to float +// FULL_FAST-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP1]] to float +// FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// FULL_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// FULL_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// FULL_FAST-NEXT: [[CALL4:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) <2 x float> @__divsc3(float noundef nofpclass(nan inf) [[CONV2]], float noundef nofpclass(nan inf) [[CONV3]], float noundef nofpclass(nan inf) [[A_REAL]], float noundef nofpclass(nan inf) [[A_IMAG]]) #[[ATTR2]] +// FULL_FAST-NEXT: store <2 x float> [[CALL4]], ptr [[COERCE]], align 4 +// FULL_FAST-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0 +// FULL_FAST-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 +// FULL_FAST-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1 +// FULL_FAST-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 +// FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// FULL_FAST-NEXT: store float [[COERCE_REAL]], ptr [[RETVAL_REALP]], align 4 +// FULL_FAST-NEXT: store float [[COERCE_IMAG]], ptr [[RETVAL_IMAGP]], align 4 +// FULL_FAST-NEXT: [[TMP2:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// FULL_FAST-NEXT: ret <2 x float> [[TMP2]] +// +// IMPRVD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @f1( +// IMPRVD_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x float> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { +// IMPRVD_FAST-NEXT: entry: +// IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// IMPRVD_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// IMPRVD_FAST-NEXT: [[C:%.*]] = alloca { float, float }, align 4 +// IMPRVD_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// IMPRVD_FAST-NEXT: store <2 x float> [[C_COERCE]], ptr [[C]], align 4 +// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// IMPRVD_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 4 +// IMPRVD_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 4 +// IMPRVD_FAST-NEXT: [[CONV:%.*]] = fpext float [[C_REAL]] to x86_fp80 +// IMPRVD_FAST-NEXT: [[CONV1:%.*]] = fpext float [[C_IMAG]] to x86_fp80 +// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) +// IMPRVD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) +// IMPRVD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt x86_fp80 [[TMP0]], [[TMP1]] +// IMPRVD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP2:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[CONV]] +// IMPRVD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[CONV1]] +// IMPRVD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[TMP3]] +// IMPRVD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP2]] +// IMPRVD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP5]] +// IMPRVD_FAST-NEXT: [[TMP7:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP4]] +// IMPRVD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP2]] +// IMPRVD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP8]] +// IMPRVD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP9]], [[TMP4]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi: +// IMPRVD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[CONV1]] +// IMPRVD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP11]], [[CONV]] +// IMPRVD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[TMP12]] +// IMPRVD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP11]] +// IMPRVD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP14]], [[B_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP16:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP15]], [[TMP13]] +// IMPRVD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP11]] +// IMPRVD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP17]], [[B_REAL]] +// IMPRVD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP18]], [[TMP13]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD_FAST: complex_div: +// IMPRVD_FAST-NEXT: [[TMP20:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD_FAST-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP20]] to float +// IMPRVD_FAST-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP21]] to float +// IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// IMPRVD_FAST-NEXT: [[TMP22:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[A_REAL]]) +// IMPRVD_FAST-NEXT: [[TMP23:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[A_IMAG]]) +// IMPRVD_FAST-NEXT: [[ABS_CMP4:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt float [[TMP22]], [[TMP23]] +// IMPRVD_FAST-NEXT: br i1 [[ABS_CMP4]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI5:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI6:%.*]] +// IMPRVD_FAST: abs_rhsr_greater_or_equal_abs_rhsi5: +// IMPRVD_FAST-NEXT: [[TMP24:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[A_REAL]] +// IMPRVD_FAST-NEXT: [[TMP25:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP24]], [[A_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP26:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[TMP25]] +// IMPRVD_FAST-NEXT: [[TMP27:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[CONV3]], [[TMP24]] +// IMPRVD_FAST-NEXT: [[TMP28:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[CONV2]], [[TMP27]] +// IMPRVD_FAST-NEXT: [[TMP29:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP28]], [[TMP26]] +// IMPRVD_FAST-NEXT: [[TMP30:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[CONV2]], [[TMP24]] +// IMPRVD_FAST-NEXT: [[TMP31:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[CONV3]], [[TMP30]] +// IMPRVD_FAST-NEXT: [[TMP32:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP31]], [[TMP26]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV7:%.*]] +// IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi6: +// IMPRVD_FAST-NEXT: [[TMP33:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[A_REAL]], [[A_IMAG]] +// IMPRVD_FAST-NEXT: [[TMP34:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP33]], [[A_REAL]] +// IMPRVD_FAST-NEXT: [[TMP35:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[A_IMAG]], [[TMP34]] +// IMPRVD_FAST-NEXT: [[TMP36:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[CONV2]], [[TMP33]] +// IMPRVD_FAST-NEXT: [[TMP37:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP36]], [[CONV3]] +// IMPRVD_FAST-NEXT: [[TMP38:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP37]], [[TMP35]] +// IMPRVD_FAST-NEXT: [[TMP39:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[CONV3]], [[TMP33]] +// IMPRVD_FAST-NEXT: [[TMP40:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP39]], [[CONV2]] +// IMPRVD_FAST-NEXT: [[TMP41:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP40]], [[TMP35]] +// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV7]] +// IMPRVD_FAST: complex_div7: +// IMPRVD_FAST-NEXT: [[TMP42:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP29]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI5]] ], [ [[TMP38]], [[ABS_RHSR_LESS_THAN_ABS_RHSI6]] ] +// IMPRVD_FAST-NEXT: [[TMP43:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP32]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI5]] ], [ [[TMP41]], [[ABS_RHSR_LESS_THAN_ABS_RHSI6]] ] +// IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD_FAST-NEXT: store float [[TMP42]], ptr [[RETVAL_REALP]], align 4 +// IMPRVD_FAST-NEXT: store float [[TMP43]], ptr [[RETVAL_IMAGP]], align 4 +// IMPRVD_FAST-NEXT: [[TMP44:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// IMPRVD_FAST-NEXT: ret <2 x float> [[TMP44]] +// +// PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x float> @f1( +// PRMTD_FAST-SAME: <2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x float> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { +// PRMTD_FAST-NEXT: entry: +// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// PRMTD_FAST-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// PRMTD_FAST-NEXT: [[C:%.*]] = alloca { float, float }, align 4 +// PRMTD_FAST-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// PRMTD_FAST-NEXT: store <2 x float> [[C_COERCE]], ptr [[C]], align 4 +// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 +// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 +// PRMTD_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[C_REAL:%.*]] = load float, ptr [[C_REALP]], align 4 +// PRMTD_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[C]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[C_IMAG:%.*]] = load float, ptr [[C_IMAGP]], align 4 +// PRMTD_FAST-NEXT: [[CONV:%.*]] = fpext float [[C_REAL]] to x86_fp80 +// PRMTD_FAST-NEXT: [[CONV1:%.*]] = fpext float [[C_IMAG]] to x86_fp80 +// PRMTD_FAST-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) +// PRMTD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) +// PRMTD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt x86_fp80 [[TMP0]], [[TMP1]] +// PRMTD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// PRMTD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: +// PRMTD_FAST-NEXT: [[TMP2:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[CONV]] +// PRMTD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[CONV1]] +// PRMTD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[TMP3]] +// PRMTD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP2]] +// PRMTD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP5]] +// PRMTD_FAST-NEXT: [[TMP7:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP4]] +// PRMTD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP2]] +// PRMTD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP8]] +// PRMTD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP9]], [[TMP4]] +// PRMTD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] +// PRMTD_FAST: abs_rhsr_less_than_abs_rhsi: +// PRMTD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[CONV1]] +// PRMTD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP11]], [[CONV]] +// PRMTD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[TMP12]] +// PRMTD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP11]] +// PRMTD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP14]], [[B_IMAG]] +// PRMTD_FAST-NEXT: [[TMP16:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP15]], [[TMP13]] +// PRMTD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP11]] +// PRMTD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP17]], [[B_REAL]] +// PRMTD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP18]], [[TMP13]] +// PRMTD_FAST-NEXT: br label [[COMPLEX_DIV]] +// PRMTD_FAST: complex_div: +// PRMTD_FAST-NEXT: [[TMP20:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// PRMTD_FAST-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP20]] to float +// PRMTD_FAST-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP21]] to float +// PRMTD_FAST-NEXT: [[EXT:%.*]] = fpext float [[CONV2]] to double +// PRMTD_FAST-NEXT: [[EXT4:%.*]] = fpext float [[CONV3]] to double +// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// PRMTD_FAST-NEXT: [[EXT5:%.*]] = fpext float [[A_REAL]] to double +// PRMTD_FAST-NEXT: [[EXT6:%.*]] = fpext float [[A_IMAG]] to double +// PRMTD_FAST-NEXT: [[TMP22:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT]], [[EXT5]] +// PRMTD_FAST-NEXT: [[TMP23:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT4]], [[EXT6]] +// PRMTD_FAST-NEXT: [[TMP24:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[TMP22]], [[TMP23]] +// PRMTD_FAST-NEXT: [[TMP25:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT5]], [[EXT5]] +// PRMTD_FAST-NEXT: [[TMP26:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT6]], [[EXT6]] +// PRMTD_FAST-NEXT: [[TMP27:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[TMP25]], [[TMP26]] +// PRMTD_FAST-NEXT: [[TMP28:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT4]], [[EXT5]] +// PRMTD_FAST-NEXT: [[TMP29:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[EXT]], [[EXT6]] +// PRMTD_FAST-NEXT: [[TMP30:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[TMP28]], [[TMP29]] +// PRMTD_FAST-NEXT: [[TMP31:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP24]], [[TMP27]] +// PRMTD_FAST-NEXT: [[TMP32:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP30]], [[TMP27]] +// PRMTD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc double [[TMP31]] to float +// PRMTD_FAST-NEXT: [[UNPROMOTION7:%.*]] = fptrunc double [[TMP32]] to float +// PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// PRMTD_FAST-NEXT: store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4 +// PRMTD_FAST-NEXT: store float [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 4 +// PRMTD_FAST-NEXT: [[TMP33:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// PRMTD_FAST-NEXT: ret <2 x float> [[TMP33]] +// +_Complex float f1(_Complex float a, _Complex long double b, _Complex float c) { + return (_Complex float)(b / c) / a; +} diff --git a/clang/test/CodeGen/pragma-cx-limited-range.c b/clang/test/CodeGen/pragma-cx-limited-range.c index 926da8afbee5..68615348c187 100644 --- a/clang/test/CodeGen/pragma-cx-limited-range.c +++ b/clang/test/CodeGen/pragma-cx-limited-range.c @@ -2,20 +2,24 @@ // RUN: -o - | FileCheck %s --check-prefix=FULL // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -complex-range=limited -o - | FileCheck --check-prefix=LMTD %s +// RUN: -complex-range=basic -o - | FileCheck --check-prefix=BASIC %s // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ // RUN: -fno-cx-limited-range -o - | FileCheck %s --check-prefix=FULL // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -complex-range=fortran -o - | FileCheck --check-prefix=FRTRN %s +// RUN: -complex-range=improved -o - | FileCheck --check-prefix=IMPRVD %s // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -fno-cx-fortran-rules -o - | FileCheck --check-prefix=FULL %s +// RUN: -complex-range=promoted -o - | FileCheck --check-prefix=PRMTD %s + +// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ +// RUN: -complex-range=full -o - | FileCheck --check-prefix=FULL %s _Complex float pragma_on_mul(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE ON // LABEL: define {{.*}} @pragma_on_mul( + // FULL: fmul float // FULL-NEXT: fmul float // FULL-NEXT: fmul float @@ -23,19 +27,26 @@ _Complex float pragma_on_mul(_Complex float a, _Complex float b) { // FULL-NEXT: fsub float // FULL-NEXT: fadd float - // LMTD: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fsub float - // LMTD-NEXT: fadd float - - // FRTRN: fmul float - // FRTRN-NEXT: fmul float - // FRTRN-NEXT: fmul float - // FRTRN-NEXT: fmul float - // FRTRN-NEXT: fsub float - // FRTRN-NEXT: fadd float + // BASIC: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fsub float + // BASIC-NEXT: fadd float + + // IMPRVD: fmul float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fsub float + // IMPRVD-NEXT: fadd float + + // PRMTD: fmul float + // PRMTD-NEXT: fmul float + // PRMTD-NEXT: fmul float + // PRMTD-NEXT: fmul float + // PRMTD-NEXT: fsub float + // PRMTD-NEXT: fadd float return a * b; } @@ -43,11 +54,14 @@ _Complex float pragma_on_mul(_Complex float a, _Complex float b) { _Complex float pragma_off_mul(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE OFF // LABEL: define {{.*}} @pragma_off_mul( + // FULL: call {{.*}} @__mulsc3 - // LMTD: call {{.*}} @__mulsc3 + // BASIC: call {{.*}} @__mulsc3 + + // IMPRVD: call {{.*}} @__mulsc3 - // FRTRN: call {{.*}} @__mulsc3 + // PRMTD: call {{.*}} @__mulsc3 return a * b; } @@ -55,6 +69,7 @@ _Complex float pragma_off_mul(_Complex float a, _Complex float b) { _Complex float pragma_on_div(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE ON // LABEL: define {{.*}} @pragma_on_div( + // FULL: fmul float // FULL-NEXT: fmul float // FULL-NEXT: fadd float @@ -67,29 +82,45 @@ _Complex float pragma_on_div(_Complex float a, _Complex float b) { // FULL-NEXT: fdiv float // FULL: fdiv float - // LMTD: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fadd float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fadd float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fmul float - // LMTD-NEXT: fsub float - // LMTD-NEXT: fdiv float - // LMTD-NEXT: fdiv float - - // FRTRN: fmul float - // FRTRN-NEXT: fmul float - // FRTRN-NEXT: fadd float - // FRTRN-NEXT: fmul float - // FRTRN-NEXT: fmul float - // FRTRN-NEXT: fadd float - // FRTRN-NEXT: fmul float - // FRTRN-NEXT: fmul float - // FRTRN-NEXT: fsub float - // FRTRN-NEXT: fdiv float - // FRTRN-NEXT: fdiv float + // BASIC: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fadd float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fadd float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fsub float + // BASIC-NEXT: fdiv float + // BASIC-NEXT: fdiv float + + // IMPRVD: fmul float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fadd float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fadd float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fsub float + // IMPRVD-NEXT: fdiv float + // IMPRVD-NEXT: fdiv float + + // PRMTD: fpext float {{.*}} to double + // PRMTD: fpext float {{.*}} to double + // PRMTD: fmul double + // PRMTD: fmul double + // PRMTD: fadd double + // PRMTD: fmul double + // PRMTD: fmul double + // PRMTD: fadd double + // PRMTD: fmul double + // PRMTD: fmul double + // PRMTD: fsub double + // PRMTD: fdiv double + // PRMTD: fdiv double + // PRMTD: fptrunc double + // PRMTD: fptrunc double return a / b; } @@ -97,11 +128,118 @@ _Complex float pragma_on_div(_Complex float a, _Complex float b) { _Complex float pragma_off_div(_Complex float a, _Complex float b) { #pragma STDC CX_LIMITED_RANGE OFF // LABEL: define {{.*}} @pragma_off_div( + // FULL: call {{.*}} @__divsc3 - // LMTD: call {{.*}} @__divsc3 + // BASIC: call {{.*}} @__divsc3 + + // IMPRVD: call {{.*}} @__divsc3 + + // PRMTD: call {{.*}} @__divdc3 + + return a / b; +} + +_Complex float pragma_default_mul(_Complex float a, _Complex float b) { +#pragma STDC CX_LIMITED_RANGE DEFAULT + // LABEL: define {{.*}} @pragma_on_mul( + + // FULL: fmul float + // FULL-NEXT: fmul float + // FULL-NEXT: fmul float + // FULL-NEXT: fmul float + // FULL-NEXT: fsub float + // FULL-NEXT: fadd float + + // BASIC: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fsub float + // BASIC-NEXT: fadd float + + // IMPRVD: fmul float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fsub float + // IMPRVD-NEXT: fadd float + + // PRMTD: fmul float + // PRMTD-NEXT: fmul float + // PRMTD-NEXT: fmul float + // PRMTD-NEXT: fmul float + // PRMTD-NEXT: fsub float + // PRMTD-NEXT: fadd float + + return a * b; +} +_Complex float pragma_default_div(_Complex float a, _Complex float b) { +#pragma STDC CX_LIMITED_RANGE DEFAULT + // LABEL: define {{.*}} @pragma_on_divx( + + // FULL: call {{.*}} @__divsc3 - // FRTRN: call {{.*}} @__divsc3 + // BASIC: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fadd float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fadd float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fmul float + // BASIC-NEXT: fsub float + // BASIC-NEXT: fdiv float + // BASIC-NEXT: fdiv float + + // IMPRVD: call{{.*}}float @llvm.fabs.f32(float {{.*}}) + // IMPRVD-NEXT: call{{.*}}float @llvm.fabs.f32(float {{.*}}) + // IMPRVD-NEXT: fcmp{{.*}}ugt float {{.*}}, {{.*}} + // IMPRVD-NEXT: br i1 {{.*}}, label + // IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi: + // IMPRVD-NEXT: fdiv float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fadd float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fadd float + // IMPRVD-NEXT: fdiv float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fsub float + // IMPRVD-NEXT: fdiv float + // IMPRVD-NEXT: br label + // IMPRVD: abs_rhsr_less_than_abs_rhsi: + // IMPRVD-NEXT: fdiv float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fadd float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fadd float + // IMPRVD-NEXT: fdiv float + // IMPRVD-NEXT: fmul float + // IMPRVD-NEXT: fsub float + // IMPRVD-NEXT: fdiv float + + // PRMTD: load float, ptr {{.*}} + // PRMTD: fpext float {{.*}} to double + // PRMTD-NEXT: fpext float {{.*}} to double + // PRMTD-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 0 + // PRMTD-NEXT: load float, ptr {{.*}} + // PRMTD-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 1 + // PRMTD-NEXT: load float, ptr {{.*}} + // PRMTD-NEXT: fpext float {{.*}} to double + // PRMTD-NEXT: fpext float {{.*}} to double + // PRMTD-NEXT: fmul double + // PRMTD-NEXT: fmul double + // PRMTD-NEXT: fadd double + // PRMTD-NEXT: fmul double + // PRMTD-NEXT: fmul double + // PRMTD-NEXT: fadd double + // PRMTD-NEXT: fmul double + // PRMTD-NEXT: fmul double + // PRMTD-NEXT: fsub double + // PRMTD-NEXT: fdiv double + // PRMTD-NEXT: fdiv double + // PRMTD-NEXT: fptrunc double {{.*}} to float + // PRMTD-NEXT: fptrunc double {{.*}} to float return a / b; } diff --git a/clang/test/CodeGen/smiths-complex-div.c b/clang/test/CodeGen/smiths-complex-div.c index 75775675c923..5882f8b3545f 100644 --- a/clang/test/CodeGen/smiths-complex-div.c +++ b/clang/test/CodeGen/smiths-complex-div.c @@ -1,58 +1,58 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ -// RUN: -complex-range=fortran -o - | FileCheck %s --check-prefix=FRTRN +// RUN: -complex-range=improved -o - | FileCheck %s --check-prefix=IMPRVD -// FRTRN-LABEL: define dso_local <2 x float> @div( -// FRTRN-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { -// FRTRN-NEXT: entry: -// FRTRN-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 -// FRTRN-NEXT: [[A:%.*]] = alloca { float, float }, align 4 -// FRTRN-NEXT: [[B:%.*]] = alloca { float, float }, align 4 -// FRTRN-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 -// FRTRN-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 -// FRTRN-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 -// FRTRN-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 -// FRTRN-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 -// FRTRN-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 -// FRTRN-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 -// FRTRN-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 -// FRTRN-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 -// FRTRN-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 -// FRTRN-NEXT: [[TMP0:%.*]] = call float @llvm.fabs.f32(float [[B_REAL]]) -// FRTRN-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[B_IMAG]]) -// FRTRN-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP0]], [[TMP1]] -// FRTRN-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] -// FRTRN: abs_rhsr_greater_or_equal_abs_rhsi: -// FRTRN-NEXT: [[TMP2:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]] -// FRTRN-NEXT: [[TMP3:%.*]] = fmul float [[TMP2]], [[B_IMAG]] -// FRTRN-NEXT: [[TMP4:%.*]] = fadd float [[B_REAL]], [[TMP3]] -// FRTRN-NEXT: [[TMP5:%.*]] = fmul float [[A_IMAG]], [[TMP2]] -// FRTRN-NEXT: [[TMP6:%.*]] = fadd float [[A_REAL]], [[TMP5]] -// FRTRN-NEXT: [[TMP7:%.*]] = fdiv float [[TMP6]], [[TMP4]] -// FRTRN-NEXT: [[TMP8:%.*]] = fmul float [[A_REAL]], [[TMP2]] -// FRTRN-NEXT: [[TMP9:%.*]] = fsub float [[A_IMAG]], [[TMP8]] -// FRTRN-NEXT: [[TMP10:%.*]] = fdiv float [[TMP9]], [[TMP4]] -// FRTRN-NEXT: br label [[COMPLEX_DIV:%.*]] -// FRTRN: abs_rhsr_less_than_abs_rhsi: -// FRTRN-NEXT: [[TMP11:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]] -// FRTRN-NEXT: [[TMP12:%.*]] = fmul float [[TMP11]], [[B_REAL]] -// FRTRN-NEXT: [[TMP13:%.*]] = fadd float [[B_IMAG]], [[TMP12]] -// FRTRN-NEXT: [[TMP14:%.*]] = fmul float [[A_REAL]], [[TMP11]] -// FRTRN-NEXT: [[TMP15:%.*]] = fadd float [[TMP14]], [[A_IMAG]] -// FRTRN-NEXT: [[TMP16:%.*]] = fdiv float [[TMP15]], [[TMP13]] -// FRTRN-NEXT: [[TMP17:%.*]] = fmul float [[A_IMAG]], [[TMP11]] -// FRTRN-NEXT: [[TMP18:%.*]] = fsub float [[TMP17]], [[A_REAL]] -// FRTRN-NEXT: [[TMP19:%.*]] = fdiv float [[TMP18]], [[TMP13]] -// FRTRN-NEXT: br label [[COMPLEX_DIV]] -// FRTRN: complex_div: -// FRTRN-NEXT: [[TMP20:%.*]] = phi float [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] -// FRTRN-NEXT: [[TMP21:%.*]] = phi float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] -// FRTRN-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 -// FRTRN-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 -// FRTRN-NEXT: store float [[TMP20]], ptr [[RETVAL_REALP]], align 4 -// FRTRN-NEXT: store float [[TMP21]], ptr [[RETVAL_IMAGP]], align 4 -// FRTRN-NEXT: [[TMP22:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 -// FRTRN-NEXT: ret <2 x float> [[TMP22]] +// IMPRVD-LABEL: define dso_local <2 x float> @div( +// IMPRVD-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// IMPRVD-NEXT: entry: +// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: [[A:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: [[B:%.*]] = alloca { float, float }, align 4 +// IMPRVD-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4 +// IMPRVD-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4 +// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0 +// IMPRVD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4 +// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1 +// IMPRVD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4 +// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0 +// IMPRVD-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4 +// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1 +// IMPRVD-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4 +// IMPRVD-NEXT: [[TMP0:%.*]] = call float @llvm.fabs.f32(float [[B_REAL]]) +// IMPRVD-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[B_IMAG]]) +// IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP0]], [[TMP1]] +// IMPRVD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] +// IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi: +// IMPRVD-NEXT: [[TMP2:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]] +// IMPRVD-NEXT: [[TMP3:%.*]] = fmul float [[TMP2]], [[B_IMAG]] +// IMPRVD-NEXT: [[TMP4:%.*]] = fadd float [[B_REAL]], [[TMP3]] +// IMPRVD-NEXT: [[TMP5:%.*]] = fmul float [[A_IMAG]], [[TMP2]] +// IMPRVD-NEXT: [[TMP6:%.*]] = fadd float [[A_REAL]], [[TMP5]] +// IMPRVD-NEXT: [[TMP7:%.*]] = fdiv float [[TMP6]], [[TMP4]] +// IMPRVD-NEXT: [[TMP8:%.*]] = fmul float [[A_REAL]], [[TMP2]] +// IMPRVD-NEXT: [[TMP9:%.*]] = fsub float [[A_IMAG]], [[TMP8]] +// IMPRVD-NEXT: [[TMP10:%.*]] = fdiv float [[TMP9]], [[TMP4]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV:%.*]] +// IMPRVD: abs_rhsr_less_than_abs_rhsi: +// IMPRVD-NEXT: [[TMP11:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]] +// IMPRVD-NEXT: [[TMP12:%.*]] = fmul float [[TMP11]], [[B_REAL]] +// IMPRVD-NEXT: [[TMP13:%.*]] = fadd float [[B_IMAG]], [[TMP12]] +// IMPRVD-NEXT: [[TMP14:%.*]] = fmul float [[A_REAL]], [[TMP11]] +// IMPRVD-NEXT: [[TMP15:%.*]] = fadd float [[TMP14]], [[A_IMAG]] +// IMPRVD-NEXT: [[TMP16:%.*]] = fdiv float [[TMP15]], [[TMP13]] +// IMPRVD-NEXT: [[TMP17:%.*]] = fmul float [[A_IMAG]], [[TMP11]] +// IMPRVD-NEXT: [[TMP18:%.*]] = fsub float [[TMP17]], [[A_REAL]] +// IMPRVD-NEXT: [[TMP19:%.*]] = fdiv float [[TMP18]], [[TMP13]] +// IMPRVD-NEXT: br label [[COMPLEX_DIV]] +// IMPRVD: complex_div: +// IMPRVD-NEXT: [[TMP20:%.*]] = phi float [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[TMP21:%.*]] = phi float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] +// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// IMPRVD-NEXT: store float [[TMP20]], ptr [[RETVAL_REALP]], align 4 +// IMPRVD-NEXT: store float [[TMP21]], ptr [[RETVAL_IMAGP]], align 4 +// IMPRVD-NEXT: [[TMP22:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// IMPRVD-NEXT: ret <2 x float> [[TMP22]] // _Complex float div(_Complex float a, _Complex float b) { return a / b; diff --git a/clang/test/Driver/range.c b/clang/test/Driver/range.c index 2d1fd7f9f1a9..da5748d7c723 100644 --- a/clang/test/Driver/range.c +++ b/clang/test/Driver/range.c @@ -1,16 +1,37 @@ // Test range options for complex multiplication and division. // RUN: %clang -### -target x86_64 -fcx-limited-range -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=LMTD %s +// RUN: | FileCheck --check-prefix=BASIC %s // RUN: %clang -### -target x86_64 -fno-cx-limited-range -c %s 2>&1 \ -// RUN: | FileCheck %s +// RUN: | FileCheck --check-prefix=FULL %s + +// RUN: %clang -### -target x86_64 -fcx-limited-range -fcx-fortran-rules \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=WARN1 %s + +// RUN: %clang -### -target x86_64 -fno-cx-limited-range -fcx-fortran-rules \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=WARN2 %s // RUN: %clang -### -target x86_64 -fcx-limited-range -fno-cx-limited-range \ // RUN: -c %s 2>&1 | FileCheck --check-prefix=FULL %s +// RUN: %clang -### -target x86_64 -fno-cx-limited-range -fcx-limited-range \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=BASIC %s + +// RUN: %clang -### -target x86_64 -fno-cx-limited-range -fno-cx-fortran-rules \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=FULL %s + +// RUN: %clang -### -target x86_64 -fno-cx-fortran-rules -fno-cx-limited-range \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=FULL %s + +// RUN: %clang -### -target x86_64 -fcx-limited-range -fno-cx-fortran-rules \ +// RUN: -c %s 2>&1 | FileCheck --check-prefix=WARN4 %s + // RUN: %clang -### -target x86_64 -fcx-fortran-rules -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=FRTRN %s +// RUN: | FileCheck --check-prefix=IMPRVD %s + +// RUN: %clang -### -target x86_64 -fno-cx-fortran-rules -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=FULL %s // RUN: %clang -### -target x86_64 -fcx-fortran-rules -c %s 2>&1 \ // RUN: -fno-cx-fortran-rules | FileCheck --check-prefix=FULL %s @@ -32,34 +53,148 @@ // RUN: %clang -### -target x86_64 -fcx-fortran-rules \ // RUN: -fcx-limited-range -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=WARN2 %s +// RUN: | FileCheck --check-prefix=WARN20 %s // RUN: %clang -### -target x86_64 -ffast-math -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=LMTD %s +// RUN: | FileCheck --check-prefix=BASIC %s // RUN: %clang -### -target x86_64 -ffast-math -fcx-limited-range -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=LMTD %s +// RUN: | FileCheck --check-prefix=BASIC %s // RUN: %clang -### -target x86_64 -fcx-limited-range -ffast-math -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=LMTD %s +// RUN: | FileCheck --check-prefix=BASIC %s // RUN: %clang -### -target x86_64 -ffast-math -fno-cx-limited-range \ // RUN: -c %s 2>&1 | FileCheck --check-prefix=FULL %s +// RUN: not %clang -### -target x86_64 -fcomplex-arithmetic=foo -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=ERR %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=basic -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=BASIC %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=improved -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=IMPRVD %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=promoted -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=PRMTD %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=full -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=FULL %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=basic \ +// RUN: -fcx-limited-range -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=BASIC %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=basic \ +// RUN: -fcomplex-arithmetic=improved -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=IMPRVD %s + +// RUN: %clang -### -target x86_64 -fcx-limited-range \ +// RUN: -fcomplex-arithmetic=improved -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN6 %s + +// RUN: %clang -### -target x86_64 -fcx-fortran-rules \ +// RUN: -fcomplex-arithmetic=basic -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN7 %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=basic \ +// RUN: -fcomplex-arithmetic=full -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=FULL %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=basic \ +// RUN: -fcomplex-arithmetic=promoted -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=PRMTD %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=improved \ +// RUN: -fcomplex-arithmetic=basic -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=BASIC %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=improved \ +// RUN: -fcomplex-arithmetic=full -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=FULL %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=improved \ +// RUN: -fcomplex-arithmetic=promoted -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=PRMTD %s + + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=promoted \ +// RUN: -fcomplex-arithmetic=basic -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=BASIC %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=promoted \ +// RUN: -fcx-limited-range -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=WARN14 %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=promoted \ +// RUN: -fcomplex-arithmetic=improved -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=IMPRVD %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=promoted \ +// RUN: -fcomplex-arithmetic=full -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=FULL %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=full \ +// RUN: -fcomplex-arithmetic=basic -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=BASIC %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=full \ +// RUN: -ffast-math -c %s 2>&1 | FileCheck --check-prefix=WARN17 %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=full \ +// RUN: -fcomplex-arithmetic=improved -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=IMPRVD %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=full \ +// RUN: -fcomplex-arithmetic=promoted -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=PRMTD %s + +// RUN: %clang -### -target x86_64 -ffast-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=BASIC %s + +// RUN: %clang -### -target x86_64 -ffast-math -fcx-limited-range -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=BASIC %s + +// RUN: %clang -### -target x86_64 -fcx-limited-range -ffast-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=BASIC %s + +// RUN: %clang -### -target x86_64 -ffast-math -fno-cx-limited-range -c %s \ +// RUN: 2>&1 | FileCheck --check-prefix=FULL %s + +// RUN: %clang -### -target x86_64 -ffast-math -fcomplex-arithmetic=basic -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=BASIC %s + +// RUN: %clang -### -target x86_64 -fcomplex-arithmetic=basic -ffast-math -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=BASIC %s + // RUN: %clang -### -Werror -target x86_64 -fcx-limited-range -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=LMTD %s +// RUN: | FileCheck --check-prefix=BASIC %s + +// RUN: %clang -### -target x86_64 -ffast-math -fcomplex-arithmetic=full -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=FULL %s -// RUN: %clang -### -Werror -target x86_64 -fcx-fortran-rules -c %s 2>&1 \ -// RUN: | FileCheck --check-prefix=FRTRN %s +// RUN: %clang -### -target x86_64 -ffast-math -fcomplex-arithmetic=basic -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=BASIC %s -// LMTD: -complex-range=limited +// BASIC: -complex-range=basic // FULL: -complex-range=full -// LMTD-NOT: -complex-range=fortran -// CHECK-NOT: -complex-range=limited -// FRTRN: -complex-range=fortran -// FRTRN-NOT: -complex-range=limited -// CHECK-NOT: -complex-range=fortran +// PRMTD: -complex-range=promoted +// BASIC-NOT: -complex-range=improved +// CHECK-NOT: -complex-range=basic +// IMPRVD: -complex-range=improved +// IMPRVD-NOT: -complex-range=basic +// CHECK-NOT: -complex-range=improved + // WARN1: warning: overriding '-fcx-limited-range' option with '-fcx-fortran-rules' [-Woverriding-option] -// WARN2: warning: overriding '-fcx-fortran-rules' option with '-fcx-limited-range' [-Woverriding-option] +// WARN2: warning: overriding '-fno-cx-limited-range' option with '-fcx-fortran-rules' [-Woverriding-option] // WARN3: warning: overriding '-fcx-fortran-rules' option with '-fno-cx-limited-range' [-Woverriding-option] // WARN4: warning: overriding '-fcx-limited-range' option with '-fno-cx-fortran-rules' [-Woverriding-option] +// WARN5: warning: overriding '-fcomplex-arithmetic=basic' option with '-fcomplex-arithmetic=improved' [-Woverriding-option] +// WARN6: warning: overriding '-fcx-limited-range' option with '-fcomplex-arithmetic=improved' [-Woverriding-option] +// WARN7: warning: overriding '-fcx-fortran-rules' option with '-fcomplex-arithmetic=basic' [-Woverriding-option] +// WARN14: overriding '-complex-range=promoted' option with '-fcx-limited-range' [-Woverriding-option] +// WARN17: warning: overriding '-fcomplex-arithmetic=full' option with '-fcomplex-arithmetic=basic' [-Woverriding-option] +// WARN20: warning: overriding '-fcx-fortran-rules' option with '-fcx-limited-range' [-Woverriding-option] + +// ERR: error: unsupported argument 'foo' to option '-fcomplex-arithmetic=' -- GitLab From 0177a9547e588222acaf6d006747b5f7014e6fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Clement=20=28=E3=83=90=E3=83=AC=E3=83=B3?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=B3=20=E3=82=AF=E3=83=AC=E3=83=A1?= =?UTF-8?q?=E3=83=B3=29?= <clementval@gmail.com> Date: Wed, 20 Mar 2024 12:58:11 -0700 Subject: [PATCH 301/307] [flang][cuda] Fix fir.cuda_kernel_launch assembly with no args (#85987) When the kernel launch has no arguments, the generated parser was expecting at least a type to be present. Make the last part of the assemble format optional. Add a run line to round-trip the output through fir-opt so we make sure the IR can be parsed and printed correctly. --- flang/include/flang/Optimizer/Dialect/FIROps.td | 2 +- flang/test/Lower/CUDA/cuda-kernel-calls.cuf | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index 8a7e36e42457..b991ec76fdd9 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -2466,7 +2466,7 @@ def fir_CUDAKernelLaunch : fir_Op<"cuda_kernel_launch", [CallOpInterface, let assemblyFormat = [{ $callee `<` `<` `<` $grid_x `,` $grid_y `,` $grid_z `,`$block_x `,` $block_y `,` $block_z ( `,` $bytes^ ( `,` $stream^ )? )? `>` `>` `>` - `` `(` $args `)` `:` `(` type($args) `)` attr-dict + `` `(` $args `)` ( `:` `(` type($args)^ `)` )? attr-dict }]; let extraClassDeclaration = [{ diff --git a/flang/test/Lower/CUDA/cuda-kernel-calls.cuf b/flang/test/Lower/CUDA/cuda-kernel-calls.cuf index f4327b326175..7e28fbb2231a 100644 --- a/flang/test/Lower/CUDA/cuda-kernel-calls.cuf +++ b/flang/test/Lower/CUDA/cuda-kernel-calls.cuf @@ -1,4 +1,5 @@ ! RUN: bbc -emit-hlfir -fcuda %s -o - | FileCheck %s +! RUN: bbc -emit-hlfir -fcuda %s -o - | fir-opt | FileCheck %s ! Test lowering of CUDA procedure calls. -- GitLab From 84115494d6475e1aea3cdd1163d3a88243b75f36 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <Krzysztof.Parzyszek@amd.com> Date: Wed, 20 Mar 2024 15:00:29 -0500 Subject: [PATCH 302/307] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr (#81626) The related functions are `gatherDataOperandAddrAndBounds` and `genBoundsOps`. The former is used in OpenACC as well, and it was updated to pass evaluate::Expr instead of parser objects. The difference in the test case comes from unfolded conversions of index expressions, which are explicitly of type integer(kind=8). Delete now unused `findRepeatableClause2` and `findClause2`. Add `AsGenericExpr` that takes std::optional. It already returns optional Expr. Making it accept an optional Expr as input would reduce the number of necessary checks when handling frequent optional values in evaluator. [Clause representation 4/6] --- flang/include/flang/Evaluate/tools.h | 8 + flang/lib/Lower/DirectivesCommon.h | 389 ++++++++++++-------- flang/lib/Lower/OpenACC.cpp | 54 ++- flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 44 +-- flang/lib/Lower/OpenMP/ClauseProcessor.h | 59 +-- flang/lib/Lower/OpenMP/OpenMP.cpp | 7 +- flang/test/Lower/OpenACC/acc-bounds.f90 | 2 +- flang/test/Lower/OpenACC/acc-enter-data.f90 | 40 +- 8 files changed, 335 insertions(+), 268 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index 9a32062440ab..8c872a0579c8 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -148,6 +148,14 @@ inline Expr<SomeType> AsGenericExpr(Expr<SomeType> &&x) { return std::move(x); } std::optional<Expr<SomeType>> AsGenericExpr(DataRef &&); std::optional<Expr<SomeType>> AsGenericExpr(const Symbol &); +// Propagate std::optional from input to output. +template <typename A> +std::optional<Expr<SomeType>> AsGenericExpr(std::optional<A> &&x) { + if (!x) + return std::nullopt; + return AsGenericExpr(std::move(*x)); +} + template <typename A> common::IfNoLvalue<Expr<SomeKind<ResultType<A>::category>>, A> AsCategoryExpr( A &&x) { diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h index 8d560db34e05..6daa72b84d90 100644 --- a/flang/lib/Lower/DirectivesCommon.h +++ b/flang/lib/Lower/DirectivesCommon.h @@ -808,6 +808,75 @@ genBaseBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, return bounds; } +namespace detail { +template <typename T> // +static T &&AsRvalueRef(T &&t) { + return std::move(t); +} +template <typename T> // +static T AsRvalueRef(T &t) { + return t; +} +template <typename T> // +static T AsRvalueRef(const T &t) { + return t; +} + +// Helper class for stripping enclosing parentheses and a conversion that +// preserves type category. This is used for triplet elements, which are +// always of type integer(kind=8). The lower/upper bounds are converted to +// an "index" type, which is 64-bit, so the explicit conversion to kind=8 +// (if present) is not needed. When it's present, though, it causes generated +// names to contain "int(..., kind=8)". +struct PeelConvert { + template <Fortran::common::TypeCategory Category, int Kind> + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Expr<Fortran::evaluate::Type<Category, Kind>> + &expr) { + return std::visit( + [](auto &&s) { return visit_with_category<Category, Kind>(s); }, + expr.u); + } + template <Fortran::common::TypeCategory Category, int Kind> + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Convert<Fortran::evaluate::Type<Category, Kind>, + Category> &expr) { + return AsGenericExpr(AsRvalueRef(expr.left())); + } + template <Fortran::common::TypeCategory Category, int Kind, typename T> + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { + return std::nullopt; // + } + template <Fortran::common::TypeCategory Category, typename T> + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { + return std::nullopt; // + } + + template <Fortran::common::TypeCategory Category> + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr<Fortran::evaluate::SomeKind<Category>> + &expr) { + return std::visit([](auto &&s) { return visit_with_category<Category>(s); }, + expr.u); + } + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &expr) { + return std::visit([](auto &&s) { return visit(s); }, expr.u); + } + template <typename T> // + static Fortran::semantics::MaybeExpr visit(const T &) { + return std::nullopt; + } +}; + +static Fortran::semantics::SomeExpr +peelOuterConvert(Fortran::semantics::SomeExpr &expr) { + if (auto peeled = PeelConvert::visit(expr)) + return *peeled; + return expr; +} +} // namespace detail + /// Generate bounds operations for an array section when subscripts are /// provided. template <typename BoundsOp, typename BoundsType> @@ -815,7 +884,7 @@ llvm::SmallVector<mlir::Value> genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, Fortran::lower::AbstractConverter &converter, Fortran::lower::StatementContext &stmtCtx, - const std::list<Fortran::parser::SectionSubscript> &subscripts, + const std::vector<Fortran::evaluate::Subscript> &subscripts, std::stringstream &asFortran, fir::ExtendedValue &dataExv, bool dataExvIsAssumedSize, AddrAndBoundsInfo &info, bool treatIndexAsSection = false) { @@ -828,8 +897,7 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1); const int dataExvRank = static_cast<int>(dataExv.rank()); for (const auto &subscript : subscripts) { - const auto *triplet{ - std::get_if<Fortran::parser::SubscriptTriplet>(&subscript.u)}; + const auto *triplet{std::get_if<Fortran::evaluate::Triplet>(&subscript.u)}; if (triplet || treatIndexAsSection) { if (dimension != 0) asFortran << ','; @@ -868,13 +936,17 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, strideInBytes = true; } - const Fortran::lower::SomeExpr *lower{nullptr}; + Fortran::semantics::MaybeExpr lower; if (triplet) { - if (const auto &tripletLb{std::get<0>(triplet->t)}) - lower = Fortran::semantics::GetExpr(*tripletLb); + lower = Fortran::evaluate::AsGenericExpr(triplet->lower()); } else { - const auto &index{std::get<Fortran::parser::IntExpr>(subscript.u)}; - lower = Fortran::semantics::GetExpr(index); + // Case of IndirectSubscriptIntegerExpr + using IndirectSubscriptIntegerExpr = + Fortran::evaluate::IndirectSubscriptIntegerExpr; + using SubscriptInteger = Fortran::evaluate::SubscriptInteger; + Fortran::evaluate::Expr<SubscriptInteger> oneInt = + std::get<IndirectSubscriptIntegerExpr>(subscript.u).value(); + lower = Fortran::evaluate::AsGenericExpr(std::move(oneInt)); if (lower->Rank() > 0) { mlir::emitError( loc, "vector subscript cannot be used for an array section"); @@ -896,7 +968,7 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, fir::getBase(converter.genExprValue(loc, *lower, stmtCtx)); lb = builder.createConvert(loc, baseLb.getType(), lb); lbound = builder.create<mlir::arith::SubIOp>(loc, lb, baseLb); - asFortran << lower->AsFortran(); + asFortran << detail::peelOuterConvert(*lower).AsFortran(); } } else { // If the lower bound is not specified, then the section @@ -912,10 +984,11 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, extent = one; } else { asFortran << ':'; - const auto &upper{std::get<1>(triplet->t)}; + Fortran::semantics::MaybeExpr upper = + Fortran::evaluate::AsGenericExpr(triplet->upper()); if (upper) { - uval = Fortran::semantics::GetIntValue(upper); + uval = Fortran::evaluate::ToInt64(*upper); if (uval) { if (defaultLb) { ubound = builder.createIntegerConstant(loc, idxTy, *uval - 1); @@ -925,22 +998,21 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, } asFortran << *uval; } else { - const Fortran::lower::SomeExpr *uexpr = - Fortran::semantics::GetExpr(*upper); mlir::Value ub = - fir::getBase(converter.genExprValue(loc, *uexpr, stmtCtx)); + fir::getBase(converter.genExprValue(loc, *upper, stmtCtx)); ub = builder.createConvert(loc, baseLb.getType(), ub); ubound = builder.create<mlir::arith::SubIOp>(loc, ub, baseLb); - asFortran << uexpr->AsFortran(); + asFortran << detail::peelOuterConvert(*upper).AsFortran(); } } if (lower && upper) { if (lval && uval && *uval < *lval) { mlir::emitError(loc, "zero sized array section"); break; - } else if (std::get<2>(triplet->t)) { - const auto &strideExpr{std::get<2>(triplet->t)}; - if (strideExpr) { + } else { + // Stride is mandatory in evaluate::Triplet. Make sure it's 1. + auto val = Fortran::evaluate::ToInt64(triplet->GetStride()); + if (!val || *val != 1) { mlir::emitError(loc, "stride cannot be specified on " "an array section"); break; @@ -993,150 +1065,157 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, return bounds; } -template <typename ObjectType, typename BoundsOp, typename BoundsType> +namespace detail { +template <typename Ref, typename Expr> // +std::optional<Ref> getRef(Expr &&expr) { + if constexpr (std::is_same_v<llvm::remove_cvref_t<Expr>, + Fortran::evaluate::DataRef>) { + if (auto *ref = std::get_if<Ref>(&expr.u)) + return *ref; + return std::nullopt; + } else { + auto maybeRef = Fortran::evaluate::ExtractDataRef(expr); + if (!maybeRef || !std::holds_alternative<Ref>(maybeRef->u)) + return std::nullopt; + return std::get<Ref>(maybeRef->u); + } +} +} // namespace detail + +template <typename BoundsOp, typename BoundsType> AddrAndBoundsInfo gatherDataOperandAddrAndBounds( Fortran::lower::AbstractConverter &converter, fir::FirOpBuilder &builder, - Fortran::semantics::SemanticsContext &semanticsContext, - Fortran::lower::StatementContext &stmtCtx, const ObjectType &object, + semantics::SemanticsContext &semaCtx, + Fortran::lower::StatementContext &stmtCtx, + Fortran::semantics::SymbolRef symbol, + const Fortran::semantics::MaybeExpr &maybeDesignator, mlir::Location operandLocation, std::stringstream &asFortran, llvm::SmallVector<mlir::Value> &bounds, bool treatIndexAsSection = false) { + using namespace Fortran; + AddrAndBoundsInfo info; - std::visit( - Fortran::common::visitors{ - [&](const Fortran::parser::Designator &designator) { - if (auto expr{Fortran::semantics::AnalyzeExpr(semanticsContext, - designator)}) { - if (((*expr).Rank() > 0 || treatIndexAsSection) && - Fortran::parser::Unwrap<Fortran::parser::ArrayElement>( - designator)) { - const auto *arrayElement = - Fortran::parser::Unwrap<Fortran::parser::ArrayElement>( - designator); - const auto *dataRef = - std::get_if<Fortran::parser::DataRef>(&designator.u); - fir::ExtendedValue dataExv; - bool dataExvIsAssumedSize = false; - if (Fortran::parser::Unwrap< - Fortran::parser::StructureComponent>( - arrayElement->base)) { - auto exprBase = Fortran::semantics::AnalyzeExpr( - semanticsContext, arrayElement->base); - dataExv = converter.genExprAddr(operandLocation, *exprBase, - stmtCtx); - info.addr = fir::getBase(dataExv); - info.rawInput = info.addr; - asFortran << (*exprBase).AsFortran(); - } else { - const Fortran::parser::Name &name = - Fortran::parser::GetLastName(*dataRef); - dataExvIsAssumedSize = Fortran::semantics::IsAssumedSizeArray( - name.symbol->GetUltimate()); - info = getDataOperandBaseAddr(converter, builder, - *name.symbol, operandLocation); - dataExv = converter.getSymbolExtendedValue(*name.symbol); - asFortran << name.ToString(); - } - - if (!arrayElement->subscripts.empty()) { - asFortran << '('; - bounds = genBoundsOps<BoundsOp, BoundsType>( - builder, operandLocation, converter, stmtCtx, - arrayElement->subscripts, asFortran, dataExv, - dataExvIsAssumedSize, info, treatIndexAsSection); - } - asFortran << ')'; - } else if (auto structComp = Fortran::parser::Unwrap< - Fortran::parser::StructureComponent>(designator)) { - fir::ExtendedValue compExv = - converter.genExprAddr(operandLocation, *expr, stmtCtx); - info.addr = fir::getBase(compExv); - info.rawInput = info.addr; - if (fir::unwrapRefType(info.addr.getType()) - .isa<fir::SequenceType>()) - bounds = genBaseBoundsOps<BoundsOp, BoundsType>( - builder, operandLocation, converter, compExv, - /*isAssumedSize=*/false); - asFortran << (*expr).AsFortran(); - - bool isOptional = Fortran::semantics::IsOptional( - *Fortran::parser::GetLastName(*structComp).symbol); - if (isOptional) - info.isPresent = builder.create<fir::IsPresentOp>( - operandLocation, builder.getI1Type(), info.rawInput); - - if (auto loadOp = mlir::dyn_cast_or_null<fir::LoadOp>( - info.addr.getDefiningOp())) { - if (fir::isAllocatableType(loadOp.getType()) || - fir::isPointerType(loadOp.getType())) - info.addr = builder.create<fir::BoxAddrOp>(operandLocation, - info.addr); - info.rawInput = info.addr; - } - - // If the component is an allocatable or pointer the result of - // genExprAddr will be the result of a fir.box_addr operation or - // a fir.box_addr has been inserted just before. - // Retrieve the box so we handle it like other descriptor. - if (auto boxAddrOp = mlir::dyn_cast_or_null<fir::BoxAddrOp>( - info.addr.getDefiningOp())) { - info.addr = boxAddrOp.getVal(); - info.rawInput = info.addr; - bounds = genBoundsOpsFromBox<BoundsOp, BoundsType>( - builder, operandLocation, converter, compExv, info); - } - } else { - if (Fortran::parser::Unwrap<Fortran::parser::ArrayElement>( - designator)) { - // Single array element. - const auto *arrayElement = - Fortran::parser::Unwrap<Fortran::parser::ArrayElement>( - designator); - (void)arrayElement; - fir::ExtendedValue compExv = - converter.genExprAddr(operandLocation, *expr, stmtCtx); - info.addr = fir::getBase(compExv); - info.rawInput = info.addr; - asFortran << (*expr).AsFortran(); - } else if (const auto *dataRef{ - std::get_if<Fortran::parser::DataRef>( - &designator.u)}) { - // Scalar or full array. - const Fortran::parser::Name &name = - Fortran::parser::GetLastName(*dataRef); - fir::ExtendedValue dataExv = - converter.getSymbolExtendedValue(*name.symbol); - info = getDataOperandBaseAddr(converter, builder, - *name.symbol, operandLocation); - if (fir::unwrapRefType(info.addr.getType()) - .isa<fir::BaseBoxType>()) { - bounds = genBoundsOpsFromBox<BoundsOp, BoundsType>( - builder, operandLocation, converter, dataExv, info); - } - bool dataExvIsAssumedSize = - Fortran::semantics::IsAssumedSizeArray( - name.symbol->GetUltimate()); - if (fir::unwrapRefType(info.addr.getType()) - .isa<fir::SequenceType>()) - bounds = genBaseBoundsOps<BoundsOp, BoundsType>( - builder, operandLocation, converter, dataExv, - dataExvIsAssumedSize); - asFortran << name.ToString(); - } else { // Unsupported - llvm::report_fatal_error( - "Unsupported type of OpenACC operand"); - } - } - } - }, - [&](const Fortran::parser::Name &name) { - info = getDataOperandBaseAddr(converter, builder, *name.symbol, - operandLocation); - asFortran << name.ToString(); - }}, - object.u); + + if (!maybeDesignator) { + info = getDataOperandBaseAddr(converter, builder, symbol, operandLocation); + asFortran << symbol->name().ToString(); + return info; + } + + semantics::SomeExpr designator = *maybeDesignator; + + if ((designator.Rank() > 0 || treatIndexAsSection) && + IsArrayElement(designator)) { + auto arrayRef = detail::getRef<evaluate::ArrayRef>(designator); + // This shouldn't fail after IsArrayElement(designator). + assert(arrayRef && "Expecting ArrayRef"); + + fir::ExtendedValue dataExv; + bool dataExvIsAssumedSize = false; + + auto toMaybeExpr = [&](auto &&base) { + using BaseType = llvm::remove_cvref_t<decltype(base)>; + evaluate::ExpressionAnalyzer ea{semaCtx}; + + if constexpr (std::is_same_v<evaluate::NamedEntity, BaseType>) { + if (auto *ref = base.UnwrapSymbolRef()) + return ea.Designate(evaluate::DataRef{*ref}); + if (auto *ref = base.UnwrapComponent()) + return ea.Designate(evaluate::DataRef{*ref}); + llvm_unreachable("Unexpected NamedEntity"); + } else { + static_assert(std::is_same_v<semantics::SymbolRef, BaseType>); + return ea.Designate(evaluate::DataRef{base}); + } + }; + + auto arrayBase = toMaybeExpr(arrayRef->base()); + assert(arrayBase); + + if (detail::getRef<evaluate::Component>(*arrayBase)) { + dataExv = converter.genExprAddr(operandLocation, *arrayBase, stmtCtx); + info.addr = fir::getBase(dataExv); + info.rawInput = info.addr; + asFortran << arrayBase->AsFortran(); + } else { + const semantics::Symbol &sym = arrayRef->GetLastSymbol(); + dataExvIsAssumedSize = + Fortran::semantics::IsAssumedSizeArray(sym.GetUltimate()); + info = getDataOperandBaseAddr(converter, builder, sym, operandLocation); + dataExv = converter.getSymbolExtendedValue(sym); + asFortran << sym.name().ToString(); + } + + if (!arrayRef->subscript().empty()) { + asFortran << '('; + bounds = genBoundsOps<BoundsOp, BoundsType>( + builder, operandLocation, converter, stmtCtx, arrayRef->subscript(), + asFortran, dataExv, dataExvIsAssumedSize, info, treatIndexAsSection); + } + asFortran << ')'; + } else if (auto compRef = detail::getRef<evaluate::Component>(designator)) { + fir::ExtendedValue compExv = + converter.genExprAddr(operandLocation, designator, stmtCtx); + info.addr = fir::getBase(compExv); + info.rawInput = info.addr; + if (fir::unwrapRefType(info.addr.getType()).isa<fir::SequenceType>()) + bounds = genBaseBoundsOps<BoundsOp, BoundsType>(builder, operandLocation, + converter, compExv, + /*isAssumedSize=*/false); + asFortran << designator.AsFortran(); + + if (semantics::IsOptional(compRef->GetLastSymbol())) { + info.isPresent = builder.create<fir::IsPresentOp>( + operandLocation, builder.getI1Type(), info.rawInput); + } + + if (auto loadOp = + mlir::dyn_cast_or_null<fir::LoadOp>(info.addr.getDefiningOp())) { + if (fir::isAllocatableType(loadOp.getType()) || + fir::isPointerType(loadOp.getType())) + info.addr = builder.create<fir::BoxAddrOp>(operandLocation, info.addr); + info.rawInput = info.addr; + } + + // If the component is an allocatable or pointer the result of + // genExprAddr will be the result of a fir.box_addr operation or + // a fir.box_addr has been inserted just before. + // Retrieve the box so we handle it like other descriptor. + if (auto boxAddrOp = + mlir::dyn_cast_or_null<fir::BoxAddrOp>(info.addr.getDefiningOp())) { + info.addr = boxAddrOp.getVal(); + info.rawInput = info.addr; + bounds = genBoundsOpsFromBox<BoundsOp, BoundsType>( + builder, operandLocation, converter, compExv, info); + } + } else { + if (detail::getRef<evaluate::ArrayRef>(designator)) { + fir::ExtendedValue compExv = + converter.genExprAddr(operandLocation, designator, stmtCtx); + info.addr = fir::getBase(compExv); + info.rawInput = info.addr; + asFortran << designator.AsFortran(); + } else if (auto symRef = detail::getRef<semantics::SymbolRef>(designator)) { + // Scalar or full array. + fir::ExtendedValue dataExv = converter.getSymbolExtendedValue(*symRef); + info = + getDataOperandBaseAddr(converter, builder, *symRef, operandLocation); + if (fir::unwrapRefType(info.addr.getType()).isa<fir::BaseBoxType>()) { + bounds = genBoundsOpsFromBox<BoundsOp, BoundsType>( + builder, operandLocation, converter, dataExv, info); + } + bool dataExvIsAssumedSize = + Fortran::semantics::IsAssumedSizeArray(symRef->get().GetUltimate()); + if (fir::unwrapRefType(info.addr.getType()).isa<fir::SequenceType>()) + bounds = genBaseBoundsOps<BoundsOp, BoundsType>( + builder, operandLocation, converter, dataExv, dataExvIsAssumedSize); + asFortran << symRef->get().name().ToString(); + } else { // Unsupported + llvm::report_fatal_error("Unsupported type of OpenACC operand"); + } + } + return info; } - } // namespace lower } // namespace Fortran diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 6539de4d8830..7b7e4a875cd8 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -269,6 +269,11 @@ getSymbolFromAccObject(const Fortran::parser::AccObject &accObject) { Fortran::parser::GetLastName(arrayElement->base); return *name.symbol; } + if (const auto *component = + Fortran::parser::Unwrap<Fortran::parser::StructureComponent>( + *designator)) { + return *component->component.symbol; + } } else if (const auto *name = std::get_if<Fortran::parser::Name>(&accObject.u)) { return *name->symbol; @@ -286,17 +291,20 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, mlir::acc::DataClause dataClause, bool structured, bool implicit, bool setDeclareAttr = false) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + Fortran::evaluate::ExpressionAnalyzer ea{semanticsContext}; for (const auto &accObject : objectList.v) { llvm::SmallVector<mlir::Value> bounds; std::stringstream asFortran; mlir::Location operandLocation = genOperandLocation(converter, accObject); + Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject); + Fortran::semantics::MaybeExpr designator = + std::visit([&](auto &&s) { return ea.Analyze(s); }, accObject.u); Fortran::lower::AddrAndBoundsInfo info = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::AccObject, mlir::acc::DataBoundsOp, - mlir::acc::DataBoundsType>(converter, builder, semanticsContext, - stmtCtx, accObject, operandLocation, - asFortran, bounds, - /*treatIndexAsSection=*/true); + mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>( + converter, builder, semanticsContext, stmtCtx, symbol, designator, + operandLocation, asFortran, bounds, + /*treatIndexAsSection=*/true); // If the input value is optional and is not a descriptor, we use the // rawInput directly. @@ -321,16 +329,19 @@ static void genDeclareDataOperandOperations( llvm::SmallVectorImpl<mlir::Value> &dataOperands, mlir::acc::DataClause dataClause, bool structured, bool implicit) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + Fortran::evaluate::ExpressionAnalyzer ea{semanticsContext}; for (const auto &accObject : objectList.v) { llvm::SmallVector<mlir::Value> bounds; std::stringstream asFortran; mlir::Location operandLocation = genOperandLocation(converter, accObject); + Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject); + Fortran::semantics::MaybeExpr designator = + std::visit([&](auto &&s) { return ea.Analyze(s); }, accObject.u); Fortran::lower::AddrAndBoundsInfo info = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::AccObject, mlir::acc::DataBoundsOp, - mlir::acc::DataBoundsType>(converter, builder, semanticsContext, - stmtCtx, accObject, operandLocation, - asFortran, bounds); + mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>( + converter, builder, semanticsContext, stmtCtx, symbol, designator, + operandLocation, asFortran, bounds); EntryOp op = createDataEntryOp<EntryOp>( builder, operandLocation, info.addr, asFortran, bounds, structured, implicit, dataClause, info.addr.getType()); @@ -339,8 +350,7 @@ static void genDeclareDataOperandOperations( if (mlir::isa<fir::BaseBoxType>(fir::unwrapRefType(info.addr.getType()))) { mlir::OpBuilder modBuilder(builder.getModule().getBodyRegion()); modBuilder.setInsertionPointAfter(builder.getFunction()); - std::string prefix = - converter.mangleName(getSymbolFromAccObject(accObject)); + std::string prefix = converter.mangleName(symbol); createDeclareAllocFuncWithArg<EntryOp>( modBuilder, builder, operandLocation, info.addr.getType(), prefix, asFortran, dataClause); @@ -770,16 +780,19 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList, llvm::SmallVectorImpl<mlir::Value> &dataOperands, llvm::SmallVector<mlir::Attribute> &privatizations) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + Fortran::evaluate::ExpressionAnalyzer ea{semanticsContext}; for (const auto &accObject : objectList.v) { llvm::SmallVector<mlir::Value> bounds; std::stringstream asFortran; mlir::Location operandLocation = genOperandLocation(converter, accObject); + Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject); + Fortran::semantics::MaybeExpr designator = + std::visit([&](auto &&s) { return ea.Analyze(s); }, accObject.u); Fortran::lower::AddrAndBoundsInfo info = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::AccObject, mlir::acc::DataBoundsOp, - mlir::acc::DataBoundsType>(converter, builder, semanticsContext, - stmtCtx, accObject, operandLocation, - asFortran, bounds); + mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>( + converter, builder, semanticsContext, stmtCtx, symbol, designator, + operandLocation, asFortran, bounds); RecipeOp recipe; mlir::Type retTy = getTypeFromBounds(bounds, info.addr.getType()); if constexpr (std::is_same_v<RecipeOp, mlir::acc::PrivateRecipeOp>) { @@ -1340,16 +1353,19 @@ genReductions(const Fortran::parser::AccObjectListWithReduction &objectList, const auto &op = std::get<Fortran::parser::AccReductionOperator>(objectList.t); mlir::acc::ReductionOperator mlirOp = getReductionOperator(op); + Fortran::evaluate::ExpressionAnalyzer ea{semanticsContext}; for (const auto &accObject : objects.v) { llvm::SmallVector<mlir::Value> bounds; std::stringstream asFortran; mlir::Location operandLocation = genOperandLocation(converter, accObject); + Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject); + Fortran::semantics::MaybeExpr designator = + std::visit([&](auto &&s) { return ea.Analyze(s); }, accObject.u); Fortran::lower::AddrAndBoundsInfo info = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::AccObject, mlir::acc::DataBoundsOp, - mlir::acc::DataBoundsType>(converter, builder, semanticsContext, - stmtCtx, accObject, operandLocation, - asFortran, bounds); + mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>( + converter, builder, semanticsContext, stmtCtx, symbol, designator, + operandLocation, asFortran, bounds); mlir::Type reductionTy = fir::unwrapRefType(info.addr.getType()); if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(reductionTy)) diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index ae798b5c0a58..95faa0767e36 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -818,65 +818,61 @@ bool ClauseProcessor::processMap( llvm::SmallVectorImpl<const Fortran::semantics::Symbol *> *mapSymbols) const { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - return findRepeatableClause2<ClauseTy::Map>( - [&](const ClauseTy::Map *mapClause, + return findRepeatableClause<omp::clause::Map>( + [&](const omp::clause::Map &clause, const Fortran::parser::CharBlock &source) { + using Map = omp::clause::Map; mlir::Location clauseLocation = converter.genLocation(source); - const auto &oMapType = - std::get<std::optional<Fortran::parser::OmpMapType>>( - mapClause->v.t); + const auto &oMapType = std::get<std::optional<Map::MapType>>(clause.t); llvm::omp::OpenMPOffloadMappingFlags mapTypeBits = llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE; // If the map type is specified, then process it else Tofrom is the // default. if (oMapType) { - const Fortran::parser::OmpMapType::Type &mapType = - std::get<Fortran::parser::OmpMapType::Type>(oMapType->t); + const Map::MapType::Type &mapType = + std::get<Map::MapType::Type>(oMapType->t); switch (mapType) { - case Fortran::parser::OmpMapType::Type::To: + case Map::MapType::Type::To: mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO; break; - case Fortran::parser::OmpMapType::Type::From: + case Map::MapType::Type::From: mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; break; - case Fortran::parser::OmpMapType::Type::Tofrom: + case Map::MapType::Type::Tofrom: mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO | llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; break; - case Fortran::parser::OmpMapType::Type::Alloc: - case Fortran::parser::OmpMapType::Type::Release: + case Map::MapType::Type::Alloc: + case Map::MapType::Type::Release: // alloc and release is the default map_type for the Target Data // Ops, i.e. if no bits for map_type is supplied then alloc/release // is implicitly assumed based on the target directive. Default // value for Target Data and Enter Data is alloc and for Exit Data // it is release. break; - case Fortran::parser::OmpMapType::Type::Delete: + case Map::MapType::Type::Delete: mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_DELETE; } - if (std::get<std::optional<Fortran::parser::OmpMapType::Always>>( - oMapType->t)) + if (std::get<std::optional<Map::MapType::Always>>(oMapType->t)) mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ALWAYS; } else { mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO | llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; } - for (const Fortran::parser::OmpObject &ompObject : - std::get<Fortran::parser::OmpObjectList>(mapClause->v.t).v) { + for (const omp::Object &object : std::get<omp::ObjectList>(clause.t)) { llvm::SmallVector<mlir::Value> bounds; std::stringstream asFortran; Fortran::lower::AddrAndBoundsInfo info = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::OmpObject, mlir::omp::MapBoundsOp, - mlir::omp::MapBoundsType>( - converter, firOpBuilder, semaCtx, stmtCtx, ompObject, - clauseLocation, asFortran, bounds, treatIndexAsSection); + mlir::omp::MapBoundsOp, mlir::omp::MapBoundsType>( + converter, firOpBuilder, semaCtx, stmtCtx, *object.id(), + object.ref(), clauseLocation, asFortran, bounds, + treatIndexAsSection); - auto origSymbol = - converter.getSymbolAddress(*getOmpObjectSymbol(ompObject)); + auto origSymbol = converter.getSymbolAddress(*object.id()); mlir::Value symAddr = info.addr; if (origSymbol && fir::isTypeWithDescriptor(origSymbol.getType())) symAddr = origSymbol; @@ -899,7 +895,7 @@ bool ClauseProcessor::processMap( mapSymLocs->push_back(symAddr.getLoc()); if (mapSymbols) - mapSymbols->push_back(getOmpObjectSymbol(ompObject)); + mapSymbols->push_back(object.id()); } }); } diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index c2db0cfc3cb7..ffa8a5e05593 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -162,9 +162,6 @@ private: /// Utility to find a clause within a range in the clause list. template <typename T> static ClauseIterator findClause(ClauseIterator begin, ClauseIterator end); - template <typename T> - static ClauseIterator2 findClause2(ClauseIterator2 begin, - ClauseIterator2 end); /// Return the first instance of the given clause found in the clause list or /// `nullptr` if not present. If more than one instance is expected, use @@ -179,10 +176,6 @@ private: bool findRepeatableClause( std::function<void(const T &, const Fortran::parser::CharBlock &source)> callbackFn) const; - template <typename T> - bool findRepeatableClause2( - std::function<void(const T *, const Fortran::parser::CharBlock &source)> - callbackFn) const; /// Set the `result` to a new `mlir::UnitAttr` if the clause is present. template <typename T> @@ -198,32 +191,31 @@ template <typename T> bool ClauseProcessor::processMotionClauses( Fortran::lower::StatementContext &stmtCtx, llvm::SmallVectorImpl<mlir::Value> &mapOperands) { - return findRepeatableClause2<T>( - [&](const T *motionClause, const Fortran::parser::CharBlock &source) { + return findRepeatableClause<T>( + [&](const T &clause, const Fortran::parser::CharBlock &source) { mlir::Location clauseLocation = converter.genLocation(source); fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - static_assert(std::is_same_v<T, ClauseProcessor::ClauseTy::To> || - std::is_same_v<T, ClauseProcessor::ClauseTy::From>); + static_assert(std::is_same_v<T, omp::clause::To> || + std::is_same_v<T, omp::clause::From>); // TODO Support motion modifiers: present, mapper, iterator. constexpr llvm::omp::OpenMPOffloadMappingFlags mapTypeBits = - std::is_same_v<T, ClauseProcessor::ClauseTy::To> + std::is_same_v<T, omp::clause::To> ? llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO : llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM; - for (const Fortran::parser::OmpObject &ompObject : motionClause->v.v) { + for (const omp::Object &object : clause.v) { llvm::SmallVector<mlir::Value> bounds; std::stringstream asFortran; Fortran::lower::AddrAndBoundsInfo info = Fortran::lower::gatherDataOperandAddrAndBounds< - Fortran::parser::OmpObject, mlir::omp::MapBoundsOp, - mlir::omp::MapBoundsType>( - converter, firOpBuilder, semaCtx, stmtCtx, ompObject, - clauseLocation, asFortran, bounds, treatIndexAsSection); + mlir::omp::MapBoundsOp, mlir::omp::MapBoundsType>( + converter, firOpBuilder, semaCtx, stmtCtx, *object.id(), + object.ref(), clauseLocation, asFortran, bounds, + treatIndexAsSection); - auto origSymbol = - converter.getSymbolAddress(*getOmpObjectSymbol(ompObject)); + auto origSymbol = converter.getSymbolAddress(*object.id()); mlir::Value symAddr = info.addr; if (origSymbol && fir::isTypeWithDescriptor(origSymbol.getType())) symAddr = origSymbol; @@ -273,17 +265,6 @@ ClauseProcessor::findClause(ClauseIterator begin, ClauseIterator end) { return end; } -template <typename T> -ClauseProcessor::ClauseIterator2 -ClauseProcessor::findClause2(ClauseIterator2 begin, ClauseIterator2 end) { - for (ClauseIterator2 it = begin; it != end; ++it) { - if (std::get_if<T>(&it->u)) - return it; - } - - return end; -} - template <typename T> const T *ClauseProcessor::findUniqueClause( const Fortran::parser::CharBlock **source) const { @@ -314,24 +295,6 @@ bool ClauseProcessor::findRepeatableClause( return found; } -template <typename T> -bool ClauseProcessor::findRepeatableClause2( - std::function<void(const T *, const Fortran::parser::CharBlock &source)> - callbackFn) const { - bool found = false; - ClauseIterator2 nextIt, endIt = clauses2.v.end(); - for (ClauseIterator2 it = clauses2.v.begin(); it != endIt; it = nextIt) { - nextIt = findClause2<T>(it, endIt); - - if (nextIt != endIt) { - callbackFn(&std::get<T>(nextIt->u), nextIt->source); - found = true; - ++nextIt; - } - } - return found; -} - template <typename T> bool ClauseProcessor::markClauseOccurrence(mlir::UnitAttr &result) const { if (findUniqueClause<T>()) { diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 5c4caa1de573..d335129565b4 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -930,11 +930,8 @@ static OpTy genTargetEnterExitDataUpdateOp( cp.processNowait(nowaitAttr); if constexpr (std::is_same_v<OpTy, mlir::omp::TargetUpdateOp>) { - cp.processMotionClauses<Fortran::parser::OmpClause::To>(stmtCtx, - mapOperands); - cp.processMotionClauses<Fortran::parser::OmpClause::From>(stmtCtx, - mapOperands); - + cp.processMotionClauses<clause::To>(stmtCtx, mapOperands); + cp.processMotionClauses<clause::From>(stmtCtx, mapOperands); } else { cp.processMap(currentLocation, directive, stmtCtx, mapOperands); } diff --git a/flang/test/Lower/OpenACC/acc-bounds.f90 b/flang/test/Lower/OpenACC/acc-bounds.f90 index df97cbcd187d..c275d4f1b1d5 100644 --- a/flang/test/Lower/OpenACC/acc-bounds.f90 +++ b/flang/test/Lower/OpenACC/acc-bounds.f90 @@ -184,7 +184,7 @@ contains ! CHECK: fir.result %c0{{.*}} : index ! CHECK: } ! CHECK: %[[BOUNDS:.*]] = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%[[STRIDE]] : index) startIdx(%c1 : index) {strideInBytes = true} -! CHECK: %[[NOCREATE:.*]] = acc.nocreate varPtr(%[[DECL_A]]#1 : !fir.ref<!fir.array<?xf32>>) bounds(%14) -> !fir.ref<!fir.array<?xf32>> {name = "a(1:n)"} +! CHECK: %[[NOCREATE:.*]] = acc.nocreate varPtr(%[[DECL_A]]#1 : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<?xf32>> {name = "a(1:n)"} ! CHECK: acc.data dataOperands(%[[NOCREATE]] : !fir.ref<!fir.array<?xf32>>) { end module diff --git a/flang/test/Lower/OpenACC/acc-enter-data.f90 b/flang/test/Lower/OpenACC/acc-enter-data.f90 index 2cf50c1b62f1..251edbf9c2dd 100644 --- a/flang/test/Lower/OpenACC/acc-enter-data.f90 +++ b/flang/test/Lower/OpenACC/acc-enter-data.f90 @@ -234,11 +234,13 @@ subroutine acc_enter_data_dummy(a, b, n, m) !$acc enter data create(b(n:m)) !CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[DECLB]]#0, %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) !CHECK: %[[LOAD_N:.*]] = fir.load %[[DECLN]]#0 : !fir.ref<i32> -!CHECK: %[[N_CONV:.*]] = fir.convert %[[LOAD_N]] : (i32) -> index -!CHECK: %[[LB:.*]] = arith.subi %[[N_CONV]], %[[N_IDX]] : index +!CHECK: %[[N_CONV1:.*]] = fir.convert %[[LOAD_N]] : (i32) -> i64 +!CHECK: %[[N_CONV2:.*]] = fir.convert %[[N_CONV1]] : (i64) -> index +!CHECK: %[[LB:.*]] = arith.subi %[[N_CONV2]], %[[N_IDX]] : index !CHECK: %[[LOAD_M:.*]] = fir.load %[[DECLM]]#0 : !fir.ref<i32> -!CHECK: %[[M_CONV:.*]] = fir.convert %[[LOAD_M]] : (i32) -> index -!CHECK: %[[UB:.*]] = arith.subi %[[M_CONV]], %[[N_IDX]] : index +!CHECK: %[[M_CONV1:.*]] = fir.convert %[[LOAD_M]] : (i32) -> i64 +!CHECK: %[[M_CONV2:.*]] = fir.convert %[[M_CONV1]] : (i64) -> index +!CHECK: %[[UB:.*]] = arith.subi %[[M_CONV2]], %[[N_IDX]] : index !CHECK: %[[BOUND1:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) extent(%[[EXT_B]] : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[N_IDX]] : index) {strideInBytes = true} !CHECK: %[[ADDR:.*]] = fir.box_addr %[[DECLB]]#0 : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> !CHECK: %[[CREATE1:.*]] = acc.create varPtr(%[[ADDR]] : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUND1]]) -> !fir.ref<!fir.array<?xf32>> {name = "b(n:m)", structured = false} @@ -248,8 +250,9 @@ subroutine acc_enter_data_dummy(a, b, n, m) !CHECK: %[[ONE:.*]] = arith.constant 1 : index !CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[DECLB]]#0, %c0_8 : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) !CHECK: %[[LOAD_N:.*]] = fir.load %[[DECLN]]#0 : !fir.ref<i32> -!CHECK: %[[CONVERT_N:.*]] = fir.convert %[[LOAD_N]] : (i32) -> index -!CHECK: %[[LB:.*]] = arith.subi %[[CONVERT_N]], %[[N_IDX]] : index +!CHECK: %[[CONVERT1_N:.*]] = fir.convert %[[LOAD_N]] : (i32) -> i64 +!CHECK: %[[CONVERT2_N:.*]] = fir.convert %[[CONVERT1_N]] : (i64) -> index +!CHECK: %[[LB:.*]] = arith.subi %[[CONVERT2_N]], %[[N_IDX]] : index !CHECK: %[[UB:.*]] = arith.subi %[[EXT_B]], %c1{{.*}} : index !CHECK: %[[BOUND1:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) extent(%[[EXT_B]] : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[N_IDX]] : index) {strideInBytes = true} !CHECK: %[[ADDR:.*]] = fir.box_addr %[[DECLB]]#0 : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> @@ -424,8 +427,9 @@ subroutine acc_enter_data_assumed(a, b, n, m) !CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[DECLA]]#0, %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) !CHECK: %[[LOAD_N:.*]] = fir.load %[[DECLN]]#0 : !fir.ref<i32> -!CHECK: %[[CONVERT_N:.*]] = fir.convert %[[LOAD_N]] : (i32) -> index -!CHECK: %[[LB:.*]] = arith.subi %[[CONVERT_N]], %[[ONE]] : index +!CHECK: %[[CONVERT1_N:.*]] = fir.convert %[[LOAD_N]] : (i32) -> i64 +!CHECK: %[[CONVERT2_N:.*]] = fir.convert %[[CONVERT1_N]] : (i64) -> index +!CHECK: %[[LB:.*]] = arith.subi %[[CONVERT2_N]], %[[ONE]] : index !CHECK: %[[C0:.*]] = arith.constant 0 : index !CHECK: %[[DIMS:.*]]:3 = fir.box_dims %[[DECLA]]#1, %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) @@ -444,8 +448,9 @@ subroutine acc_enter_data_assumed(a, b, n, m) !CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[DECLA]]#0, %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) !CHECK: %[[LOAD_M:.*]] = fir.load %[[DECLM]]#0 : !fir.ref<i32> -!CHECK: %[[CONVERT_M:.*]] = fir.convert %[[LOAD_M]] : (i32) -> index -!CHECK: %[[UB:.*]] = arith.subi %[[CONVERT_M]], %[[ONE]] : index +!CHECK: %[[CONVERT1_M:.*]] = fir.convert %[[LOAD_M]] : (i32) -> i64 +!CHECK: %[[CONVERT2_M:.*]] = fir.convert %[[CONVERT1_M]] : (i64) -> index +!CHECK: %[[UB:.*]] = arith.subi %[[CONVERT2_M]], %[[ONE]] : index !CHECK: %[[DIMS1:.*]]:3 = fir.box_dims %[[DECLA]]#1, %{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) !CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[BASELB]] : index) upperbound(%[[UB]] : index) extent(%[[DIMS1]]#1 : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[ONE]] : index) {strideInBytes = true} @@ -460,12 +465,14 @@ subroutine acc_enter_data_assumed(a, b, n, m) !CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[DECLA]]#0, %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) !CHECK: %[[LOAD_N:.*]] = fir.load %[[DECLN]]#0 : !fir.ref<i32> -!CHECK: %[[CONVERT_N:.*]] = fir.convert %[[LOAD_N]] : (i32) -> index -!CHECK: %[[LB:.*]] = arith.subi %[[CONVERT_N]], %[[ONE]] : index +!CHECK: %[[CONVERT1_N:.*]] = fir.convert %[[LOAD_N]] : (i32) -> i64 +!CHECK: %[[CONVERT2_N:.*]] = fir.convert %[[CONVERT1_N]] : (i64) -> index +!CHECK: %[[LB:.*]] = arith.subi %[[CONVERT2_N]], %[[ONE]] : index !CHECK: %[[LOAD_M:.*]] = fir.load %[[DECLM]]#0 : !fir.ref<i32> -!CHECK: %[[CONVERT_M:.*]] = fir.convert %[[LOAD_M]] : (i32) -> index -!CHECK: %[[UB:.*]] = arith.subi %[[CONVERT_M]], %[[ONE]] : index +!CHECK: %[[CONVERT1_M:.*]] = fir.convert %[[LOAD_M]] : (i32) -> i64 +!CHECK: %[[CONVERT2_M:.*]] = fir.convert %[[CONVERT1_M]] : (i64) -> index +!CHECK: %[[UB:.*]] = arith.subi %[[CONVERT2_M]], %[[ONE]] : index !CHECK: %[[DIMS1:.*]]:3 = fir.box_dims %[[DECLA]]#1, %{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) !CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) extent(%[[DIMS1]]#1 : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[ONE]] : index) {strideInBytes = true} @@ -480,8 +487,9 @@ subroutine acc_enter_data_assumed(a, b, n, m) !CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[DECLB]]#0, %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) !CHECK: %[[LOAD_M:.*]] = fir.load %[[DECLM]]#0 : !fir.ref<i32> -!CHECK: %[[CONVERT_M:.*]] = fir.convert %[[LOAD_M]] : (i32) -> index -!CHECK: %[[UB:.*]] = arith.subi %[[CONVERT_M]], %[[LB_C10_IDX]] : index +!CHECK: %[[CONVERT1_M:.*]] = fir.convert %[[LOAD_M]] : (i32) -> i64 +!CHECK: %[[CONVERT2_M:.*]] = fir.convert %[[CONVERT1_M]] : (i64) -> index +!CHECK: %[[UB:.*]] = arith.subi %[[CONVERT2_M]], %[[LB_C10_IDX]] : index !CHECK: %[[DIMS1:.*]]:3 = fir.box_dims %[[DECLB]]#1, %{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) !CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[ZERO]] : index) upperbound(%[[UB]] : index) extent(%[[DIMS1]]#1 : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[LB_C10_IDX]] : index) {strideInBytes = true} -- GitLab From 17af9addbbd0dc675c962bf034ea083b2b61a01a Mon Sep 17 00:00:00 2001 From: Marc Auberer <marc.auberer@chillibits.com> Date: Wed, 20 Mar 2024 21:18:58 +0100 Subject: [PATCH 303/307] [DAG] Add SDPatternMatch m_ZExtOrSelf/m_SExtOrSelf/m_AExtOrSelf/m_TruncOrSelf matchers (#85480) Fixes #85395 --- llvm/include/llvm/CodeGen/SDPatternMatch.h | 33 +++++++++++++++++++ .../CodeGen/SelectionDAGPatternMatchTest.cpp | 32 ++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/llvm/include/llvm/CodeGen/SDPatternMatch.h b/llvm/include/llvm/CodeGen/SDPatternMatch.h index 541c0ecb5be3..4cc7bb9c3b55 100644 --- a/llvm/include/llvm/CodeGen/SDPatternMatch.h +++ b/llvm/include/llvm/CodeGen/SDPatternMatch.h @@ -632,6 +632,38 @@ template <typename Opnd> inline UnaryOpc_match<Opnd> m_Trunc(const Opnd &Op) { return UnaryOpc_match<Opnd>(ISD::TRUNCATE, Op); } +/// Match a zext or identity +/// Allows to peek through optional extensions +template <typename Opnd> +inline Or<UnaryOpc_match<Opnd>, Opnd> m_ZExtOrSelf(Opnd &&Op) { + return Or<UnaryOpc_match<Opnd>, Opnd>(m_ZExt(std::forward<Opnd>(Op)), + std::forward<Opnd>(Op)); +} + +/// Match a sext or identity +/// Allows to peek through optional extensions +template <typename Opnd> +inline Or<UnaryOpc_match<Opnd>, Opnd> m_SExtOrSelf(Opnd &&Op) { + return Or<UnaryOpc_match<Opnd>, Opnd>(m_SExt(std::forward<Opnd>(Op)), + std::forward<Opnd>(Op)); +} + +/// Match a aext or identity +/// Allows to peek through optional extensions +template <typename Opnd> +inline Or<UnaryOpc_match<Opnd>, Opnd> m_AExtOrSelf(Opnd &&Op) { + return Or<UnaryOpc_match<Opnd>, Opnd>(m_AnyExt(std::forward<Opnd>(Op)), + std::forward<Opnd>(Op)); +} + +/// Match a trunc or identity +/// Allows to peek through optional truncations +template <typename Opnd> +inline Or<UnaryOpc_match<Opnd>, Opnd> m_TruncOrSelf(Opnd &&Op) { + return Or<UnaryOpc_match<Opnd>, Opnd>(m_Trunc(std::forward<Opnd>(Op)), + std::forward<Opnd>(Op)); +} + // === Constants === struct ConstantInt_match { APInt *BindVal; @@ -737,6 +769,7 @@ template <typename ValTy> inline BinaryOpc_match<ValTy, SpecificInt_match, true> m_Not(const ValTy &V) { return m_Xor(V, m_AllOnes()); } + } // namespace SDPatternMatch } // namespace llvm #endif diff --git a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp index 1967a62bbf9d..a7112cfac63d 100644 --- a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp +++ b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp @@ -251,6 +251,38 @@ TEST_F(SelectionDAGPatternMatchTest, patternCombinators) { EXPECT_TRUE(sd_match(Add, m_AllOf(m_Opc(ISD::ADD), m_OneUse()))); } +TEST_F(SelectionDAGPatternMatchTest, optionalResizing) { + SDLoc DL; + auto Int32VT = EVT::getIntegerVT(Context, 32); + auto Int64VT = EVT::getIntegerVT(Context, 64); + + SDValue Op32 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int32VT); + SDValue Op64 = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, Int64VT); + SDValue ZExt = DAG->getNode(ISD::ZERO_EXTEND, DL, Int64VT, Op32); + SDValue SExt = DAG->getNode(ISD::SIGN_EXTEND, DL, Int64VT, Op32); + SDValue AExt = DAG->getNode(ISD::ANY_EXTEND, DL, Int64VT, Op32); + SDValue Trunc = DAG->getNode(ISD::TRUNCATE, DL, Int32VT, Op64); + + using namespace SDPatternMatch; + SDValue A; + EXPECT_TRUE(sd_match(Op32, m_ZExtOrSelf(m_Value(A)))); + EXPECT_TRUE(A == Op32); + EXPECT_TRUE(sd_match(ZExt, m_ZExtOrSelf(m_Value(A)))); + EXPECT_TRUE(A == Op32); + EXPECT_TRUE(sd_match(Op64, m_SExtOrSelf(m_Value(A)))); + EXPECT_TRUE(A == Op64); + EXPECT_TRUE(sd_match(SExt, m_SExtOrSelf(m_Value(A)))); + EXPECT_TRUE(A == Op32); + EXPECT_TRUE(sd_match(Op32, m_AExtOrSelf(m_Value(A)))); + EXPECT_TRUE(A == Op32); + EXPECT_TRUE(sd_match(AExt, m_AExtOrSelf(m_Value(A)))); + EXPECT_TRUE(A == Op32); + EXPECT_TRUE(sd_match(Op64, m_TruncOrSelf(m_Value(A)))); + EXPECT_TRUE(A == Op64); + EXPECT_TRUE(sd_match(Trunc, m_TruncOrSelf(m_Value(A)))); + EXPECT_TRUE(A == Op64); +} + TEST_F(SelectionDAGPatternMatchTest, matchNode) { SDLoc DL; auto Int32VT = EVT::getIntegerVT(Context, 32); -- GitLab From 1f1f569b29f42161ea978328aea60044f16eee49 Mon Sep 17 00:00:00 2001 From: Christudasan Devadasan <Christudasan.Devadasan@amd.com> Date: Wed, 20 Mar 2024 19:59:40 +0530 Subject: [PATCH 304/307] [PowerPC] Clang format (NFC). --- llvm/lib/Target/PowerPC/PPCFrameLowering.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp index 424501c35c04..6dcb59a3a57f 100644 --- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -2676,7 +2676,7 @@ bool PPCFrameLowering::restoreCalleeSavedRegisters( Restored.set(Dst); } else { - // Default behavior for non-CR saves. + // Default behavior for non-CR saves. const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); // Functions without NoUnwind need to preserve the order of elements in -- GitLab From c2fd0e4398a90be2f4640964f3c1f2a73a3a1487 Mon Sep 17 00:00:00 2001 From: Stanislav Mekhanoshin <rampitec@users.noreply.github.com> Date: Wed, 20 Mar 2024 13:29:29 -0700 Subject: [PATCH 305/307] [AMDGPU] Copy SOP properties from pseudo to real. NFCI. (#85997) This is to help llvm-obdump to analyze instructions in a future patch. --- llvm/lib/Target/AMDGPU/SOPInstructions.td | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/llvm/lib/Target/AMDGPU/SOPInstructions.td b/llvm/lib/Target/AMDGPU/SOPInstructions.td index 1159c4e0fc2e..d34ee34e5bbf 100644 --- a/llvm/lib/Target/AMDGPU/SOPInstructions.td +++ b/llvm/lib/Target/AMDGPU/SOPInstructions.td @@ -60,6 +60,11 @@ class SOP1_Real<bits<8> op, SOP1_Pseudo ps, string real_name = ps.Mnemonic> : let SchedRW = ps.SchedRW; let mayLoad = ps.mayLoad; let mayStore = ps.mayStore; + let isTerminator = ps.isTerminator; + let isReturn = ps.isReturn; + let isCall = ps.isCall; + let isBranch = ps.isBranch; + let isBarrier = ps.isBarrier; // encoding bits<7> sdst; @@ -977,6 +982,9 @@ class SOPK_Real<SOPK_Pseudo ps, string name = ps.Mnemonic> : let mayStore = ps.mayStore; let isBranch = ps.isBranch; let isCall = ps.isCall; + let isTerminator = ps.isTerminator; + let isReturn = ps.isReturn; + let isBarrier = ps.isBarrier; // encoding bits<7> sdst; @@ -1426,6 +1434,11 @@ class SOPP_Real<SOPP_Pseudo ps, string name = ps.Mnemonic> : let SchedRW = ps.SchedRW; let mayLoad = ps.mayLoad; let mayStore = ps.mayStore; + let isTerminator = ps.isTerminator; + let isReturn = ps.isReturn; + let isCall = ps.isCall; + let isBranch = ps.isBranch; + let isBarrier = ps.isBarrier; bits <16> simm16; } -- GitLab From 294a6c3b650d2411e50487b287b24b7d85847162 Mon Sep 17 00:00:00 2001 From: Kazu Hirata <kazu@google.com> Date: Wed, 20 Mar 2024 13:38:26 -0700 Subject: [PATCH 306/307] [clang] Fix a warning This patch fixes: clang/lib/CodeGen/CGExprComplex.cpp:1037:14: error: unused variable 'ComplexElementTy' [-Werror,-Wunused-variable] --- clang/lib/CodeGen/CGExprComplex.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 27ddaacc28f5..b873bc6737bb 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -1034,7 +1034,6 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { llvm::Value *OrigLHSi = LHSi; if (!LHSi) LHSi = llvm::Constant::getNullValue(RHSi->getType()); - QualType ComplexElementTy = Op.Ty->castAs<ComplexType>()->getElementType(); if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Improved || (Op.FPFeatures.getComplexRange() == LangOptions::CX_Promoted && FPHasBeenPromoted)) -- GitLab From f6f474c4ef9694a4ca8f08d59fd112c250fb9c73 Mon Sep 17 00:00:00 2001 From: Paul Kirth <paulkirth@google.com> Date: Wed, 20 Mar 2024 13:39:39 -0700 Subject: [PATCH 307/307] [llvm][lld] Pre-commit tests for RISCV TLSDESC symbols Currently, we mistakenly mark the local labels used in RISC-V TLSDESC as TLS symbols, when they should not be. This patch adds tests with the current incorrect behavior, and subsequent patches will address the issue. Reviewers: MaskRay, topperc Reviewed By: MaskRay Pull Request: https://github.com/llvm/llvm-project/pull/85816 --- lld/test/ELF/riscv-tlsdesc.s | 25 +++++++++++++++++++++++ llvm/test/CodeGen/RISCV/tlsdesc-symbol.ll | 24 ++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 llvm/test/CodeGen/RISCV/tlsdesc-symbol.ll diff --git a/lld/test/ELF/riscv-tlsdesc.s b/lld/test/ELF/riscv-tlsdesc.s index 1738f86256ca..c583e15cf30c 100644 --- a/lld/test/ELF/riscv-tlsdesc.s +++ b/lld/test/ELF/riscv-tlsdesc.s @@ -29,6 +29,12 @@ # RUN: ld.lld -e 0 -z now a.32.o c.32.so -o a.32.ie # RUN: llvm-objdump --no-show-raw-insn -M no-aliases -h -d a.32.ie | FileCheck %s --check-prefix=IE32 +# RUN: llvm-mc -triple=riscv64 -filetype=obj d.s -o d.64.o +# RUN: not ld.lld -shared -soname=d.64.so -o d.64.so d.64.o 2>&1 | FileCheck %s --check-prefix=BADTLSLABEL + +# RUN: llvm-mc -triple=riscv32 -filetype=obj d.s -o d.32.o --defsym ELF32=1 +# RUN: not ld.lld -shared -soname=d.32.so -o d.32.so d.32.o 2>&1 | FileCheck %s --check-prefix=BADTLSLABEL + # GD64-RELA: .rela.dyn { # GD64-RELA-NEXT: 0x2408 R_RISCV_TLSDESC - 0x7FF # GD64-RELA-NEXT: 0x23E8 R_RISCV_TLSDESC a 0x0 @@ -150,6 +156,9 @@ # IE32-NEXT: lw a0, 0x80(a0) # IE32-NEXT: add a0, a0, tp +## FIXME This should not pass, but the code MC layer needs a fix to prevent this. +# BADTLSLABEL: error: d.{{.*}}.o has an STT_TLS symbol but doesn't have an SHF_TLS section + #--- a.s .macro load dst, src .ifdef ELF32 @@ -192,3 +201,19 @@ b: .tbss .globl c c: .zero 4 + +#--- d.s +.macro load dst, src +.ifdef ELF32 +lw \dst, \src +.else +ld \dst, \src +.endif +.endm + +.Ltlsdesc_hi0: + auipc a0, %tlsdesc_hi(foo) + load a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0) + addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0) + jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0) + add a1, a0, tp diff --git a/llvm/test/CodeGen/RISCV/tlsdesc-symbol.ll b/llvm/test/CodeGen/RISCV/tlsdesc-symbol.ll new file mode 100644 index 000000000000..23ba2ffb1ad7 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/tlsdesc-symbol.ll @@ -0,0 +1,24 @@ +;; The test in this file do not appear in tls-models.ll because +;; they are not auto-generated. +; RUN: llc -mtriple=riscv64 -relocation-model=pic -enable-tlsdesc < %s \ +; RUN: | llvm-mc -triple=riscv64 -filetype=obj -o - \ +; RUN: | llvm-readelf --symbols - \ +; RUN: | FileCheck %s + +; RUN: llc -mtriple=riscv32 -relocation-model=pic -enable-tlsdesc < %s \ +; RUN: | llvm-mc -triple=riscv32 -filetype=obj -o - \ +; RUN: | llvm-readelf --symbols - \ +; RUN: | FileCheck %s + +; Check that TLS symbols are lowered correctly based on the specified +; model. Make sure they're external to avoid them all being optimised to Local +; Exec for the executable. + +@unspecified = external thread_local global i32 + +define ptr @f1() nounwind { +entry: + ret ptr @unspecified + ; CHECK: Symbol table '.symtab' contains 7 entries: + ; CHECK: TLS {{.*}} unspecified +} -- GitLab