xref: /llvm-project/llvm/test/Transforms/AtomicExpand/LoongArch/atomicrmw-expand.ll (revision 427be0767523b6e0f4004a421892f463d62446ac)
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