1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -mtriple=i686-linux-gnu -atomic-expand %s | FileCheck %s
3
4define float @test_atomicrmw_fadd_f32(float* %ptr, float %value) {
5; CHECK-LABEL: @test_atomicrmw_fadd_f32(
6; CHECK-NEXT:    [[TMP1:%.*]] = load float, float* [[PTR:%.*]], align 4
7; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
8; CHECK:       atomicrmw.start:
9; CHECK-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
10; CHECK-NEXT:    [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]]
11; CHECK-NEXT:    [[TMP2:%.*]] = bitcast float* [[PTR]] to i32*
12; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float [[NEW]] to i32
13; CHECK-NEXT:    [[TMP4:%.*]] = bitcast float [[LOADED]] to i32
14; CHECK-NEXT:    [[TMP5:%.*]] = cmpxchg i32* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst
15; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
16; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
17; CHECK-NEXT:    [[TMP6]] = bitcast i32 [[NEWLOADED]] to float
18; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
19; CHECK:       atomicrmw.end:
20; CHECK-NEXT:    ret float [[TMP6]]
21;
22  %res = atomicrmw fadd float* %ptr, float %value seq_cst
23  ret float %res
24}
25
26define double @test_atomicrmw_fadd_f64(double* %ptr, double %value) {
27; CHECK-LABEL: @test_atomicrmw_fadd_f64(
28; CHECK-NEXT:    [[TMP1:%.*]] = load double, double* [[PTR:%.*]], align 8
29; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
30; CHECK:       atomicrmw.start:
31; CHECK-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
32; CHECK-NEXT:    [[NEW:%.*]] = fadd double [[LOADED]], [[VALUE:%.*]]
33; CHECK-NEXT:    [[TMP2:%.*]] = bitcast double* [[PTR]] to i64*
34; CHECK-NEXT:    [[TMP3:%.*]] = bitcast double [[NEW]] to i64
35; CHECK-NEXT:    [[TMP4:%.*]] = bitcast double [[LOADED]] to i64
36; CHECK-NEXT:    [[TMP5:%.*]] = cmpxchg i64* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst
37; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1
38; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0
39; CHECK-NEXT:    [[TMP6]] = bitcast i64 [[NEWLOADED]] to double
40; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
41; CHECK:       atomicrmw.end:
42; CHECK-NEXT:    ret double [[TMP6]]
43;
44  %res = atomicrmw fadd double* %ptr, double %value seq_cst
45  ret double %res
46}
47
48define float @test_atomicrmw_fadd_f32_as1(float addrspace(1)* %ptr, float %value) {
49; CHECK-LABEL: @test_atomicrmw_fadd_f32_as1(
50; CHECK-NEXT:    [[TMP1:%.*]] = load float, float addrspace(1)* [[PTR:%.*]], align 4
51; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
52; CHECK:       atomicrmw.start:
53; CHECK-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
54; CHECK-NEXT:    [[NEW:%.*]] = fadd float [[LOADED]], [[VALUE:%.*]]
55; CHECK-NEXT:    [[TMP2:%.*]] = bitcast float addrspace(1)* [[PTR]] to i32 addrspace(1)*
56; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float [[NEW]] to i32
57; CHECK-NEXT:    [[TMP4:%.*]] = bitcast float [[LOADED]] to i32
58; CHECK-NEXT:    [[TMP5:%.*]] = cmpxchg i32 addrspace(1)* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst
59; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
60; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
61; CHECK-NEXT:    [[TMP6]] = bitcast i32 [[NEWLOADED]] to float
62; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
63; CHECK:       atomicrmw.end:
64; CHECK-NEXT:    ret float [[TMP6]]
65;
66  %res = atomicrmw fadd float addrspace(1)* %ptr, float %value seq_cst
67  ret float %res
68}
69
70define float @test_atomicrmw_fsub_f32(float* %ptr, float %value) {
71; CHECK-LABEL: @test_atomicrmw_fsub_f32(
72; CHECK-NEXT:    [[TMP1:%.*]] = load float, float* [[PTR:%.*]], align 4
73; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
74; CHECK:       atomicrmw.start:
75; CHECK-NEXT:    [[LOADED:%.*]] = phi float [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
76; CHECK-NEXT:    [[NEW:%.*]] = fsub float [[LOADED]], [[VALUE:%.*]]
77; CHECK-NEXT:    [[TMP2:%.*]] = bitcast float* [[PTR]] to i32*
78; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float [[NEW]] to i32
79; CHECK-NEXT:    [[TMP4:%.*]] = bitcast float [[LOADED]] to i32
80; CHECK-NEXT:    [[TMP5:%.*]] = cmpxchg i32* [[TMP2]], i32 [[TMP4]], i32 [[TMP3]] seq_cst seq_cst
81; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
82; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
83; CHECK-NEXT:    [[TMP6]] = bitcast i32 [[NEWLOADED]] to float
84; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
85; CHECK:       atomicrmw.end:
86; CHECK-NEXT:    ret float [[TMP6]]
87;
88  %res = atomicrmw fsub float* %ptr, float %value seq_cst
89  ret float %res
90}
91
92define double @test_atomicrmw_fsub_f64(double* %ptr, double %value) {
93; CHECK-LABEL: @test_atomicrmw_fsub_f64(
94; CHECK-NEXT:    [[TMP1:%.*]] = load double, double* [[PTR:%.*]], align 8
95; CHECK-NEXT:    br label [[ATOMICRMW_START:%.*]]
96; CHECK:       atomicrmw.start:
97; CHECK-NEXT:    [[LOADED:%.*]] = phi double [ [[TMP1]], [[TMP0:%.*]] ], [ [[TMP6:%.*]], [[ATOMICRMW_START]] ]
98; CHECK-NEXT:    [[NEW:%.*]] = fsub double [[LOADED]], [[VALUE:%.*]]
99; CHECK-NEXT:    [[TMP2:%.*]] = bitcast double* [[PTR]] to i64*
100; CHECK-NEXT:    [[TMP3:%.*]] = bitcast double [[NEW]] to i64
101; CHECK-NEXT:    [[TMP4:%.*]] = bitcast double [[LOADED]] to i64
102; CHECK-NEXT:    [[TMP5:%.*]] = cmpxchg i64* [[TMP2]], i64 [[TMP4]], i64 [[TMP3]] seq_cst seq_cst
103; CHECK-NEXT:    [[SUCCESS:%.*]] = extractvalue { i64, i1 } [[TMP5]], 1
104; CHECK-NEXT:    [[NEWLOADED:%.*]] = extractvalue { i64, i1 } [[TMP5]], 0
105; CHECK-NEXT:    [[TMP6]] = bitcast i64 [[NEWLOADED]] to double
106; CHECK-NEXT:    br i1 [[SUCCESS]], label [[ATOMICRMW_END:%.*]], label [[ATOMICRMW_START]]
107; CHECK:       atomicrmw.end:
108; CHECK-NEXT:    ret double [[TMP6]]
109;
110  %res = atomicrmw fsub double* %ptr, double %value seq_cst
111  ret double %res
112}
113