1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=hawaii -passes=atomic-expand %s | FileCheck -check-prefixes=GCN,GFX7 %s 3; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -passes=atomic-expand %s | FileCheck -check-prefixes=GCN,GFX9 %s 4 5define float @test_atomicrmw_fmax_f32_flat(ptr %ptr, float %value) { 6; GCN-LABEL: @test_atomicrmw_fmax_f32_flat( 7; GCN-NEXT: [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4 8; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] 9; GCN: atomicrmw.start: 10; GCN-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] 11; GCN-NEXT: [[TMP2:%.*]] = call float @llvm.maxnum.f32(float [[LOADED]], float [[VALUE:%.*]]) 12; GCN-NEXT: [[TMP3:%.*]] = bitcast float [[TMP2]] to i32 13; GCN-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 14; GCN-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4 15; GCN-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 16; GCN-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 17; GCN-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float 18; GCN-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 19; GCN: atomicrmw.end: 20; GCN-NEXT: ret float [[TMP6]] 21; 22 %res = atomicrmw fmax ptr %ptr, float %value seq_cst 23 ret float %res 24} 25 26define float @test_atomicrmw_fmax_f32_global(ptr addrspace(1) %ptr, float %value) { 27; GCN-LABEL: @test_atomicrmw_fmax_f32_global( 28; GCN-NEXT: [[TMP1:%.*]] = load float, ptr addrspace(1) [[PTR:%.*]], align 4 29; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] 30; GCN: atomicrmw.start: 31; GCN-NEXT: [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] 32; GCN-NEXT: [[TMP2:%.*]] = call float @llvm.maxnum.f32(float [[LOADED]], float [[VALUE:%.*]]) 33; GCN-NEXT: [[TMP3:%.*]] = bitcast float [[TMP2]] to i32 34; GCN-NEXT: [[TMP4:%.*]] = bitcast float [[LOADED]] to i32 35; GCN-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4 36; GCN-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 37; GCN-NEXT: [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0 38; GCN-NEXT: [[TMP6]] = bitcast i32 [[NEWLOADED]] to float 39; GCN-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 40; GCN: atomicrmw.end: 41; GCN-NEXT: ret float [[TMP6]] 42; 43 %res = atomicrmw fmax ptr addrspace(1) %ptr, float %value seq_cst 44 ret float %res 45} 46 47define float @test_atomicrmw_fmax_f32_local(ptr addrspace(3) %ptr, float %value) { 48; GCN-LABEL: @test_atomicrmw_fmax_f32_local( 49; GCN-NEXT: [[RES:%.*]] = atomicrmw fmax ptr addrspace(3) [[PTR:%.*]], float [[VALUE:%.*]] seq_cst, align 4 50; GCN-NEXT: ret float [[RES]] 51; 52 %res = atomicrmw fmax ptr addrspace(3) %ptr, float %value seq_cst 53 ret float %res 54} 55 56define half @test_atomicrmw_fmax_f16_flat(ptr %ptr, half %value) { 57; GCN-LABEL: @test_atomicrmw_fmax_f16_flat( 58; GCN-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4) 59; GCN-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64 60; GCN-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 61; GCN-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 62; GCN-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 63; GCN-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]] 64; GCN-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 65; GCN-NEXT: [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4 66; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] 67; GCN: atomicrmw.start: 68; GCN-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 69; GCN-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 70; GCN-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16 71; GCN-NEXT: [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to half 72; GCN-NEXT: [[TMP5:%.*]] = call half @llvm.maxnum.f16(half [[TMP4]], half [[VALUE:%.*]]) 73; GCN-NEXT: [[TMP6:%.*]] = bitcast half [[TMP5]] to i16 74; GCN-NEXT: [[EXTENDED:%.*]] = zext i16 [[TMP6]] to i32 75; GCN-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 76; GCN-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 77; GCN-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 78; GCN-NEXT: [[TMP7:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 79; GCN-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1 80; GCN-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP7]], 0 81; GCN-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 82; GCN: atomicrmw.end: 83; GCN-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 84; GCN-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16 85; GCN-NEXT: [[TMP8:%.*]] = bitcast i16 [[EXTRACTED3]] to half 86; GCN-NEXT: ret half [[TMP8]] 87; 88 %res = atomicrmw fmax ptr %ptr, half %value seq_cst 89 ret half %res 90} 91 92define half @test_atomicrmw_fmax_f16_global(ptr addrspace(1) %ptr, half %value) { 93; GCN-LABEL: @test_atomicrmw_fmax_f16_global( 94; GCN-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 95; GCN-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 96; GCN-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 97; GCN-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 98; GCN-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 99; GCN-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]] 100; GCN-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 101; GCN-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 102; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] 103; GCN: atomicrmw.start: 104; GCN-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 105; GCN-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 106; GCN-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16 107; GCN-NEXT: [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to half 108; GCN-NEXT: [[TMP5:%.*]] = call half @llvm.maxnum.f16(half [[TMP4]], half [[VALUE:%.*]]) 109; GCN-NEXT: [[TMP6:%.*]] = bitcast half [[TMP5]] to i16 110; GCN-NEXT: [[EXTENDED:%.*]] = zext i16 [[TMP6]] to i32 111; GCN-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 112; GCN-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 113; GCN-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 114; GCN-NEXT: [[TMP7:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 115; GCN-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1 116; GCN-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP7]], 0 117; GCN-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 118; GCN: atomicrmw.end: 119; GCN-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 120; GCN-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16 121; GCN-NEXT: [[TMP8:%.*]] = bitcast i16 [[EXTRACTED3]] to half 122; GCN-NEXT: ret half [[TMP8]] 123; 124 %res = atomicrmw fmax ptr addrspace(1) %ptr, half %value seq_cst 125 ret half %res 126} 127 128define half @test_atomicrmw_fmax_f16_global_align4(ptr addrspace(1) %ptr, half %value) { 129; GCN-LABEL: @test_atomicrmw_fmax_f16_global_align4( 130; GCN-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4 131; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] 132; GCN: atomicrmw.start: 133; GCN-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 134; GCN-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i16 135; GCN-NEXT: [[TMP2:%.*]] = bitcast i16 [[EXTRACTED]] to half 136; GCN-NEXT: [[TMP3:%.*]] = call half @llvm.maxnum.f16(half [[TMP2]], half [[VALUE:%.*]]) 137; GCN-NEXT: [[TMP4:%.*]] = bitcast half [[TMP3]] to i16 138; GCN-NEXT: [[EXTENDED:%.*]] = zext i16 [[TMP4]] to i32 139; GCN-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], -65536 140; GCN-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]] 141; GCN-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 142; GCN-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 143; GCN-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP5]], 0 144; GCN-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 145; GCN: atomicrmw.end: 146; GCN-NEXT: [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i16 147; GCN-NEXT: [[TMP6:%.*]] = bitcast i16 [[EXTRACTED1]] to half 148; GCN-NEXT: ret half [[TMP6]] 149; 150 %res = atomicrmw fmax ptr addrspace(1) %ptr, half %value seq_cst, align 4 151 ret half %res 152} 153 154define half @test_atomicrmw_fmax_f16_local(ptr addrspace(3) %ptr, half %value) { 155; GCN-LABEL: @test_atomicrmw_fmax_f16_local( 156; GCN-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(3) @llvm.ptrmask.p3.i32(ptr addrspace(3) [[PTR:%.*]], i32 -4) 157; GCN-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(3) [[PTR]] to i32 158; GCN-NEXT: [[PTRLSB:%.*]] = and i32 [[TMP1]], 3 159; GCN-NEXT: [[TMP2:%.*]] = shl i32 [[PTRLSB]], 3 160; GCN-NEXT: [[MASK:%.*]] = shl i32 65535, [[TMP2]] 161; GCN-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 162; GCN-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(3) [[ALIGNEDADDR]], align 4 163; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] 164; GCN: atomicrmw.start: 165; GCN-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 166; GCN-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[TMP2]] 167; GCN-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16 168; GCN-NEXT: [[TMP4:%.*]] = bitcast i16 [[EXTRACTED]] to half 169; GCN-NEXT: [[TMP5:%.*]] = call half @llvm.maxnum.f16(half [[TMP4]], half [[VALUE:%.*]]) 170; GCN-NEXT: [[TMP6:%.*]] = bitcast half [[TMP5]] to i16 171; GCN-NEXT: [[EXTENDED:%.*]] = zext i16 [[TMP6]] to i32 172; GCN-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[TMP2]] 173; GCN-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 174; GCN-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 175; GCN-NEXT: [[TMP7:%.*]] = cmpxchg ptr addrspace(3) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 176; GCN-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1 177; GCN-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP7]], 0 178; GCN-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 179; GCN: atomicrmw.end: 180; GCN-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[TMP2]] 181; GCN-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i16 182; GCN-NEXT: [[TMP8:%.*]] = bitcast i16 [[EXTRACTED3]] to half 183; GCN-NEXT: ret half [[TMP8]] 184; 185 %res = atomicrmw fmax ptr addrspace(3) %ptr, half %value seq_cst 186 ret half %res 187} 188 189define double @test_atomicrmw_fmax_f64_flat(ptr %ptr, double %value) { 190; GCN-LABEL: @test_atomicrmw_fmax_f64_flat( 191; GCN-NEXT: [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[PTR:%.*]]) 192; GCN-NEXT: br i1 [[IS_PRIVATE]], label [[ATOMICRMW_PRIVATE:%.*]], label [[ATOMICRMW_GLOBAL:%.*]] 193; GCN: atomicrmw.private: 194; GCN-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[PTR]] to ptr addrspace(5) 195; GCN-NEXT: [[LOADED_PRIVATE:%.*]] = load double, ptr addrspace(5) [[TMP1]], align 8 196; GCN-NEXT: [[TMP2:%.*]] = call double @llvm.maxnum.f64(double [[LOADED_PRIVATE]], double [[VALUE:%.*]]) 197; GCN-NEXT: store double [[TMP2]], ptr addrspace(5) [[TMP1]], align 8 198; GCN-NEXT: br label [[ATOMICRMW_PHI:%.*]] 199; GCN: atomicrmw.global: 200; GCN-NEXT: [[TMP3:%.*]] = load double, ptr [[PTR]], align 8 201; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] 202; GCN: atomicrmw.start: 203; GCN-NEXT: [[LOADED:%.*]] = phi double [ [[TMP3]], [[ATOMICRMW_GLOBAL]] ], [ [[TMP8:%.*]], [[ATOMICRMW_START]] ] 204; GCN-NEXT: [[TMP4:%.*]] = call double @llvm.maxnum.f64(double [[LOADED]], double [[VALUE]]) 205; GCN-NEXT: [[TMP5:%.*]] = bitcast double [[TMP4]] to i64 206; GCN-NEXT: [[TMP6:%.*]] = bitcast double [[LOADED]] to i64 207; GCN-NEXT: [[TMP7:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP6]], i64 [[TMP5]] seq_cst seq_cst, align 8, !noalias.addrspace [[META0:![0-9]+]] 208; GCN-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP7]], 1 209; GCN-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP7]], 0 210; GCN-NEXT: [[TMP8]] = bitcast i64 [[NEWLOADED]] to double 211; GCN-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END1:%.*]], label [[ATOMICRMW_START]] 212; GCN: atomicrmw.end1: 213; GCN-NEXT: br label [[ATOMICRMW_PHI]] 214; GCN: atomicrmw.phi: 215; GCN-NEXT: [[RES:%.*]] = phi double [ [[LOADED_PRIVATE]], [[ATOMICRMW_PRIVATE]] ], [ [[TMP8]], [[ATOMICRMW_END1]] ] 216; GCN-NEXT: br label [[ATOMICRMW_END:%.*]] 217; GCN: atomicrmw.end: 218; GCN-NEXT: ret double [[RES]] 219; 220 %res = atomicrmw fmax ptr %ptr, double %value seq_cst 221 ret double %res 222} 223 224define double @test_atomicrmw_fmax_f64_flat__noprivate(ptr %ptr, double %value) { 225; GCN-LABEL: @test_atomicrmw_fmax_f64_flat__noprivate( 226; GCN-NEXT: [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8 227; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] 228; GCN: atomicrmw.start: 229; GCN-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] 230; GCN-NEXT: [[TMP2:%.*]] = call double @llvm.maxnum.f64(double [[LOADED]], double [[VALUE:%.*]]) 231; GCN-NEXT: [[TMP3:%.*]] = bitcast double [[TMP2]] to i64 232; GCN-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 233; GCN-NEXT: [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8, !noalias.addrspace [[META0]] 234; GCN-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 235; GCN-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 236; GCN-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double 237; GCN-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 238; GCN: atomicrmw.end: 239; GCN-NEXT: ret double [[TMP6]] 240; 241 %res = atomicrmw fmax ptr %ptr, double %value seq_cst, !noalias.addrspace !0 242 ret double %res 243} 244 245define double @test_atomicrmw_fmax_f64_global(ptr addrspace(1) %ptr, double %value) { 246; GCN-LABEL: @test_atomicrmw_fmax_f64_global( 247; GCN-NEXT: [[TMP1:%.*]] = load double, ptr addrspace(1) [[PTR:%.*]], align 8 248; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] 249; GCN: atomicrmw.start: 250; GCN-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] 251; GCN-NEXT: [[TMP2:%.*]] = call double @llvm.maxnum.f64(double [[LOADED]], double [[VALUE:%.*]]) 252; GCN-NEXT: [[TMP3:%.*]] = bitcast double [[TMP2]] to i64 253; GCN-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 254; GCN-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8 255; GCN-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 256; GCN-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 257; GCN-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double 258; GCN-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 259; GCN: atomicrmw.end: 260; GCN-NEXT: ret double [[TMP6]] 261; 262 %res = atomicrmw fmax ptr addrspace(1) %ptr, double %value seq_cst 263 ret double %res 264} 265 266define double @test_atomicrmw_fmax_f64_local(ptr addrspace(3) %ptr, double %value) { 267; GCN-LABEL: @test_atomicrmw_fmax_f64_local( 268; GCN-NEXT: [[RES:%.*]] = atomicrmw fmax ptr addrspace(3) [[PTR:%.*]], double [[VALUE:%.*]] seq_cst, align 8 269; GCN-NEXT: ret double [[RES]] 270; 271 %res = atomicrmw fmax ptr addrspace(3) %ptr, double %value seq_cst 272 ret double %res 273} 274 275define double @test_atomicrmw_fmax_f64_global_strictfp(ptr addrspace(1) %ptr, double %value) strictfp { 276; GCN-LABEL: @test_atomicrmw_fmax_f64_global_strictfp( 277; GCN-NEXT: [[TMP1:%.*]] = load double, ptr addrspace(1) [[PTR:%.*]], align 8 278; GCN-NEXT: br label [[ATOMICRMW_START:%.*]] 279; GCN: atomicrmw.start: 280; GCN-NEXT: [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ] 281; GCN-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.maxnum.f64(double [[LOADED]], double [[VALUE:%.*]], metadata !"fpexcept.strict") #[[ATTR4:[0-9]+]] 282; GCN-NEXT: [[TMP3:%.*]] = bitcast double [[TMP2]] to i64 283; GCN-NEXT: [[TMP4:%.*]] = bitcast double [[LOADED]] to i64 284; GCN-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8 285; GCN-NEXT: [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1 286; GCN-NEXT: [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0 287; GCN-NEXT: [[TMP6]] = bitcast i64 [[NEWLOADED]] to double 288; GCN-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 289; GCN: atomicrmw.end: 290; GCN-NEXT: ret double [[TMP6]] 291; 292 %res = atomicrmw fmax ptr addrspace(1) %ptr, double %value seq_cst 293 ret double %res 294} 295 296!0 = !{i32 5, i32 6} 297 298;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: 299; GFX7: {{.*}} 300; GFX9: {{.*}} 301