1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -mtriple=amdgcn-amd-amdhsa -S -passes=atomic-expand %s | FileCheck %s 3 4define i8 @test_atomicrmw_xchg_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 5; CHECK-LABEL: @test_atomicrmw_xchg_i8_global_system( 6; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 7; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 8; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 9; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 10; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 11; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 12; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 13; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32 14; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 15; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 16; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 17; CHECK: atomicrmw.start: 18; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP4]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 19; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 20; CHECK-NEXT: [[TMP6:%.*]] = or i32 [[TMP5]], [[VALOPERAND_SHIFTED]] 21; CHECK-NEXT: [[TMP7:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[TMP6]] seq_cst seq_cst, align 4 22; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1 23; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP7]], 0 24; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 25; CHECK: atomicrmw.end: 26; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 27; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 28; CHECK-NEXT: ret i8 [[EXTRACTED]] 29; 30 %res = atomicrmw xchg ptr addrspace(1) %ptr, i8 %value seq_cst 31 ret i8 %res 32} 33 34define i8 @test_atomicrmw_add_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 35; CHECK-LABEL: @test_atomicrmw_add_i8_global_system( 36; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 37; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 38; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 39; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 40; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 41; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 42; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 43; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32 44; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 45; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 46; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 47; CHECK: atomicrmw.start: 48; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP4]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 49; CHECK-NEXT: [[NEW:%.*]] = add i32 [[LOADED]], [[VALOPERAND_SHIFTED]] 50; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[NEW]], [[MASK]] 51; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 52; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP6]], [[TMP5]] 53; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[TMP7]] seq_cst seq_cst, align 4 54; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1 55; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0 56; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 57; CHECK: atomicrmw.end: 58; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 59; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 60; CHECK-NEXT: ret i8 [[EXTRACTED]] 61; 62 %res = atomicrmw add ptr addrspace(1) %ptr, i8 %value seq_cst 63 ret i8 %res 64} 65 66define i8 @test_atomicrmw_add_i8_global_system_align2(ptr addrspace(1) %ptr, i8 %value) { 67; CHECK-LABEL: @test_atomicrmw_add_i8_global_system_align2( 68; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 69; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 70; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 71; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 72; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 73; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 74; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 75; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32 76; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 77; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 78; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 79; CHECK: atomicrmw.start: 80; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP4]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 81; CHECK-NEXT: [[NEW:%.*]] = add i32 [[LOADED]], [[VALOPERAND_SHIFTED]] 82; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[NEW]], [[MASK]] 83; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 84; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP6]], [[TMP5]] 85; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[TMP7]] seq_cst seq_cst, align 4 86; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1 87; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0 88; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 89; CHECK: atomicrmw.end: 90; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 91; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 92; CHECK-NEXT: ret i8 [[EXTRACTED]] 93; 94 %res = atomicrmw add ptr addrspace(1) %ptr, i8 %value seq_cst, align 2 95 ret i8 %res 96} 97 98define i8 @test_atomicrmw_add_i8_global_system_align4(ptr addrspace(1) %ptr, i8 %value) { 99; CHECK-LABEL: @test_atomicrmw_add_i8_global_system_align4( 100; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[VALUE:%.*]] to i32 101; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4 102; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 103; CHECK: atomicrmw.start: 104; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP2]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 105; CHECK-NEXT: [[NEW:%.*]] = add i32 [[LOADED]], [[TMP1]] 106; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[NEW]], 255 107; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[LOADED]], -256 108; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP4]], [[TMP3]] 109; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[TMP5]] seq_cst seq_cst, align 4 110; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1 111; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0 112; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 113; CHECK: atomicrmw.end: 114; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[NEWLOADED]] to i8 115; CHECK-NEXT: ret i8 [[EXTRACTED]] 116; 117 %res = atomicrmw add ptr addrspace(1) %ptr, i8 %value seq_cst, align 4 118 ret i8 %res 119} 120 121define i8 @test_atomicrmw_sub_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 122; CHECK-LABEL: @test_atomicrmw_sub_i8_global_system( 123; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 124; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 125; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 126; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 127; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 128; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 129; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 130; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32 131; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 132; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 133; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 134; CHECK: atomicrmw.start: 135; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP4]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 136; CHECK-NEXT: [[NEW:%.*]] = sub i32 [[LOADED]], [[VALOPERAND_SHIFTED]] 137; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[NEW]], [[MASK]] 138; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 139; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP6]], [[TMP5]] 140; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[TMP7]] seq_cst seq_cst, align 4 141; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1 142; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0 143; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 144; CHECK: atomicrmw.end: 145; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 146; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 147; CHECK-NEXT: ret i8 [[EXTRACTED]] 148; 149 %res = atomicrmw sub ptr addrspace(1) %ptr, i8 %value seq_cst 150 ret i8 %res 151} 152 153define i8 @test_atomicrmw_and_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 154; CHECK-LABEL: @test_atomicrmw_and_i8_global_system( 155; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 156; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 157; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 158; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 159; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 160; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 161; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 162; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32 163; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 164; CHECK-NEXT: [[ANDOPERAND:%.*]] = or i32 [[VALOPERAND_SHIFTED]], [[INV_MASK]] 165; CHECK-NEXT: [[TMP4:%.*]] = atomicrmw and ptr addrspace(1) [[ALIGNEDADDR]], i32 [[ANDOPERAND]] seq_cst, align 4 166; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]] 167; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 168; CHECK-NEXT: ret i8 [[EXTRACTED]] 169; 170 %res = atomicrmw and ptr addrspace(1) %ptr, i8 %value seq_cst 171 ret i8 %res 172} 173 174define i8 @test_atomicrmw_nand_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 175; CHECK-LABEL: @test_atomicrmw_nand_i8_global_system( 176; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 177; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 178; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 179; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 180; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 181; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 182; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 183; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32 184; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 185; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 186; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 187; CHECK: atomicrmw.start: 188; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP4]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 189; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[LOADED]], [[VALOPERAND_SHIFTED]] 190; CHECK-NEXT: [[NEW:%.*]] = xor i32 [[TMP5]], -1 191; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[NEW]], [[MASK]] 192; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 193; CHECK-NEXT: [[TMP8:%.*]] = or i32 [[TMP7]], [[TMP6]] 194; CHECK-NEXT: [[TMP9:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[TMP8]] seq_cst seq_cst, align 4 195; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP9]], 1 196; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP9]], 0 197; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 198; CHECK: atomicrmw.end: 199; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 200; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 201; CHECK-NEXT: ret i8 [[EXTRACTED]] 202; 203 %res = atomicrmw nand ptr addrspace(1) %ptr, i8 %value seq_cst 204 ret i8 %res 205} 206 207define i8 @test_atomicrmw_or_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 208; CHECK-LABEL: @test_atomicrmw_or_i8_global_system( 209; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 210; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 211; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 212; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 213; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 214; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 215; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 216; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32 217; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 218; CHECK-NEXT: [[TMP4:%.*]] = atomicrmw or ptr addrspace(1) [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] seq_cst, align 4 219; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]] 220; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 221; CHECK-NEXT: ret i8 [[EXTRACTED]] 222; 223 %res = atomicrmw or ptr addrspace(1) %ptr, i8 %value seq_cst 224 ret i8 %res 225} 226 227define i8 @test_atomicrmw_xor_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 228; CHECK-LABEL: @test_atomicrmw_xor_i8_global_system( 229; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 230; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 231; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 232; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 233; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 234; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 235; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 236; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[VALUE:%.*]] to i32 237; CHECK-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 238; CHECK-NEXT: [[TMP4:%.*]] = atomicrmw xor ptr addrspace(1) [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] seq_cst, align 4 239; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]] 240; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 241; CHECK-NEXT: ret i8 [[EXTRACTED]] 242; 243 %res = atomicrmw xor ptr addrspace(1) %ptr, i8 %value seq_cst 244 ret i8 %res 245} 246 247define i8 @test_atomicrmw_max_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 248; CHECK-LABEL: @test_atomicrmw_max_i8_global_system( 249; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 250; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 251; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 252; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 253; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 254; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 255; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 256; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 257; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 258; CHECK: atomicrmw.start: 259; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 260; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 261; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 262; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i8 [[EXTRACTED]], [[VALUE:%.*]] 263; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP4]], i8 [[EXTRACTED]], i8 [[VALUE]] 264; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 265; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 266; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 267; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 268; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 269; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 270; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP5]], 0 271; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 272; CHECK: atomicrmw.end: 273; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 274; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 275; CHECK-NEXT: ret i8 [[EXTRACTED3]] 276; 277 %res = atomicrmw max ptr addrspace(1) %ptr, i8 %value seq_cst 278 ret i8 %res 279} 280 281define i8 @test_atomicrmw_min_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 282; CHECK-LABEL: @test_atomicrmw_min_i8_global_system( 283; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 284; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 285; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 286; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 287; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 288; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 289; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 290; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 291; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 292; CHECK: atomicrmw.start: 293; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 294; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 295; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 296; CHECK-NEXT: [[TMP4:%.*]] = icmp sle i8 [[EXTRACTED]], [[VALUE:%.*]] 297; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP4]], i8 [[EXTRACTED]], i8 [[VALUE]] 298; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 299; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 300; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 301; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 302; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 303; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 304; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP5]], 0 305; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 306; CHECK: atomicrmw.end: 307; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 308; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 309; CHECK-NEXT: ret i8 [[EXTRACTED3]] 310; 311 %res = atomicrmw min ptr addrspace(1) %ptr, i8 %value seq_cst 312 ret i8 %res 313} 314 315define i8 @test_atomicrmw_umax_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 316; CHECK-LABEL: @test_atomicrmw_umax_i8_global_system( 317; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 318; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 319; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 320; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 321; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 322; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 323; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 324; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 325; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 326; CHECK: atomicrmw.start: 327; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 328; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 329; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 330; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]] 331; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP4]], i8 [[EXTRACTED]], i8 [[VALUE]] 332; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 333; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 334; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 335; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 336; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 337; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 338; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP5]], 0 339; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 340; CHECK: atomicrmw.end: 341; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 342; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 343; CHECK-NEXT: ret i8 [[EXTRACTED3]] 344; 345 %res = atomicrmw umax ptr addrspace(1) %ptr, i8 %value seq_cst 346 ret i8 %res 347} 348 349define i8 @test_atomicrmw_umin_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 350; CHECK-LABEL: @test_atomicrmw_umin_i8_global_system( 351; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 352; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 353; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 354; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 355; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 356; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 357; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 358; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 359; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 360; CHECK: atomicrmw.start: 361; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 362; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 363; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 364; CHECK-NEXT: [[TMP4:%.*]] = icmp ule i8 [[EXTRACTED]], [[VALUE:%.*]] 365; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP4]], i8 [[EXTRACTED]], i8 [[VALUE]] 366; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 367; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 368; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 369; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 370; CHECK-NEXT: [[TMP5:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 371; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1 372; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP5]], 0 373; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 374; CHECK: atomicrmw.end: 375; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 376; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 377; CHECK-NEXT: ret i8 [[EXTRACTED3]] 378; 379 %res = atomicrmw umin ptr addrspace(1) %ptr, i8 %value seq_cst 380 ret i8 %res 381} 382 383define i8 @test_cmpxchg_i8_global_system(ptr addrspace(1) %out, i8 %in, i8 %old) { 384; CHECK-LABEL: @test_cmpxchg_i8_global_system( 385; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr addrspace(1) [[OUT:%.*]], i64 4 386; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[GEP]], i64 -4) 387; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[GEP]] to i64 388; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 389; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 390; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 391; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 392; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 393; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[IN:%.*]] to i32 394; CHECK-NEXT: [[TMP4:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 395; CHECK-NEXT: [[TMP5:%.*]] = zext i8 [[OLD:%.*]] to i32 396; CHECK-NEXT: [[TMP6:%.*]] = shl i32 [[TMP5]], [[SHIFTAMT]] 397; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 398; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP7]], [[INV_MASK]] 399; CHECK-NEXT: br label [[PARTWORD_CMPXCHG_LOOP:%.*]] 400; CHECK: partword.cmpxchg.loop: 401; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP8]], [[TMP0:%.*]] ], [ [[TMP15:%.*]], [[PARTWORD_CMPXCHG_FAILURE:%.*]] ] 402; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP4]] 403; CHECK-NEXT: [[TMP11:%.*]] = or i32 [[TMP9]], [[TMP6]] 404; CHECK-NEXT: [[TMP12:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[TMP11]], i32 [[TMP10]] seq_cst seq_cst, align 4 405; CHECK-NEXT: [[TMP13:%.*]] = extractvalue { i32, i1 } [[TMP12]], 0 406; CHECK-NEXT: [[TMP14:%.*]] = extractvalue { i32, i1 } [[TMP12]], 1 407; CHECK-NEXT: br i1 [[TMP14]], label [[PARTWORD_CMPXCHG_END:%.*]], label [[PARTWORD_CMPXCHG_FAILURE]] 408; CHECK: partword.cmpxchg.failure: 409; CHECK-NEXT: [[TMP15]] = and i32 [[TMP13]], [[INV_MASK]] 410; CHECK-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP9]], [[TMP15]] 411; CHECK-NEXT: br i1 [[TMP16]], label [[PARTWORD_CMPXCHG_LOOP]], label [[PARTWORD_CMPXCHG_END]] 412; CHECK: partword.cmpxchg.end: 413; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP13]], [[SHIFTAMT]] 414; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 415; CHECK-NEXT: [[TMP17:%.*]] = insertvalue { i8, i1 } poison, i8 [[EXTRACTED]], 0 416; CHECK-NEXT: [[TMP18:%.*]] = insertvalue { i8, i1 } [[TMP17]], i1 [[TMP14]], 1 417; CHECK-NEXT: [[EXTRACT:%.*]] = extractvalue { i8, i1 } [[TMP18]], 0 418; CHECK-NEXT: ret i8 [[EXTRACT]] 419; 420 %gep = getelementptr i8, ptr addrspace(1) %out, i64 4 421 %res = cmpxchg ptr addrspace(1) %gep, i8 %old, i8 %in seq_cst seq_cst 422 %extract = extractvalue {i8, i1} %res, 0 423 ret i8 %extract 424} 425 426define i8 @test_atomicrmw_inc_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 427; CHECK-LABEL: @test_atomicrmw_inc_i8_global_system( 428; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 429; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 430; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 431; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 432; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 433; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 434; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 435; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 436; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 437; CHECK: atomicrmw.start: 438; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 439; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 440; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 441; CHECK-NEXT: [[TMP4:%.*]] = add i8 [[EXTRACTED]], 1 442; CHECK-NEXT: [[TMP5:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]] 443; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 0, i8 [[TMP4]] 444; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 445; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 446; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 447; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 448; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 449; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1 450; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0 451; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 452; CHECK: atomicrmw.end: 453; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 454; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 455; CHECK-NEXT: ret i8 [[EXTRACTED3]] 456; 457 %res = atomicrmw uinc_wrap ptr addrspace(1) %ptr, i8 %value seq_cst 458 ret i8 %res 459} 460 461define i8 @test_atomicrmw_inc_i8_global_system_align2(ptr addrspace(1) %ptr, i8 %value) { 462; CHECK-LABEL: @test_atomicrmw_inc_i8_global_system_align2( 463; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 464; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 465; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 466; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 467; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 468; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 469; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 470; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 471; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 472; CHECK: atomicrmw.start: 473; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 474; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 475; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 476; CHECK-NEXT: [[TMP4:%.*]] = add i8 [[EXTRACTED]], 1 477; CHECK-NEXT: [[TMP5:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]] 478; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 0, i8 [[TMP4]] 479; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 480; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 481; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 482; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 483; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 484; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1 485; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0 486; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 487; CHECK: atomicrmw.end: 488; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 489; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 490; CHECK-NEXT: ret i8 [[EXTRACTED3]] 491; 492 %res = atomicrmw uinc_wrap ptr addrspace(1) %ptr, i8 %value seq_cst, align 2 493 ret i8 %res 494} 495 496define i8 @test_atomicrmw_inc_i8_global_system_align4(ptr addrspace(1) %ptr, i8 %value) { 497; CHECK-LABEL: @test_atomicrmw_inc_i8_global_system_align4( 498; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4 499; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 500; CHECK: atomicrmw.start: 501; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 502; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i8 503; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[EXTRACTED]], 1 504; CHECK-NEXT: [[TMP3:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]] 505; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP3]], i8 0, i8 [[TMP2]] 506; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 507; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], -256 508; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]] 509; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 510; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1 511; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0 512; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 513; CHECK: atomicrmw.end: 514; CHECK-NEXT: [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i8 515; CHECK-NEXT: ret i8 [[EXTRACTED1]] 516; 517 %res = atomicrmw uinc_wrap ptr addrspace(1) %ptr, i8 %value seq_cst, align 4 518 ret i8 %res 519} 520 521define i8 @test_atomicrmw_inc_i8_flat_system(ptr %ptr, i8 %value) { 522; CHECK-LABEL: @test_atomicrmw_inc_i8_flat_system( 523; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4) 524; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64 525; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 526; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 527; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 528; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 529; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 530; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4 531; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 532; CHECK: atomicrmw.start: 533; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 534; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 535; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 536; CHECK-NEXT: [[TMP4:%.*]] = add i8 [[EXTRACTED]], 1 537; CHECK-NEXT: [[TMP5:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]] 538; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 0, i8 [[TMP4]] 539; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 540; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 541; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 542; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 543; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 544; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1 545; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0 546; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 547; CHECK: atomicrmw.end: 548; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 549; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 550; CHECK-NEXT: ret i8 [[EXTRACTED3]] 551; 552 %res = atomicrmw uinc_wrap ptr %ptr, i8 %value seq_cst 553 ret i8 %res 554} 555 556define i8 @test_atomicrmw_inc_i8_flat_system_align2(ptr %ptr, i8 %value) { 557; CHECK-LABEL: @test_atomicrmw_inc_i8_flat_system_align2( 558; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4) 559; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64 560; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 561; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 562; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 563; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 564; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 565; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4 566; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 567; CHECK: atomicrmw.start: 568; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 569; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 570; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 571; CHECK-NEXT: [[TMP4:%.*]] = add i8 [[EXTRACTED]], 1 572; CHECK-NEXT: [[TMP5:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]] 573; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 0, i8 [[TMP4]] 574; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 575; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 576; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 577; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 578; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 579; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1 580; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0 581; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 582; CHECK: atomicrmw.end: 583; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 584; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 585; CHECK-NEXT: ret i8 [[EXTRACTED3]] 586; 587 %res = atomicrmw uinc_wrap ptr %ptr, i8 %value seq_cst, align 2 588 ret i8 %res 589} 590 591define i8 @test_atomicrmw_inc_i8_flat_system_align4(ptr %ptr, i8 %value) { 592; CHECK-LABEL: @test_atomicrmw_inc_i8_flat_system_align4( 593; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[PTR:%.*]], align 4 594; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 595; CHECK: atomicrmw.start: 596; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 597; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i8 598; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[EXTRACTED]], 1 599; CHECK-NEXT: [[TMP3:%.*]] = icmp uge i8 [[EXTRACTED]], [[VALUE:%.*]] 600; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP3]], i8 0, i8 [[TMP2]] 601; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 602; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], -256 603; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]] 604; CHECK-NEXT: [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 605; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1 606; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP4]], 0 607; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 608; CHECK: atomicrmw.end: 609; CHECK-NEXT: [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i8 610; CHECK-NEXT: ret i8 [[EXTRACTED1]] 611; 612 %res = atomicrmw uinc_wrap ptr %ptr, i8 %value seq_cst, align 4 613 ret i8 %res 614} 615 616define i8 @test_atomicrmw_dec_i8_global_system(ptr addrspace(1) %ptr, i8 %value) { 617; CHECK-LABEL: @test_atomicrmw_dec_i8_global_system( 618; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 619; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 620; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 621; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 622; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 623; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 624; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 625; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 626; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 627; CHECK: atomicrmw.start: 628; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 629; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 630; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 631; CHECK-NEXT: [[TMP4:%.*]] = sub i8 [[EXTRACTED]], 1 632; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[EXTRACTED]], 0 633; CHECK-NEXT: [[TMP6:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]] 634; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]] 635; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP7]], i8 [[VALUE]], i8 [[TMP4]] 636; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 637; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 638; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 639; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 640; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 641; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1 642; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0 643; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 644; CHECK: atomicrmw.end: 645; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 646; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 647; CHECK-NEXT: ret i8 [[EXTRACTED3]] 648; 649 %res = atomicrmw udec_wrap ptr addrspace(1) %ptr, i8 %value seq_cst 650 ret i8 %res 651} 652 653define i8 @test_atomicrmw_dec_i8_global_system_align2(ptr addrspace(1) %ptr, i8 %value) { 654; CHECK-LABEL: @test_atomicrmw_dec_i8_global_system_align2( 655; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i64(ptr addrspace(1) [[PTR:%.*]], i64 -4) 656; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64 657; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 658; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 659; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 660; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 661; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 662; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[ALIGNEDADDR]], align 4 663; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 664; CHECK: atomicrmw.start: 665; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 666; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 667; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 668; CHECK-NEXT: [[TMP4:%.*]] = sub i8 [[EXTRACTED]], 1 669; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[EXTRACTED]], 0 670; CHECK-NEXT: [[TMP6:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]] 671; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]] 672; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP7]], i8 [[VALUE]], i8 [[TMP4]] 673; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 674; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 675; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 676; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 677; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr addrspace(1) [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 678; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1 679; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0 680; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 681; CHECK: atomicrmw.end: 682; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 683; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 684; CHECK-NEXT: ret i8 [[EXTRACTED3]] 685; 686 %res = atomicrmw udec_wrap ptr addrspace(1) %ptr, i8 %value seq_cst, align 2 687 ret i8 %res 688} 689 690define i8 @test_atomicrmw_dec_i8_global_system_align4(ptr addrspace(1) %ptr, i8 %value) { 691; CHECK-LABEL: @test_atomicrmw_dec_i8_global_system_align4( 692; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(1) [[PTR:%.*]], align 4 693; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 694; CHECK: atomicrmw.start: 695; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 696; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i8 697; CHECK-NEXT: [[TMP2:%.*]] = sub i8 [[EXTRACTED]], 1 698; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[EXTRACTED]], 0 699; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]] 700; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]] 701; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 [[VALUE]], i8 [[TMP2]] 702; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 703; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], -256 704; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]] 705; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr addrspace(1) [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 706; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1 707; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0 708; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 709; CHECK: atomicrmw.end: 710; CHECK-NEXT: [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i8 711; CHECK-NEXT: ret i8 [[EXTRACTED1]] 712; 713 %res = atomicrmw udec_wrap ptr addrspace(1) %ptr, i8 %value seq_cst, align 4 714 ret i8 %res 715} 716 717define i8 @test_atomicrmw_dec_i8_flat_system(ptr %ptr, i8 %value) { 718; CHECK-LABEL: @test_atomicrmw_dec_i8_flat_system( 719; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4) 720; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64 721; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 722; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 723; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 724; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 725; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 726; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4 727; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 728; CHECK: atomicrmw.start: 729; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 730; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 731; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 732; CHECK-NEXT: [[TMP4:%.*]] = sub i8 [[EXTRACTED]], 1 733; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[EXTRACTED]], 0 734; CHECK-NEXT: [[TMP6:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]] 735; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]] 736; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP7]], i8 [[VALUE]], i8 [[TMP4]] 737; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 738; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 739; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 740; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 741; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 742; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1 743; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0 744; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 745; CHECK: atomicrmw.end: 746; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 747; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 748; CHECK-NEXT: ret i8 [[EXTRACTED3]] 749; 750 %res = atomicrmw udec_wrap ptr %ptr, i8 %value seq_cst 751 ret i8 %res 752} 753 754define i8 @test_atomicrmw_dec_i8_flat_system_align2(ptr %ptr, i8 %value) { 755; CHECK-LABEL: @test_atomicrmw_dec_i8_flat_system_align2( 756; CHECK-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 -4) 757; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PTR]] to i64 758; CHECK-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 759; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 760; CHECK-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 761; CHECK-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 762; CHECK-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 763; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ALIGNEDADDR]], align 4 764; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 765; CHECK: atomicrmw.start: 766; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 767; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[LOADED]], [[SHIFTAMT]] 768; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 769; CHECK-NEXT: [[TMP4:%.*]] = sub i8 [[EXTRACTED]], 1 770; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[EXTRACTED]], 0 771; CHECK-NEXT: [[TMP6:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]] 772; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]] 773; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP7]], i8 [[VALUE]], i8 [[TMP4]] 774; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 775; CHECK-NEXT: [[SHIFTED1:%.*]] = shl nuw i32 [[EXTENDED]], [[SHIFTAMT]] 776; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], [[INV_MASK]] 777; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[SHIFTED1]] 778; CHECK-NEXT: [[TMP8:%.*]] = cmpxchg ptr [[ALIGNEDADDR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 779; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1 780; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP8]], 0 781; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 782; CHECK: atomicrmw.end: 783; CHECK-NEXT: [[SHIFTED2:%.*]] = lshr i32 [[NEWLOADED]], [[SHIFTAMT]] 784; CHECK-NEXT: [[EXTRACTED3:%.*]] = trunc i32 [[SHIFTED2]] to i8 785; CHECK-NEXT: ret i8 [[EXTRACTED3]] 786; 787 %res = atomicrmw udec_wrap ptr %ptr, i8 %value seq_cst, align 2 788 ret i8 %res 789} 790 791define i8 @test_atomicrmw_dec_i8_flat_system_align4(ptr %ptr, i8 %value) { 792; CHECK-LABEL: @test_atomicrmw_dec_i8_flat_system_align4( 793; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[PTR:%.*]], align 4 794; CHECK-NEXT: br label [[ATOMICRMW_START:%.*]] 795; CHECK: atomicrmw.start: 796; CHECK-NEXT: [[LOADED:%.*]] = phi i32 [ [[TMP1]], [[TMP0:%.*]] ], [ [[NEWLOADED:%.*]], [[ATOMICRMW_START]] ] 797; CHECK-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[LOADED]] to i8 798; CHECK-NEXT: [[TMP2:%.*]] = sub i8 [[EXTRACTED]], 1 799; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[EXTRACTED]], 0 800; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i8 [[EXTRACTED]], [[VALUE:%.*]] 801; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]] 802; CHECK-NEXT: [[NEW:%.*]] = select i1 [[TMP5]], i8 [[VALUE]], i8 [[TMP2]] 803; CHECK-NEXT: [[EXTENDED:%.*]] = zext i8 [[NEW]] to i32 804; CHECK-NEXT: [[UNMASKED:%.*]] = and i32 [[LOADED]], -256 805; CHECK-NEXT: [[INSERTED:%.*]] = or i32 [[UNMASKED]], [[EXTENDED]] 806; CHECK-NEXT: [[TMP6:%.*]] = cmpxchg ptr [[PTR]], i32 [[LOADED]], i32 [[INSERTED]] seq_cst seq_cst, align 4 807; CHECK-NEXT: [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1 808; CHECK-NEXT: [[NEWLOADED]] = extractvalue { i32, i1 } [[TMP6]], 0 809; CHECK-NEXT: br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]] 810; CHECK: atomicrmw.end: 811; CHECK-NEXT: [[EXTRACTED1:%.*]] = trunc i32 [[NEWLOADED]] to i8 812; CHECK-NEXT: ret i8 [[EXTRACTED1]] 813; 814 %res = atomicrmw udec_wrap ptr %ptr, i8 %value seq_cst, align 4 815 ret i8 %res 816} 817