xref: /llvm-project/llvm/test/Transforms/AtomicExpand/LoongArch/atomicrmw-fp.ll (revision fe42e72db29e48aa81eac2aa922afd90a7f01517)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S --mtriple=loongarch64 --passes=atomic-expand --mattr=+d %s | FileCheck %s
3
4define float @atomicrmw_fadd_float(ptr %ptr, float %value) {
5; CHECK-LABEL: @atomicrmw_fadd_float(
6; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4
7; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
8; CHECK:       atomicrmw.start:
9; CHECK-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
10; CHECK-NEXT:    [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]]
11; CHECK-NEXT:    [[TMP2:%.*]] = bitcast float [[NEW]] to i32
12; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
13; CHECK-NEXT:    [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4
14; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
15; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
16; CHECK-NEXT:    [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
17; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
18; CHECK:       atomicrmw.end:
19; CHECK-NEXT:    ret float [[TMP5]]
20;
21  %res = atomicrmw fadd ptr %ptr, float %value seq_cst
22  ret float %res
23}
24
25define float @atomicrmw_fsub_float(ptr %ptr, float %value) {
26; CHECK-LABEL: @atomicrmw_fsub_float(
27; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4
28; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
29; CHECK:       atomicrmw.start:
30; CHECK-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
31; CHECK-NEXT:    [[NEW:%.*]] = fsub float [[LOADED]], [[VALUE:%.*]]
32; CHECK-NEXT:    [[TMP2:%.*]] = bitcast float [[NEW]] to i32
33; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float [[LOADED]] to i32
34; CHECK-NEXT:    [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP3]], i32 [[TMP2]] seq_cst seq_cst, align 4
35; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
36; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
37; CHECK-NEXT:    [[TMP5]] = bitcast i32 [[NEWLOADED]] to float
38; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
39; CHECK:       atomicrmw.end:
40; CHECK-NEXT:    ret float [[TMP5]]
41;
42  %res = atomicrmw fsub ptr %ptr, float %value seq_cst
43  ret float %res
44}
45
46define float @atomicrmw_fmin_float(ptr %ptr, float %value) {
47; CHECK-LABEL: @atomicrmw_fmin_float(
48; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4
49; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
50; CHECK:       atomicrmw.start:
51; CHECK-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
52; CHECK-NEXT:    [[TMP2:%.*]] = call float @llvm.minnum.f32(float [[LOADED]], float [[VALUE:%.*]])
53; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float [[TMP2]] to i32
54; CHECK-NEXT:    [[TMP4:%.*]] = bitcast float [[LOADED]] to i32
55; CHECK-NEXT:    [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4
56; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
57; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
58; CHECK-NEXT:    [[TMP6]] = bitcast i32 [[NEWLOADED]] to float
59; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
60; CHECK:       atomicrmw.end:
61; CHECK-NEXT:    ret float [[TMP6]]
62;
63  %res = atomicrmw fmin ptr %ptr, float %value seq_cst
64  ret float %res
65}
66
67define float @atomicrmw_fmax_float(ptr %ptr, float %value) {
68; CHECK-LABEL: @atomicrmw_fmax_float(
69; CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[PTR:%.*]], align 4
70; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
71; CHECK:       atomicrmw.start:
72; CHECK-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
73; CHECK-NEXT:    [[TMP2:%.*]] = call float @llvm.maxnum.f32(float [[LOADED]], float [[VALUE:%.*]])
74; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float [[TMP2]] to i32
75; CHECK-NEXT:    [[TMP4:%.*]] = bitcast float [[LOADED]] to i32
76; CHECK-NEXT:    [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst, align 4
77; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
78; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
79; CHECK-NEXT:    [[TMP6]] = bitcast i32 [[NEWLOADED]] to float
80; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
81; CHECK:       atomicrmw.end:
82; CHECK-NEXT:    ret float [[TMP6]]
83;
84  %res = atomicrmw fmax ptr %ptr, float %value seq_cst
85  ret float %res
86}
87
88define double @atomicrmw_fadd_double(ptr %ptr, double %value) {
89; CHECK-LABEL: @atomicrmw_fadd_double(
90; CHECK-NEXT:    [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8
91; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
92; CHECK:       atomicrmw.start:
93; CHECK-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
94; CHECK-NEXT:    [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]]
95; CHECK-NEXT:    [[TMP2:%.*]] = bitcast double [[NEW]] to i64
96; CHECK-NEXT:    [[TMP3:%.*]] = bitcast double [[LOADED]] to i64
97; CHECK-NEXT:    [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP3]], i64 [[TMP2]] seq_cst seq_cst, align 8
98; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP4]], 1
99; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP4]], 0
100; CHECK-NEXT:    [[TMP5]] = bitcast i64 [[NEWLOADED]] to double
101; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
102; CHECK:       atomicrmw.end:
103; CHECK-NEXT:    ret double [[TMP5]]
104;
105  %res = atomicrmw fadd ptr %ptr, double %value seq_cst
106  ret double %res
107}
108
109define double @atomicrmw_fsub_double(ptr %ptr, double %value) {
110; CHECK-LABEL: @atomicrmw_fsub_double(
111; CHECK-NEXT:    [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8
112; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
113; CHECK:       atomicrmw.start:
114; CHECK-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP5:%.*]], [[ATOMICRMW_START]] ]
115; CHECK-NEXT:    [[NEW:%.*]] = fsub double [[LOADED]], [[VALUE:%.*]]
116; CHECK-NEXT:    [[TMP2:%.*]] = bitcast double [[NEW]] to i64
117; CHECK-NEXT:    [[TMP3:%.*]] = bitcast double [[LOADED]] to i64
118; CHECK-NEXT:    [[TMP4:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP3]], i64 [[TMP2]] seq_cst seq_cst, align 8
119; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP4]], 1
120; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP4]], 0
121; CHECK-NEXT:    [[TMP5]] = bitcast i64 [[NEWLOADED]] to double
122; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
123; CHECK:       atomicrmw.end:
124; CHECK-NEXT:    ret double [[TMP5]]
125;
126  %res = atomicrmw fsub ptr %ptr, double %value seq_cst
127  ret double %res
128}
129
130define double @atomicrmw_fmin_double(ptr %ptr, double %value) {
131; CHECK-LABEL: @atomicrmw_fmin_double(
132; CHECK-NEXT:    [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8
133; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
134; CHECK:       atomicrmw.start:
135; CHECK-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
136; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.minnum.f64(double [[LOADED]], double [[VALUE:%.*]])
137; CHECK-NEXT:    [[TMP3:%.*]] = bitcast double [[TMP2]] to i64
138; CHECK-NEXT:    [[TMP4:%.*]] = bitcast double [[LOADED]] to i64
139; CHECK-NEXT:    [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8
140; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1
141; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0
142; CHECK-NEXT:    [[TMP6]] = bitcast i64 [[NEWLOADED]] to double
143; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
144; CHECK:       atomicrmw.end:
145; CHECK-NEXT:    ret double [[TMP6]]
146;
147  %res = atomicrmw fmin ptr %ptr, double %value seq_cst
148  ret double %res
149}
150
151define double @atomicrmw_fmax_double(ptr %ptr, double %value) {
152; CHECK-LABEL: @atomicrmw_fmax_double(
153; CHECK-NEXT:    [[TMP1:%.*]] = load double, ptr [[PTR:%.*]], align 8
154; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
155; CHECK:       atomicrmw.start:
156; CHECK-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
157; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.maxnum.f64(double [[LOADED]], double [[VALUE:%.*]])
158; CHECK-NEXT:    [[TMP3:%.*]] = bitcast double [[TMP2]] to i64
159; CHECK-NEXT:    [[TMP4:%.*]] = bitcast double [[LOADED]] to i64
160; CHECK-NEXT:    [[TMP5:%.*]] = cmpxchg ptr [[PTR]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst, align 8
161; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1
162; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0
163; CHECK-NEXT:    [[TMP6]] = bitcast i64 [[NEWLOADED]] to double
164; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
165; CHECK:       atomicrmw.end:
166; CHECK-NEXT:    ret double [[TMP6]]
167;
168  %res = atomicrmw fmax ptr %ptr, double %value seq_cst
169  ret double %res
170}
171