diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td --- a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td +++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td @@ -537,37 +537,52 @@ } // End let AddressSpaces } // End foreach as - +// TODO: Add GISelPredicateCode for the ret and noret PatFrags once +// GlobalISelEmitter allows pattern matches where src and dst def count +// mismatch. multiclass ret_noret_binary_atomic_op { + let PredicateCode = [{ return (SDValue(N, 0).use_empty()); }] in { + defm "_noret" : binary_atomic_op; + } + + let PredicateCode = [{ return !(SDValue(N, 0).use_empty()); }] in { + defm "_ret" : binary_atomic_op; + } +} + +multiclass ret_noret_ternary_atomic_op { + let PredicateCode = [{ return (SDValue(N, 0).use_empty()); }] in { + defm "_noret" : ternary_atomic_op; + } + + let PredicateCode = [{ return !(SDValue(N, 0).use_empty()); }] in { + defm "_ret" : ternary_atomic_op; + } +} + +multiclass binary_atomic_op_all_as { foreach as = [ "global", "flat", "constant", "local", "private", "region" ] in { let AddressSpaces = !cast("LoadAddress_"#as).AddrSpaces in { defm "_"#as : binary_atomic_op; - - let PredicateCode = [{return (SDValue(N, 0).use_empty());}] in { - defm "_"#as#"_noret" : binary_atomic_op; - } - - let PredicateCode = [{return !(SDValue(N, 0).use_empty());}] in { - defm "_"#as#"_ret" : binary_atomic_op; - } + defm "_"#as : ret_noret_binary_atomic_op; } } } -defm atomic_swap : ret_noret_binary_atomic_op; -defm atomic_load_add : ret_noret_binary_atomic_op; -defm atomic_load_and : ret_noret_binary_atomic_op; -defm atomic_load_max : ret_noret_binary_atomic_op; -defm atomic_load_min : ret_noret_binary_atomic_op; -defm atomic_load_or : ret_noret_binary_atomic_op; -defm atomic_load_sub : ret_noret_binary_atomic_op; -defm atomic_load_umax : ret_noret_binary_atomic_op; -defm atomic_load_umin : ret_noret_binary_atomic_op; -defm atomic_load_xor : ret_noret_binary_atomic_op; -defm atomic_load_fadd : ret_noret_binary_atomic_op; +defm atomic_swap : binary_atomic_op_all_as; +defm atomic_load_add : binary_atomic_op_all_as; +defm atomic_load_and : binary_atomic_op_all_as; +defm atomic_load_max : binary_atomic_op_all_as; +defm atomic_load_min : binary_atomic_op_all_as; +defm atomic_load_or : binary_atomic_op_all_as; +defm atomic_load_sub : binary_atomic_op_all_as; +defm atomic_load_umax : binary_atomic_op_all_as; +defm atomic_load_umin : binary_atomic_op_all_as; +defm atomic_load_xor : binary_atomic_op_all_as; +defm atomic_load_fadd : binary_atomic_op_all_as; let MemoryVT = v2f16 in -defm atomic_load_fadd_v2f16 : ret_noret_binary_atomic_op; -defm AMDGPUatomic_cmp_swap : ret_noret_binary_atomic_op; +defm atomic_load_fadd_v2f16 : binary_atomic_op_all_as; +defm AMDGPUatomic_cmp_swap : binary_atomic_op_all_as; def load_align8_local : PatFrag<(ops node:$ptr), (load_local node:$ptr)>, Aligned<8> { @@ -595,12 +610,13 @@ let AddressSpaces = StoreAddress_local.AddrSpaces in { defm atomic_cmp_swap_local : ternary_atomic_op; -defm atomic_cmp_swap_local_m0 : ternary_atomic_op; +defm atomic_cmp_swap_local : ret_noret_ternary_atomic_op; +defm atomic_cmp_swap_local_m0 : ret_noret_ternary_atomic_op; } let AddressSpaces = StoreAddress_region.AddrSpaces in { -defm atomic_cmp_swap_region : ternary_atomic_op; -defm atomic_cmp_swap_region_m0 : ternary_atomic_op; +defm atomic_cmp_swap_region : ret_noret_ternary_atomic_op; +defm atomic_cmp_swap_region_m0 : ret_noret_ternary_atomic_op; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AMDGPU/DSInstructions.td b/llvm/lib/Target/AMDGPU/DSInstructions.td --- a/llvm/lib/Target/AMDGPU/DSInstructions.td +++ b/llvm/lib/Target/AMDGPU/DSInstructions.td @@ -904,6 +904,28 @@ def : DSAtomicRetPat(frag#"_region_m0_"#vt.Size), 1>; } +multiclass DSAtomicRetNoRetPat_mc { + let OtherPredicates = [LDSRequiresM0Init] in { + def : DSAtomicRetPat(frag#"_local_m0_ret_"#vt.Size)>; + def : DSAtomicRetPat(frag#"_local_m0_noret_"#vt.Size)>; + } + + let OtherPredicates = [NotLDSRequiresM0Init] in { + def : DSAtomicRetPat(!cast(inst)#"_gfx9"), vt, + !cast(frag#"_local_ret_"#vt.Size)>; + def : DSAtomicRetPat(!cast(noRetInst)#"_gfx9"), vt, + !cast(frag#"_local_noret_"#vt.Size)>; + } + + def : DSAtomicRetPat(frag#"_region_m0_ret_"#vt.Size), 1>; + def : DSAtomicRetPat(frag#"_region_m0_noret_"#vt.Size), 1>; +} + class DSAtomicCmpXChg : GCNPat < @@ -911,62 +933,68 @@ (inst $ptr, getVregSrcForVT.ret:$cmp, getVregSrcForVT.ret:$swap, offset:$offset, (i1 gds)) >; -multiclass DSAtomicCmpXChg_mc { +multiclass DSAtomicCmpXChg_mc { let OtherPredicates = [LDSRequiresM0Init] in { - def : DSAtomicCmpXChg(frag#"_local_m0_"#vt.Size)>; + def : DSAtomicCmpXChg(frag#"_local_m0_ret_"#vt.Size)>; + def : DSAtomicCmpXChg(frag#"_local_m0_noret_"#vt.Size)>; } let OtherPredicates = [NotLDSRequiresM0Init] in { def : DSAtomicCmpXChg(!cast(inst)#"_gfx9"), vt, - !cast(frag#"_local_"#vt.Size)>; + !cast(frag#"_local_ret_"#vt.Size)>; + def : DSAtomicCmpXChg(!cast(noRetInst)#"_gfx9"), vt, + !cast(frag#"_local_noret_"#vt.Size)>; } - def : DSAtomicCmpXChg(frag#"_region_m0_"#vt.Size), 1>; + def : DSAtomicCmpXChg(frag#"_region_m0_ret_"#vt.Size), 1>; + def : DSAtomicCmpXChg(frag#"_region_m0_noret_"#vt.Size), 1>; } // 32-bit atomics. defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicCmpXChg_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicCmpXChg_mc; let SubtargetPredicate = HasLDSFPAtomicAdd in { -defm : DSAtomicRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; } // 64-bit atomics. defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; -defm : DSAtomicRetPat_mc; - -defm : DSAtomicCmpXChg_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; +defm : DSAtomicRetNoRetPat_mc; + +defm : DSAtomicCmpXChg_mc; let SubtargetPredicate = isGFX90APlus in { -def : DSAtomicRetPat; +def : DSAtomicRetPat; +def : DSAtomicRetPat; } def : Pat < diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -291,19 +291,10 @@ // PatFrags for global memory operations //===----------------------------------------------------------------------===// -foreach as = [ "global", "flat", "constant", "local", "private", "region" ] in { -let AddressSpaces = !cast("LoadAddress_"#as).AddrSpaces in { - - -defm atomic_inc_#as : binary_atomic_op; -defm atomic_dec_#as : binary_atomic_op; -defm atomic_load_fmin_#as : binary_atomic_op; -defm atomic_load_fmax_#as : binary_atomic_op; - - -} // End let AddressSpaces = ... -} // End foreach AddrSpace - +defm atomic_inc : binary_atomic_op_all_as; +defm atomic_dec : binary_atomic_op_all_as; +defm atomic_load_fmin : binary_atomic_op_all_as; +defm atomic_load_fmax : binary_atomic_op_all_as; //===----------------------------------------------------------------------===// // SDNodes PatFrags for loads/stores with a glue input. @@ -686,10 +677,14 @@ let AddressSpaces = StoreAddress_local.AddrSpaces in { defm _local_m0 : binary_atomic_op (NAME#"_glue"), IsInt>; + defm _local_m0 : ret_noret_binary_atomic_op (NAME#"_glue"), + IsInt>; } let AddressSpaces = StoreAddress_region.AddrSpaces in { defm _region_m0 : binary_atomic_op (NAME#"_glue"), IsInt>; + defm _region_m0 : ret_noret_binary_atomic_op (NAME#"_glue"), + IsInt>; } }