brintos

brintos / llvm-project-archived public Read only

0
0
Text · 38.5 KiB · ca5ffd1 Raw
865 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S -o - %s | FileCheck %s3 4; Check that we don't replace `atomicrmw <op> LHS, 0` with `load atomic LHS`.5; Doing that would lose the store semantic of the `atomicrmw` operation.6; This may enable some other optimizations that would otherwise be illegal when7; the store semantic was present (e.g., like dropping a fence).8 9; Idempotent atomicrmw are still canonicalized.10define i32 @atomic_add_zero(ptr %addr) {11; CHECK-LABEL: @atomic_add_zero(12; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 monotonic, align 413; CHECK-NEXT:    ret i32 [[RES]]14;15  %res = atomicrmw add ptr %addr, i32 0 monotonic16  ret i32 %res17}18 19define i32 @atomic_or_zero(ptr %addr) {20; CHECK-LABEL: @atomic_or_zero(21; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 monotonic, align 422; CHECK-NEXT:    ret i32 [[RES]]23;24  %res = atomicrmw or ptr %addr, i32 0 monotonic25  ret i32 %res26}27 28; Idempotent atomicrmw are still canonicalized.29define i32 @atomic_sub_zero(ptr %addr) {30; CHECK-LABEL: @atomic_sub_zero(31; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 monotonic, align 432; CHECK-NEXT:    ret i32 [[RES]]33;34  %res = atomicrmw sub ptr %addr, i32 0 monotonic35  ret i32 %res36}37 38; Idempotent atomicrmw are still canonicalized.39define i32 @atomic_and_allones(ptr %addr) {40; CHECK-LABEL: @atomic_and_allones(41; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 monotonic, align 442; CHECK-NEXT:    ret i32 [[RES]]43;44  %res = atomicrmw and ptr %addr, i32 -1 monotonic45  ret i32 %res46}47 48; Idempotent atomicrmw are still canonicalized.49define i32 @atomic_umin_uint_max(ptr %addr) {50; CHECK-LABEL: @atomic_umin_uint_max(51; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 monotonic, align 452; CHECK-NEXT:    ret i32 [[RES]]53;54  %res = atomicrmw umin ptr %addr, i32 -1 monotonic55  ret i32 %res56}57 58; Idempotent atomicrmw are still canonicalized.59define i32 @atomic_umax_zero(ptr %addr) {60; CHECK-LABEL: @atomic_umax_zero(61; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 monotonic, align 462; CHECK-NEXT:    ret i32 [[RES]]63;64  %res = atomicrmw umax ptr %addr, i32 0 monotonic65  ret i32 %res66}67 68; Idempotent atomicrmw are still canonicalized.69define i8 @atomic_min_smax_char(ptr %addr) {70; CHECK-LABEL: @atomic_min_smax_char(71; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i8 0 monotonic, align 172; CHECK-NEXT:    ret i8 [[RES]]73;74  %res = atomicrmw min ptr %addr, i8 127 monotonic75  ret i8 %res76}77 78; Idempotent atomicrmw are still canonicalized.79define i8 @atomic_max_smin_char(ptr %addr) {80; CHECK-LABEL: @atomic_max_smin_char(81; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i8 0 monotonic, align 182; CHECK-NEXT:    ret i8 [[RES]]83;84  %res = atomicrmw max ptr %addr, i8 -128 monotonic85  ret i8 %res86}87 88; Idempotent atomicrmw are still canonicalized.89define float @atomic_fsub_zero(ptr %addr) {90; CHECK-LABEL: @atomic_fsub_zero(91; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float -0.000000e+00 monotonic, align 492; CHECK-NEXT:    ret float [[RES]]93;94  %res = atomicrmw fsub ptr %addr, float 0.0 monotonic95  ret float %res96}97 98define float @atomic_fadd_zero(ptr %addr) {99; CHECK-LABEL: @atomic_fadd_zero(100; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float -0.000000e+00 monotonic, align 4101; CHECK-NEXT:    ret float [[RES]]102;103  %res = atomicrmw fadd ptr %addr, float -0.0 monotonic104  ret float %res105}106 107; Idempotent atomicrmw are still canonicalized.108define float @atomic_fsub_canon(ptr %addr) {109; CHECK-LABEL: @atomic_fsub_canon(110; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float -0.000000e+00 release, align 4111; CHECK-NEXT:    ret float [[RES]]112;113  %res = atomicrmw fsub ptr %addr, float 0.0 release114  ret float %res115}116 117define float @atomic_fadd_canon(ptr %addr) {118; CHECK-LABEL: @atomic_fadd_canon(119; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float -0.000000e+00 release, align 4120; CHECK-NEXT:    ret float [[RES]]121;122  %res = atomicrmw fadd ptr %addr, float -0.0 release123  ret float %res124}125 126; Can't replace a volatile w/a load; this would eliminate a volatile store.127define i64 @atomic_sub_zero_volatile(ptr %addr) {128; CHECK-LABEL: @atomic_sub_zero_volatile(129; CHECK-NEXT:    [[RES:%.*]] = atomicrmw volatile sub ptr [[ADDR:%.*]], i64 0 acquire, align 8130; CHECK-NEXT:    ret i64 [[RES]]131;132  %res = atomicrmw volatile sub ptr %addr, i64 0 acquire133  ret i64 %res134}135 136 137; Check that the transformation properly preserve the syncscope.138; Idempotent atomicrmw are still canonicalized.139define i16 @atomic_syncscope(ptr %addr) {140; CHECK-LABEL: @atomic_syncscope(141; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i16 0 syncscope("some_syncscope") acquire, align 2142; CHECK-NEXT:    ret i16 [[RES]]143;144  %res = atomicrmw or ptr %addr, i16 0 syncscope("some_syncscope") acquire145  ret i16 %res146}147 148; By eliminating the store part of the atomicrmw, we would get rid of the149; release semantic, which is incorrect.  We can canonicalize the operation.150define i16 @atomic_seq_cst(ptr %addr) {151; CHECK-LABEL: @atomic_seq_cst(152; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i16 0 seq_cst, align 2153; CHECK-NEXT:    ret i16 [[RES]]154;155  %res = atomicrmw add ptr %addr, i16 0 seq_cst156  ret i16 %res157}158 159; Check that the transformation does not apply when the value is changed by160; the atomic operation (non zero constant).161define i16 @atomic_add_non_zero(ptr %addr) {162; CHECK-LABEL: @atomic_add_non_zero(163; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr [[ADDR:%.*]], i16 2 monotonic, align 2164; CHECK-NEXT:    ret i16 [[RES]]165;166  %res = atomicrmw add ptr %addr, i16 2 monotonic167  ret i16 %res168}169 170; Idempotent atomicrmw are still canonicalized.171define i16 @atomic_xor_zero(ptr %addr) {172; CHECK-LABEL: @atomic_xor_zero(173; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i16 0 monotonic, align 2174; CHECK-NEXT:    ret i16 [[RES]]175;176  %res = atomicrmw xor ptr %addr, i16 0 monotonic177  ret i16 %res178}179 180; Check that the transformation does not apply when the ordering is181; incompatible with a load (release).  Do canonicalize.182define i16 @atomic_release(ptr %addr) {183; CHECK-LABEL: @atomic_release(184; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i16 0 release, align 2185; CHECK-NEXT:    ret i16 [[RES]]186;187  %res = atomicrmw sub ptr %addr, i16 0 release188  ret i16 %res189}190 191; Check that the transformation does not apply when the ordering is192; incompatible with a load (acquire, release).  Do canonicalize.193define i16 @atomic_acq_rel(ptr %addr) {194; CHECK-LABEL: @atomic_acq_rel(195; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i16 0 acq_rel, align 2196; CHECK-NEXT:    ret i16 [[RES]]197;198  %res = atomicrmw xor ptr %addr, i16 0 acq_rel199  ret i16 %res200}201 202define i32 @sat_or_allones(ptr %addr) {203; CHECK-LABEL: @sat_or_allones(204; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 monotonic, align 4205; CHECK-NEXT:    ret i32 [[RES]]206;207  %res = atomicrmw or ptr %addr, i32 -1 monotonic208  ret i32 %res209}210 211define i32 @sat_and_zero(ptr %addr) {212; CHECK-LABEL: @sat_and_zero(213; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 0 monotonic, align 4214; CHECK-NEXT:    ret i32 [[RES]]215;216  %res = atomicrmw and ptr %addr, i32 0 monotonic217  ret i32 %res218}219 220define i32 @sat_umin_uint_min(ptr %addr) {221; CHECK-LABEL: @sat_umin_uint_min(222; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 0 monotonic, align 4223; CHECK-NEXT:    ret i32 [[RES]]224;225  %res = atomicrmw umin ptr %addr, i32 0 monotonic226  ret i32 %res227}228 229define i32 @sat_umax_uint_max(ptr %addr) {230; CHECK-LABEL: @sat_umax_uint_max(231; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 monotonic, align 4232; CHECK-NEXT:    ret i32 [[RES]]233;234  %res = atomicrmw umax ptr %addr, i32 -1 monotonic235  ret i32 %res236}237 238define i8 @sat_min_smin_char(ptr %addr) {239; CHECK-LABEL: @sat_min_smin_char(240; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i8 -128 monotonic, align 1241; CHECK-NEXT:    ret i8 [[RES]]242;243  %res = atomicrmw min ptr %addr, i8 -128 monotonic244  ret i8 %res245}246 247define i8 @sat_max_smax_char(ptr %addr) {248; CHECK-LABEL: @sat_max_smax_char(249; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i8 127 monotonic, align 1250; CHECK-NEXT:    ret i8 [[RES]]251;252  %res = atomicrmw max ptr %addr, i8 127 monotonic253  ret i8 %res254}255 256define double @sat_fadd_nan(ptr %addr) {257; CHECK-LABEL: @sat_fadd_nan(258; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], double 0x7FF00000FFFFFFFF release, align 8259; CHECK-NEXT:    ret double [[RES]]260;261  %res = atomicrmw fadd ptr %addr, double 0x7FF00000FFFFFFFF release262  ret double %res263}264 265define double @sat_fsub_nan(ptr %addr) {266; CHECK-LABEL: @sat_fsub_nan(267; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], double 0x7FF00000FFFFFFFF release, align 8268; CHECK-NEXT:    ret double [[RES]]269;270  %res = atomicrmw fsub ptr %addr, double 0x7FF00000FFFFFFFF release271  ret double %res272}273 274define void @sat_fsub_nan_unused(ptr %addr) {275; CHECK-LABEL: @sat_fsub_nan_unused(276; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], double 0x7FF00000FFFFFFFF monotonic, align 8277; CHECK-NEXT:    ret void278;279  atomicrmw fsub ptr %addr, double 0x7FF00000FFFFFFFF monotonic280  ret void281}282 283define void @xchg_unused_monotonic(ptr %addr) {284; CHECK-LABEL: @xchg_unused_monotonic(285; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 0 monotonic, align 4286; CHECK-NEXT:    ret void287;288  atomicrmw xchg ptr %addr, i32 0 monotonic289  ret void290}291 292define void @xchg_unused_release(ptr %addr) {293; CHECK-LABEL: @xchg_unused_release(294; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 release, align 4295; CHECK-NEXT:    ret void296;297  atomicrmw xchg ptr %addr, i32 -1 release298  ret void299}300 301define void @xchg_unused_under_aligned(ptr %addr) {302; CHECK-LABEL: @xchg_unused_under_aligned(303; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 release, align 1304; CHECK-NEXT:    ret void305;306  atomicrmw xchg ptr %addr, i32 -1 release, align 1307  ret void308}309 310define void @xchg_unused_over_aligned(ptr %addr) {311; CHECK-LABEL: @xchg_unused_over_aligned(312; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 release, align 8313; CHECK-NEXT:    ret void314;315  atomicrmw xchg ptr %addr, i32 -1 release, align 8316  ret void317}318 319define void @xchg_unused_seq_cst(ptr %addr) {320; CHECK-LABEL: @xchg_unused_seq_cst(321; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 0 seq_cst, align 4322; CHECK-NEXT:    ret void323;324  atomicrmw xchg ptr %addr, i32 0 seq_cst325  ret void326}327 328define void @xchg_unused_volatile(ptr %addr) {329; CHECK-LABEL: @xchg_unused_volatile(330; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw volatile xchg ptr [[ADDR:%.*]], i32 0 monotonic, align 4331; CHECK-NEXT:    ret void332;333  atomicrmw volatile xchg ptr %addr, i32 0 monotonic334  ret void335}336 337define void @sat_or_allones_unused(ptr %addr) {338; CHECK-LABEL: @sat_or_allones_unused(339; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 monotonic, align 4340; CHECK-NEXT:    ret void341;342  atomicrmw or ptr %addr, i32 -1 monotonic343  ret void344}345 346define void @undef_operand_unused(ptr %addr) {347; CHECK-LABEL: @undef_operand_unused(348; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 undef monotonic, align 4349; CHECK-NEXT:    ret void350;351  atomicrmw or ptr %addr, i32 undef monotonic352  ret void353}354 355define i32 @undef_operand_used(ptr %addr) {356; CHECK-LABEL: @undef_operand_used(357; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 undef monotonic, align 4358; CHECK-NEXT:    ret i32 [[RES]]359;360  %res = atomicrmw or ptr %addr, i32 undef monotonic361  ret i32 %res362}363 364define double @sat_fmax_inf(ptr %addr) {365; CHECK-LABEL: @sat_fmax_inf(366; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], double 0x7FF0000000000000 monotonic, align 8367; CHECK-NEXT:    ret double [[RES]]368;369  %res = atomicrmw fmax ptr %addr, double 0x7FF0000000000000 monotonic370  ret double %res371}372 373define double @no_sat_fmax_inf(ptr %addr) {374; CHECK-LABEL: @no_sat_fmax_inf(375; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fmax ptr [[ADDR:%.*]], double 1.000000e-01 monotonic, align 8376; CHECK-NEXT:    ret double [[RES]]377;378  %res = atomicrmw fmax ptr %addr, double 1.000000e-01 monotonic379  ret double %res380}381 382define double @sat_fmin_inf(ptr %addr) {383; CHECK-LABEL: @sat_fmin_inf(384; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], double 0xFFF0000000000000 monotonic, align 8385; CHECK-NEXT:    ret double [[RES]]386;387  %res = atomicrmw fmin ptr %addr, double 0xFFF0000000000000 monotonic388  ret double %res389}390 391define double @no_sat_fmin_inf(ptr %addr) {392; CHECK-LABEL: @no_sat_fmin_inf(393; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fmin ptr [[ADDR:%.*]], double 1.000000e-01 monotonic, align 8394; CHECK-NEXT:    ret double [[RES]]395;396  %res = atomicrmw fmin ptr %addr, double 1.000000e-01 monotonic397  ret double %res398}399 400define double @sat_fmaximum_inf(ptr %addr) {401; CHECK-LABEL: @sat_fmaximum_inf(402; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fmaximum ptr [[ADDR:%.*]], double 0x7FF0000000000000 monotonic, align 8403; CHECK-NEXT:    ret double [[RES]]404;405  %res = atomicrmw fmaximum ptr %addr, double 0x7FF0000000000000 monotonic406  ret double %res407}408 409define double @no_sat_fmaximum_inf(ptr %addr) {410; CHECK-LABEL: @no_sat_fmaximum_inf(411; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fmaximum ptr [[ADDR:%.*]], double 1.000000e-01 monotonic, align 8412; CHECK-NEXT:    ret double [[RES]]413;414  %res = atomicrmw fmaximum ptr %addr, double 1.000000e-01 monotonic415  ret double %res416}417 418define double @sat_fminimum_inf(ptr %addr) {419; CHECK-LABEL: @sat_fminimum_inf(420; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fminimum ptr [[ADDR:%.*]], double 0xFFF0000000000000 monotonic, align 8421; CHECK-NEXT:    ret double [[RES]]422;423  %res = atomicrmw fminimum ptr %addr, double 0xFFF0000000000000 monotonic424  ret double %res425}426 427define double @no_sat_fminimum_inf(ptr %addr) {428; CHECK-LABEL: @no_sat_fminimum_inf(429; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fminimum ptr [[ADDR:%.*]], double 1.000000e-01 monotonic, align 8430; CHECK-NEXT:    ret double [[RES]]431;432  %res = atomicrmw fminimum ptr %addr, double 1.000000e-01 monotonic433  ret double %res434}435 436; Idempotent atomicrmw are still canonicalized.437define i32 @atomic_add_zero_preserve_md(ptr %addr) {438; CHECK-LABEL: @atomic_add_zero_preserve_md(439; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 syncscope("agent") monotonic, align 4, !mmra [[META0:![0-9]+]], !amdgpu.no.fine.grained.host.memory [[META1:![0-9]+]], !amdgpu.no.remote.memory.access [[META1]]440; CHECK-NEXT:    ret i32 [[RES]]441;442  %res = atomicrmw add ptr %addr, i32 0 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1443  ret i32 %res444}445 446define i32 @atomic_or_zero_preserve_md(ptr %addr) {447; CHECK-LABEL: @atomic_or_zero_preserve_md(448; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]449; CHECK-NEXT:    ret i32 [[RES]]450;451  %res = atomicrmw or ptr %addr, i32 0 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1452  ret i32 %res453}454 455; Idempotent atomicrmw are still canonicalized.456define i32 @atomic_sub_zero_preserve_md(ptr %addr) {457; CHECK-LABEL: @atomic_sub_zero_preserve_md(458; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]459; CHECK-NEXT:    ret i32 [[RES]]460;461  %res = atomicrmw sub ptr %addr, i32 0 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1462  ret i32 %res463}464 465; Idempotent atomicrmw are still canonicalized.466define i32 @atomic_and_allones_preserve_md(ptr %addr) {467; CHECK-LABEL: @atomic_and_allones_preserve_md(468; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]469; CHECK-NEXT:    ret i32 [[RES]]470;471  %res = atomicrmw and ptr %addr, i32 -1 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1472  ret i32 %res473}474 475; Idempotent atomicrmw are still canonicalized.476define i32 @atomic_umin_uint_max_preserve_md(ptr %addr) {477; CHECK-LABEL: @atomic_umin_uint_max_preserve_md(478; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]479; CHECK-NEXT:    ret i32 [[RES]]480;481  %res = atomicrmw umin ptr %addr, i32 -1 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1482  ret i32 %res483}484 485; Idempotent atomicrmw are still canonicalized.486define i32 @atomic_umax_zero_preserve_md(ptr %addr) {487; CHECK-LABEL: @atomic_umax_zero_preserve_md(488; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 0 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]489; CHECK-NEXT:    ret i32 [[RES]]490;491  %res = atomicrmw umax ptr %addr, i32 0 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1492  ret i32 %res493}494 495; Idempotent atomicrmw are still canonicalized.496define i8 @atomic_min_smax_char_preserve_md(ptr %addr) {497; CHECK-LABEL: @atomic_min_smax_char_preserve_md(498; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i8 0 syncscope("agent") monotonic, align 1, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]499; CHECK-NEXT:    ret i8 [[RES]]500;501  %res = atomicrmw min ptr %addr, i8 127 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1502  ret i8 %res503}504 505; Idempotent atomicrmw are still canonicalized.506define i8 @atomic_max_smin_char_preserve_md(ptr %addr) {507; CHECK-LABEL: @atomic_max_smin_char_preserve_md(508; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i8 0 syncscope("agent") monotonic, align 1, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]509; CHECK-NEXT:    ret i8 [[RES]]510;511  %res = atomicrmw max ptr %addr, i8 -128 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1512  ret i8 %res513}514 515; Idempotent atomicrmw are still canonicalized.516define float @atomic_fsub_zero_preserve_md(ptr %addr) {517; CHECK-LABEL: @atomic_fsub_zero_preserve_md(518; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float -0.000000e+00 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]519; CHECK-NEXT:    ret float [[RES]]520;521  %res = atomicrmw fsub ptr %addr, float 0.0 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1522  ret float %res523}524 525define float @atomic_fadd_zero_preserve_md(ptr %addr) {526; CHECK-LABEL: @atomic_fadd_zero_preserve_md(527; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float -0.000000e+00 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]528; CHECK-NEXT:    ret float [[RES]]529;530  %res = atomicrmw fadd ptr %addr, float -0.0 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1531  ret float %res532}533 534; Idempotent atomicrmw are still canonicalized.535define float @atomic_fsub_canon_preserve_md(ptr %addr) {536; CHECK-LABEL: @atomic_fsub_canon_preserve_md(537; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float -0.000000e+00 release, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]538; CHECK-NEXT:    ret float [[RES]]539;540  %res = atomicrmw fsub ptr %addr, float 0.0 release, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1541  ret float %res542}543 544define float @atomic_fadd_canon_preserve_md(ptr %addr) {545; CHECK-LABEL: @atomic_fadd_canon_preserve_md(546; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fadd ptr [[ADDR:%.*]], float -0.000000e+00 release, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]547; CHECK-NEXT:    ret float [[RES]]548;549  %res = atomicrmw fadd ptr %addr, float -0.0 release, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1550  ret float %res551}552 553; Can't replace a volatile w/a load; this would eliminate a volatile store.554define i64 @atomic_sub_zero_volatile_preserve_md(ptr %addr) {555; CHECK-LABEL: @atomic_sub_zero_volatile_preserve_md(556; CHECK-NEXT:    [[RES:%.*]] = atomicrmw volatile sub ptr [[ADDR:%.*]], i64 0 acquire, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]557; CHECK-NEXT:    ret i64 [[RES]]558;559  %res = atomicrmw volatile sub ptr %addr, i64 0 acquire, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1560  ret i64 %res561}562 563 564; Check that the transformation properly preserve the syncscope.565; Idempotent atomicrmw are still canonicalized.566define i16 @atomic_syncscope_preserve_md(ptr %addr) {567; CHECK-LABEL: @atomic_syncscope_preserve_md(568; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i16 0 syncscope("some_syncscope") acquire, align 2, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]569; CHECK-NEXT:    ret i16 [[RES]]570;571  %res = atomicrmw or ptr %addr, i16 0 syncscope("some_syncscope") acquire, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1572  ret i16 %res573}574 575; By eliminating the store part of the atomicrmw, we would get rid of the576; release semantic, which is incorrect.  We can canonicalize the operation.577define i16 @atomic_seq_cst_preserve_md(ptr %addr) {578; CHECK-LABEL: @atomic_seq_cst_preserve_md(579; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i16 0 seq_cst, align 2, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]580; CHECK-NEXT:    ret i16 [[RES]]581;582  %res = atomicrmw add ptr %addr, i16 0 seq_cst, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1583  ret i16 %res584}585 586; Check that the transformation does not apply when the value is changed by587; the atomic operation (non zero constant).588define i16 @atomic_add_non_zero_preserve_md(ptr %addr) {589; CHECK-LABEL: @atomic_add_non_zero_preserve_md(590; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr [[ADDR:%.*]], i16 2 syncscope("agent") monotonic, align 2, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]591; CHECK-NEXT:    ret i16 [[RES]]592;593  %res = atomicrmw add ptr %addr, i16 2 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1594  ret i16 %res595}596 597; Idempotent atomicrmw are still canonicalized.598define i16 @atomic_xor_zero_preserve_md(ptr %addr) {599; CHECK-LABEL: @atomic_xor_zero_preserve_md(600; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i16 0 syncscope("agent") monotonic, align 2, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]601; CHECK-NEXT:    ret i16 [[RES]]602;603  %res = atomicrmw xor ptr %addr, i16 0 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1604  ret i16 %res605}606 607; Check that the transformation does not apply when the ordering is608; incompatible with a load (release).  Do canonicalize.609define i16 @atomic_release_preserve_md(ptr %addr) {610; CHECK-LABEL: @atomic_release_preserve_md(611; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i16 0 release, align 2, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]612; CHECK-NEXT:    ret i16 [[RES]]613;614  %res = atomicrmw sub ptr %addr, i16 0 release, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1615  ret i16 %res616}617 618; Check that the transformation does not apply when the ordering is619; incompatible with a load (acquire, release).  Do canonicalize.620define i16 @atomic_acq_rel_preserve_md(ptr %addr) {621; CHECK-LABEL: @atomic_acq_rel_preserve_md(622; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i16 0 acq_rel, align 2, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]623; CHECK-NEXT:    ret i16 [[RES]]624;625  %res = atomicrmw xor ptr %addr, i16 0 acq_rel, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1626  ret i16 %res627}628 629define i32 @sat_or_allones_preserve_md(ptr %addr) {630; CHECK-LABEL: @sat_or_allones_preserve_md(631; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]632; CHECK-NEXT:    ret i32 [[RES]]633;634  %res = atomicrmw or ptr %addr, i32 -1 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1635  ret i32 %res636}637 638define i32 @sat_and_zero_preserve_md(ptr %addr) {639; CHECK-LABEL: @sat_and_zero_preserve_md(640; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 0 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]641; CHECK-NEXT:    ret i32 [[RES]]642;643  %res = atomicrmw and ptr %addr, i32 0 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1644  ret i32 %res645}646 647define i32 @sat_umin_uint_min_preserve_md(ptr %addr) {648; CHECK-LABEL: @sat_umin_uint_min_preserve_md(649; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 0 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]650; CHECK-NEXT:    ret i32 [[RES]]651;652  %res = atomicrmw umin ptr %addr, i32 0 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1653  ret i32 %res654}655 656define i32 @sat_umax_uint_max_preserve_md(ptr %addr) {657; CHECK-LABEL: @sat_umax_uint_max_preserve_md(658; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]659; CHECK-NEXT:    ret i32 [[RES]]660;661  %res = atomicrmw umax ptr %addr, i32 -1 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1662  ret i32 %res663}664 665define i8 @sat_min_smin_char_preserve_md(ptr %addr) {666; CHECK-LABEL: @sat_min_smin_char_preserve_md(667; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i8 -128 syncscope("agent") monotonic, align 1, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]668; CHECK-NEXT:    ret i8 [[RES]]669;670  %res = atomicrmw min ptr %addr, i8 -128 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1671  ret i8 %res672}673 674define i8 @sat_max_smax_char_preserve_md(ptr %addr) {675; CHECK-LABEL: @sat_max_smax_char_preserve_md(676; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i8 127 syncscope("agent") monotonic, align 1, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]677; CHECK-NEXT:    ret i8 [[RES]]678;679  %res = atomicrmw max ptr %addr, i8 127 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1680  ret i8 %res681}682 683define double @sat_fadd_nan_preserve_md(ptr %addr) {684; CHECK-LABEL: @sat_fadd_nan_preserve_md(685; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], double 0x7FF00000FFFFFFFF release, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]686; CHECK-NEXT:    ret double [[RES]]687;688  %res = atomicrmw fadd ptr %addr, double 0x7FF00000FFFFFFFF release, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1689  ret double %res690}691 692define double @sat_fsub_nan_preserve_md(ptr %addr) {693; CHECK-LABEL: @sat_fsub_nan_preserve_md(694; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], double 0x7FF00000FFFFFFFF release, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]695; CHECK-NEXT:    ret double [[RES]]696;697  %res = atomicrmw fsub ptr %addr, double 0x7FF00000FFFFFFFF release, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1698  ret double %res699}700 701define void @sat_fsub_nan_unused_preserve_md(ptr %addr) {702; CHECK-LABEL: @sat_fsub_nan_unused_preserve_md(703; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], double 0x7FF00000FFFFFFFF syncscope("agent") monotonic, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]704; CHECK-NEXT:    ret void705;706  atomicrmw fsub ptr %addr, double 0x7FF00000FFFFFFFF syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1707  ret void708}709 710define void @xchg_unused_monotonic_preserve_md(ptr %addr) {711; CHECK-LABEL: @xchg_unused_monotonic_preserve_md(712; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 0 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]713; CHECK-NEXT:    ret void714;715  atomicrmw xchg ptr %addr, i32 0 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1716  ret void717}718 719define void @xchg_unused_release_preserve_md(ptr %addr) {720; CHECK-LABEL: @xchg_unused_release_preserve_md(721; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 syncscope("agent") release, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]722; CHECK-NEXT:    ret void723;724  atomicrmw xchg ptr %addr, i32 -1 syncscope("agent") release, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1725  ret void726}727 728define void @xchg_unused_under_aligned_preserve_md(ptr %addr) {729; CHECK-LABEL: @xchg_unused_under_aligned_preserve_md(730; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 syncscope("agent") release, align 1, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]731; CHECK-NEXT:    ret void732;733  atomicrmw xchg ptr %addr, i32 -1 syncscope("agent") release, align 1, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1734  ret void735}736 737define void @xchg_unused_over_aligned_preserve_md(ptr %addr) {738; CHECK-LABEL: @xchg_unused_over_aligned_preserve_md(739; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 syncscope("agent") release, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]740; CHECK-NEXT:    ret void741;742  atomicrmw xchg ptr %addr, i32 -1 syncscope("agent") release, align 8, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1743  ret void744}745 746define void @xchg_unused_seq_cst_preserve_md(ptr %addr) {747; CHECK-LABEL: @xchg_unused_seq_cst_preserve_md(748; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 0 syncscope("agent") seq_cst, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]749; CHECK-NEXT:    ret void750;751  atomicrmw xchg ptr %addr, i32 0 syncscope("agent") seq_cst, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1752  ret void753}754 755define void @xchg_unused_volatile_preserve_md(ptr %addr) {756; CHECK-LABEL: @xchg_unused_volatile_preserve_md(757; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw volatile xchg ptr [[ADDR:%.*]], i32 0 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]758; CHECK-NEXT:    ret void759;760  atomicrmw volatile xchg ptr %addr, i32 0 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1761  ret void762}763 764define void @sat_or_allones_unused_preserve_md(ptr %addr) {765; CHECK-LABEL: @sat_or_allones_unused_preserve_md(766; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], i32 -1 syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]767; CHECK-NEXT:    ret void768;769  atomicrmw or ptr %addr, i32 -1 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1770  ret void771}772 773define void @undef_operand_unused_preserve_md(ptr %addr) {774; CHECK-LABEL: @undef_operand_unused_preserve_md(775; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 undef syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]776; CHECK-NEXT:    ret void777;778  atomicrmw or ptr %addr, i32 undef syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1779  ret void780}781 782define i32 @undef_operand_used_preserve_md(ptr %addr) {783; CHECK-LABEL: @undef_operand_used_preserve_md(784; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr [[ADDR:%.*]], i32 undef syncscope("agent") monotonic, align 4, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]785; CHECK-NEXT:    ret i32 [[RES]]786;787  %res = atomicrmw or ptr %addr, i32 undef syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1788  ret i32 %res789}790 791define double @sat_fmax_inf_preserve_md(ptr %addr) {792; CHECK-LABEL: @sat_fmax_inf_preserve_md(793; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], double 0x7FF0000000000000 syncscope("agent") monotonic, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]794; CHECK-NEXT:    ret double [[RES]]795;796  %res = atomicrmw fmax ptr %addr, double 0x7FF0000000000000 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1797  ret double %res798}799 800define double @no_sat_fmax_inf_preserve_md(ptr %addr) {801; CHECK-LABEL: @no_sat_fmax_inf_preserve_md(802; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fmax ptr [[ADDR:%.*]], double 1.000000e-01 syncscope("agent") monotonic, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]803; CHECK-NEXT:    ret double [[RES]]804;805  %res = atomicrmw fmax ptr %addr, double 1.000000e-01 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1806  ret double %res807}808 809define double @sat_fmin_inf_preserve_md(ptr %addr) {810; CHECK-LABEL: @sat_fmin_inf_preserve_md(811; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xchg ptr [[ADDR:%.*]], double 0xFFF0000000000000 syncscope("agent") monotonic, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]812; CHECK-NEXT:    ret double [[RES]]813;814  %res = atomicrmw fmin ptr %addr, double 0xFFF0000000000000 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1815  ret double %res816}817 818define double @no_sat_fmin_inf_preserve_md(ptr %addr) {819; CHECK-LABEL: @no_sat_fmin_inf_preserve_md(820; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fmin ptr [[ADDR:%.*]], double 1.000000e-01 syncscope("agent") monotonic, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]821; CHECK-NEXT:    ret double [[RES]]822;823  %res = atomicrmw fmin ptr %addr, double 1.000000e-01 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1824  ret double %res825}826 827define double @sat_fmaximum_inf_preserve_md(ptr %addr) {828; CHECK-LABEL: @sat_fmaximum_inf_preserve_md(829; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fmaximum ptr [[ADDR:%.*]], double 0x7FF0000000000000 syncscope("agent") monotonic, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]830; CHECK-NEXT:    ret double [[RES]]831;832  %res = atomicrmw fmaximum ptr %addr, double 0x7FF0000000000000 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1833  ret double %res834}835 836define double @no_sat_fmaximum_inf_preserve_md(ptr %addr) {837; CHECK-LABEL: @no_sat_fmaximum_inf_preserve_md(838; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fmaximum ptr [[ADDR:%.*]], double 1.000000e-01 syncscope("agent") monotonic, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]839; CHECK-NEXT:    ret double [[RES]]840;841  %res = atomicrmw fmaximum ptr %addr, double 1.000000e-01 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1842  ret double %res843}844 845define double @sat_fminimum_inf_preserve_md(ptr %addr) {846; CHECK-LABEL: @sat_fminimum_inf_preserve_md(847; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fminimum ptr [[ADDR:%.*]], double 0xFFF0000000000000 syncscope("agent") monotonic, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]848; CHECK-NEXT:    ret double [[RES]]849;850  %res = atomicrmw fminimum ptr %addr, double 0xFFF0000000000000 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1851  ret double %res852}853 854define double @no_sat_fminimum_inf_preserve_md(ptr %addr) {855; CHECK-LABEL: @no_sat_fminimum_inf_preserve_md(856; CHECK-NEXT:    [[RES:%.*]] = atomicrmw fminimum ptr [[ADDR:%.*]], double 1.000000e-01 syncscope("agent") monotonic, align 8, !mmra [[META0]], !amdgpu.no.fine.grained.host.memory [[META1]], !amdgpu.no.remote.memory.access [[META1]]857; CHECK-NEXT:    ret double [[RES]]858;859  %res = atomicrmw fminimum ptr %addr, double 1.000000e-01 syncscope("agent") monotonic, !amdgpu.no.fine.grained.host.memory !0, !amdgpu.no.remote.memory.access !0, !mmra !1860  ret double %res861}862 863!0 = !{}864!1 = !{!"foo", !"bar"}865