1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; RUN: opt -S --mtriple=loongarch64 --mattr=+d,+lamcas %s | FileCheck %s --check-prefix=NO-EXPAND 3; RUN: opt -S --mtriple=loongarch64 --passes=atomic-expand --mattr=+d,+lamcas %s | FileCheck %s --check-prefix=EXPAND 4 5; When -mlamcas is enabled, all atomicrmw and/or/xor ptr %a,a i8/i16 %b ordering 6; will be expanded to am{and/or/xo}[_db].w by LoongArchTargetLowering::emitExpandAtomicRMW 7 8define i8 @atomicrmw_and_i8_acquire(ptr %a, i8 %b) nounwind { 9; NO-EXPAND-LABEL: define i8 @atomicrmw_and_i8_acquire( 10; NO-EXPAND-SAME: ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0:[0-9]+]] { 11; NO-EXPAND-NEXT: [[TMP1:%.*]] = atomicrmw and ptr [[A]], i8 [[B]] acquire, align 1 12; NO-EXPAND-NEXT: ret i8 [[TMP1]] 13; 14; EXPAND-LABEL: define i8 @atomicrmw_and_i8_acquire( 15; EXPAND-SAME: ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0:[0-9]+]] { 16; EXPAND-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[A]], i64 -4) 17; EXPAND-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[A]] to i64 18; EXPAND-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 19; EXPAND-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 20; EXPAND-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 21; EXPAND-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 22; EXPAND-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 23; EXPAND-NEXT: [[TMP3:%.*]] = zext i8 [[B]] to i32 24; EXPAND-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 25; EXPAND-NEXT: [[ANDOPERAND:%.*]] = or i32 [[VALOPERAND_SHIFTED]], [[INV_MASK]] 26; EXPAND-NEXT: [[TMP4:%.*]] = atomicrmw and ptr [[ALIGNEDADDR]], i32 [[ANDOPERAND]] acquire, align 4 27; EXPAND-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]] 28; EXPAND-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 29; EXPAND-NEXT: ret i8 [[EXTRACTED]] 30; 31 %1 = atomicrmw and ptr %a, i8 %b acquire 32 ret i8 %1 33} 34 35define i16 @atomicrmw_and_i16_acquire(ptr %a, i16 %b) nounwind { 36; NO-EXPAND-LABEL: define i16 @atomicrmw_and_i16_acquire( 37; NO-EXPAND-SAME: ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] { 38; NO-EXPAND-NEXT: [[TMP1:%.*]] = atomicrmw and ptr [[A]], i16 [[B]] acquire, align 2 39; NO-EXPAND-NEXT: ret i16 [[TMP1]] 40; 41; EXPAND-LABEL: define i16 @atomicrmw_and_i16_acquire( 42; EXPAND-SAME: ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] { 43; EXPAND-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[A]], i64 -4) 44; EXPAND-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[A]] to i64 45; EXPAND-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 46; EXPAND-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 47; EXPAND-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 48; EXPAND-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]] 49; EXPAND-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 50; EXPAND-NEXT: [[TMP3:%.*]] = zext i16 [[B]] to i32 51; EXPAND-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 52; EXPAND-NEXT: [[ANDOPERAND:%.*]] = or i32 [[VALOPERAND_SHIFTED]], [[INV_MASK]] 53; EXPAND-NEXT: [[TMP4:%.*]] = atomicrmw and ptr [[ALIGNEDADDR]], i32 [[ANDOPERAND]] acquire, align 4 54; EXPAND-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]] 55; EXPAND-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16 56; EXPAND-NEXT: ret i16 [[EXTRACTED]] 57; 58 %1 = atomicrmw and ptr %a, i16 %b acquire 59 ret i16 %1 60 61} 62 63define i8 @atomicrmw_or_i8_acquire(ptr %a, i8 %b) nounwind { 64; NO-EXPAND-LABEL: define i8 @atomicrmw_or_i8_acquire( 65; NO-EXPAND-SAME: ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] { 66; NO-EXPAND-NEXT: [[TMP1:%.*]] = atomicrmw or ptr [[A]], i8 [[B]] acquire, align 1 67; NO-EXPAND-NEXT: ret i8 [[TMP1]] 68; 69; EXPAND-LABEL: define i8 @atomicrmw_or_i8_acquire( 70; EXPAND-SAME: ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] { 71; EXPAND-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[A]], i64 -4) 72; EXPAND-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[A]] to i64 73; EXPAND-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 74; EXPAND-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 75; EXPAND-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 76; EXPAND-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 77; EXPAND-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 78; EXPAND-NEXT: [[TMP3:%.*]] = zext i8 [[B]] to i32 79; EXPAND-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 80; EXPAND-NEXT: [[TMP4:%.*]] = atomicrmw or ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] acquire, align 4 81; EXPAND-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]] 82; EXPAND-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 83; EXPAND-NEXT: ret i8 [[EXTRACTED]] 84; 85 %1 = atomicrmw or ptr %a, i8 %b acquire 86 ret i8 %1 87} 88 89define i16 @atomicrmw_or_i16_acquire(ptr %a, i16 %b) nounwind { 90; NO-EXPAND-LABEL: define i16 @atomicrmw_or_i16_acquire( 91; NO-EXPAND-SAME: ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] { 92; NO-EXPAND-NEXT: [[TMP1:%.*]] = atomicrmw or ptr [[A]], i16 [[B]] acquire, align 2 93; NO-EXPAND-NEXT: ret i16 [[TMP1]] 94; 95; EXPAND-LABEL: define i16 @atomicrmw_or_i16_acquire( 96; EXPAND-SAME: ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] { 97; EXPAND-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[A]], i64 -4) 98; EXPAND-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[A]] to i64 99; EXPAND-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 100; EXPAND-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 101; EXPAND-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 102; EXPAND-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]] 103; EXPAND-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 104; EXPAND-NEXT: [[TMP3:%.*]] = zext i16 [[B]] to i32 105; EXPAND-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 106; EXPAND-NEXT: [[TMP4:%.*]] = atomicrmw or ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] acquire, align 4 107; EXPAND-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]] 108; EXPAND-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16 109; EXPAND-NEXT: ret i16 [[EXTRACTED]] 110; 111 %1 = atomicrmw or ptr %a, i16 %b acquire 112 ret i16 %1 113} 114 115define i8 @atomicrmw_xor_i8_acquire(ptr %a, i8 %b) nounwind { 116; NO-EXPAND-LABEL: define i8 @atomicrmw_xor_i8_acquire( 117; NO-EXPAND-SAME: ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] { 118; NO-EXPAND-NEXT: [[TMP1:%.*]] = atomicrmw xor ptr [[A]], i8 [[B]] acquire, align 1 119; NO-EXPAND-NEXT: ret i8 [[TMP1]] 120; 121; EXPAND-LABEL: define i8 @atomicrmw_xor_i8_acquire( 122; EXPAND-SAME: ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] { 123; EXPAND-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[A]], i64 -4) 124; EXPAND-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[A]] to i64 125; EXPAND-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 126; EXPAND-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 127; EXPAND-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 128; EXPAND-NEXT: [[MASK:%.*]] = shl i32 255, [[SHIFTAMT]] 129; EXPAND-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 130; EXPAND-NEXT: [[TMP3:%.*]] = zext i8 [[B]] to i32 131; EXPAND-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 132; EXPAND-NEXT: [[TMP4:%.*]] = atomicrmw xor ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] acquire, align 4 133; EXPAND-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]] 134; EXPAND-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i8 135; EXPAND-NEXT: ret i8 [[EXTRACTED]] 136; 137 %1 = atomicrmw xor ptr %a, i8 %b acquire 138 ret i8 %1 139} 140 141define i16 @atomicrmw_xor_i16_acquire(ptr %a, i16 %b) nounwind { 142; NO-EXPAND-LABEL: define i16 @atomicrmw_xor_i16_acquire( 143; NO-EXPAND-SAME: ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] { 144; NO-EXPAND-NEXT: [[TMP1:%.*]] = atomicrmw xor ptr [[A]], i16 [[B]] acquire, align 2 145; NO-EXPAND-NEXT: ret i16 [[TMP1]] 146; 147; EXPAND-LABEL: define i16 @atomicrmw_xor_i16_acquire( 148; EXPAND-SAME: ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] { 149; EXPAND-NEXT: [[ALIGNEDADDR:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[A]], i64 -4) 150; EXPAND-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[A]] to i64 151; EXPAND-NEXT: [[PTRLSB:%.*]] = and i64 [[TMP1]], 3 152; EXPAND-NEXT: [[TMP2:%.*]] = shl i64 [[PTRLSB]], 3 153; EXPAND-NEXT: [[SHIFTAMT:%.*]] = trunc i64 [[TMP2]] to i32 154; EXPAND-NEXT: [[MASK:%.*]] = shl i32 65535, [[SHIFTAMT]] 155; EXPAND-NEXT: [[INV_MASK:%.*]] = xor i32 [[MASK]], -1 156; EXPAND-NEXT: [[TMP3:%.*]] = zext i16 [[B]] to i32 157; EXPAND-NEXT: [[VALOPERAND_SHIFTED:%.*]] = shl i32 [[TMP3]], [[SHIFTAMT]] 158; EXPAND-NEXT: [[TMP4:%.*]] = atomicrmw xor ptr [[ALIGNEDADDR]], i32 [[VALOPERAND_SHIFTED]] acquire, align 4 159; EXPAND-NEXT: [[SHIFTED:%.*]] = lshr i32 [[TMP4]], [[SHIFTAMT]] 160; EXPAND-NEXT: [[EXTRACTED:%.*]] = trunc i32 [[SHIFTED]] to i16 161; EXPAND-NEXT: ret i16 [[EXTRACTED]] 162; 163 %1 = atomicrmw xor ptr %a, i16 %b acquire 164 ret i16 %1 165} 166